[CMake] SHARED library containing OBJECT library: Missing -fPIC

Benjamin Eikel cmake at eikel.org
Fri Jun 22 03:50:53 EDT 2012


Hello,

I have a problem using an OBJECT library that I want to compile into a SHARED 
library using CMake version 2.8.8.

Here is a small example that demonstrates my problem:

# --------------- CMakeLists.txt ---------------
cmake_minimum_required(VERSION 2.8.8)
project(CMakeTest CXX)
add_library(MyLibSub OBJECT 
        ClassA.cpp
)
add_library(MyLib SHARED
        $<TARGET_OBJECTS:MyLibSub>
        ClassB.cpp
)

The content of the other four files is more or less irrelevant. To make the 
example complete, I added them at the end of this e-mail.

When I want to build this example, I get the following error:

$ mkdir build && cd build && cmake .. && make
-- The CXX compiler identification is GNU 4.7.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/benjamin/Desktop/CMake test/build
Scanning dependencies of target MyLibSub
[ 50%] Building CXX object CMakeFiles/MyLibSub.dir/ClassA.cpp.o
[ 50%] Built target MyLibSub
Scanning dependencies of target MyLib
[100%] Building CXX object CMakeFiles/MyLib.dir/ClassB.cpp.o
Linking CXX shared library libMyLib.so
/usr/bin/ld: CMakeFiles/MyLibSub.dir/ClassA.cpp.o: relocation R_X86_64_32 
against `.rodata' can not be used when making a shared object; recompile with 
-fPIC
CMakeFiles/MyLibSub.dir/ClassA.cpp.o: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
make[2]: *** [libMyLib.so] Error 1
make[1]: *** [CMakeFiles/MyLib.dir/all] Error 2
make: *** [all] Error 2

When I add the line
set_target_properties(MyLibSub PROPERTIES COMPILE_FLAGS "-fPIC")
to the CMakeLists.txt, everything works fine. Am I doing something wrong? 
Should CMake add "-fPIC" automatically in this case? Your feedback is greatly 
appreciated.

Kind regards
Benjamin



// --------------- ClassA.cpp ---------------
#include "ClassA.h"
#include <iostream>

void ClassA::printName() {
        std::cout << "ClassA" << std::endl;
}
// --------------- ClassA.h ---------------
#ifndef CLASSA_H
#define CLASSA_H

struct ClassA {
        void printName();
};

#endif /* CLASSA_H */
// --------------- ClassB.cpp ---------------
#include "ClassB.h"
#include <iostream>

void ClassB::printName() {
        std::cout << "ClassB" << std::endl;
        a.printName();
}
// --------------- ClassB.h ---------------
#ifndef CLASSB_H
#define CLASSB_H

#include "ClassA.h"

struct ClassB {
        void printName();
        ClassA a;
};

#endif /* CLASSB_H */



More information about the CMake mailing list