Re: [cmake-developers] Duplicated linking flags are removed when linking final executable
On 03/15/2016 05:58 AM, Sergio Checa wrote: > 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). This may work: add_library(A SHARED a.cpp) add_library(B SHARED b.cpp) add_library(L SHARED lib.cpp) target_link_libraries(main L -Wl,-as-needed A -Wl,-no-as-needed -Wl,-as-needed B -Wl,-no-as-needed ) The only thing that CMake guarantees about link line generation is that it will start with the direct tll() arguments. Additional arguments may be appended to satisfy explicit and inferred dependencies. The problem with trying to do it through dependency propagation is that all of CMake's logic for dependency propagation was designed for libraries and not flags. It has no idea how flags tie to the libraries or how multiple arguments should be grouped. While your patch may fix your particular use case it may also change existing behavior for other projects in ways we cannot anticipate. If you search the list archives you'll find discussion about the possibility of defining a LINK_ITEMS target property that specifies how a library should appear on the link line as a group of items that are always kept together. This would allow groups as above. However, the discussion never reached a conclusion about the design. Another approach would be to have a first-class feature added to support -as-needed behavior activated by a target property. -Brad -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] Duplicated linking flags are removed when linking final executable
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 -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
Re: [cmake-developers] Duplicated linking flags are removed when linking final executable
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 -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers
[cmake-developers] Duplicated linking flags are removed when linking final executable
Hello, This is my first email to this list, so please tell me if I'm not following the contribution process properly. Here is the scenario that I am working on: .---> -flags A | main > L -| | '---> -flags B If "-flags" are the same text, only one occurrence appears in the resulting linking line in the target's generated link.txt. This is a simple CMakeLists.txt that reproduces the above (doesn't build anything): cmake_minimum_required(VERSION 3.5) file(WRITE a.cpp "") file(WRITE b.cpp "") file(WRITE lib.cpp "") file(WRITE main.cpp "") add_library(A STATIC a.cpp) add_library(B STATIC b.cpp) add_library(L STATIC lib.cpp) 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) When linking, only one occurrence of "-Wl,-whole-archive" and one of "-Wl,-no-whole-archive" are kept. The others are filtered out. All the best, Sergio From 155d039bedfd0cd517866ea131882360700f82a5 Mon Sep 17 00:00:00 2001 From: Sergio Checa Blanco Date: Mon, 14 Mar 2016 13:34:43 +0100 Subject: [PATCH] Duplicated linking flags are removed Duplicated flags are not allowed when linking library targets into a final executable target. The following CMakeLists.txt can be used to test the effect of the patch, by checking the content of the generated file CMakeFiles/main.dir/link.txt. cmake_minimum_required(VERSION 3.5) file(WRITE a.cpp "") file(WRITE b.cpp "") file(WRITE lib.cpp "") file(WRITE main.cpp "") add_library(A STATIC a.cpp) add_library(B STATIC b.cpp) add_library(L STATIC lib.cpp) 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) --- Source/cmComputeLinkDepends.cxx | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 2796fdf..08df390 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -298,6 +298,7 @@ cmComputeLinkDepends::AllocateLinkEntry(std::string const& item) index_entry(item, static_cast(this->EntryList.size())); std::map::iterator lei = this->LinkEntryIndex.insert(index_entry).first; + lei->second = this->EntryList.size(); this->EntryList.push_back(LinkEntry()); this->InferredDependSets.push_back(0); this->EntryConstraintGraph.push_back(EdgeList()); @@ -307,9 +308,12 @@ cmComputeLinkDepends::AllocateLinkEntry(std::string const& item) // int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) { + bool itemIsFlag = (!item.Target && item[0] == '-' && item[1] != 'l' && + item.substr(0, 10) != "-framework"); + // Check if the item entry has already been added. std::map::iterator lei = this->LinkEntryIndex.find(item); - if(lei != this->LinkEntryIndex.end()) + if(lei != this->LinkEntryIndex.end() && !itemIsFlag) { // Yes. We do not need to follow the item's dependencies again. return lei->second; @@ -323,8 +327,7 @@ int cmComputeLinkDepends::AddLinkEntry(cmLinkItem const& item) LinkEntry& entry = this->EntryList[index]; entry.Item = item; entry.Target = item.Target; - entry.IsFlag = (!entry.Target && item[0] == '-' && item[1] != 'l' && - item.substr(0, 10) != "-framework"); + entry.IsFlag = itemIsFlag; // If the item has dependencies queue it to follow them. if(entry.Target) -- 2.1.3 -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers