Re: [cmake-developers] Duplicated linking flags are removed when linking final executable

2016-03-15 Thread Brad King
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

2016-03-15 Thread Sergio Checa
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

2016-03-14 Thread Brad King
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

2016-03-14 Thread Sergio Checa
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