[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