[cmake-developers] Duplicated linking flags are removed when linking final executable
Sergio Checa
Sergio.Checa at bmw-carit.de
Tue Mar 15 05:58:57 EDT 2016
Hi,
Thanks for the suggestion about OBJECT libraries, I've learnt one more way to design my build process.
Nevertheless, the effect also appears when linking dynamic libraries. For example, a slightly modified CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
file(WRITE a.cpp "")
file(WRITE b.cpp "")
file(WRITE lib.cpp "")
file(WRITE main.cpp "int main(){return 0;}")
add_library(A SHARED a.cpp)
add_library(B SHARED b.cpp)
add_library(L SHARED lib.cpp)
target_link_libraries(L
-Wl,-as-needed A -Wl,-no-as-needed
-Wl,-as-needed B -Wl,-no-as-needed
)
add_executable(main main.cpp)
target_link_libraries(main L)
In this example, I only want libA and libB linked into the main executable iff their symbols are used somewhere in the linking chain (-as-needed). However, libB appears as a needed library because the -Wl,-as-needed flag has no effect on it (it's not in front of libB in CMakeFiles/main.dir/link.txt)
$> objdump -p main | grep NEEDED
...
NEEDED libL.so
NEEDED libB.so
...
Furthermore, if I link 'main' manually from the command line, then 'main' doesn't link libB anymore:
$> g++ -o main ../main.cpp -lL -L.
$> objdump -p main | grep NEEDED
...
NEEDED libL.so
...
The reason why I think it's a bug is that the linkage behaves differently between cmake and raw command line, due to some conflicts between flags when constructing the linking command.
Here is yet another weird scenario:
.---> X ---> -as-needed A -no-as-needed
|
main ----|
|
'---> Y ---> -as-needed B -no-as-needed
CMakeLists.txt to reproduce it:
cmake_minimum_required(VERSION 3.5)
file(WRITE a.cpp "")
file(WRITE b.cpp "")
file(WRITE x.cpp "")
file(WRITE y.cpp "")
file(WRITE main.cpp "int main(){return 0;}")
add_library(A SHARED a.cpp)
add_library(B SHARED b.cpp)
add_library(X SHARED x.cpp)
add_library(Y SHARED y.cpp)
target_link_libraries(X
-Wl,-as-needed A -Wl,-no-as-needed
)
target_link_libraries(Y
-Wl,-as-needed B -Wl,-no-as-needed
)
add_executable(main main.cpp)
target_link_libraries(main X Y)
The result if that both libA and libB are linked in the final executable 'main'. The content of CMakeFiles/main.d/link.txt:
/usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main -rdynamic libX.so libY.so libA.so -Wl,-as-needed -Wl,-no-as-needed libB.so -Wl,-rpath,/tmp/build
Best regards,
Sergio
On 14/03/16 15:58, Brad King wrote:
On 03/14/2016 09:33 AM, Sergio Checa wrote:
target_link_libraries(L
-Wl,-whole-archive A -Wl,-no-whole-archive
-Wl,-whole-archive B -Wl,-no-whole-archive
)
add_executable(main main.cpp)
target_link_libraries(main L)
Specifying flags anywhere except the final executable's target_link_libraries
is not very well defined. I'd rather not try to define behavior different
than has been there for a long time.
It looks like you're trying to achieve what OBJECT libraries are for:
https://cmake.org/cmake/help/v3.5/command/add_library.html#object-libraries
Please try that approach instead.
-Brad
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake-developers/attachments/20160315/e291d3e3/attachment.html>
More information about the cmake-developers
mailing list