MantisBT - CMake
View Issue Details
0008946CMakeCMakepublic2009-04-29 06:552016-06-10 14:30
Alexandre Feblot 
Brad King 
normalfeatureN/A
closedmoved 
CMake-2-6 
 
0008946: Need a solution to surround some libraries with linker flags inthe link line
There is no way to surround some (whatever they are, whereever they are located in the link line) libraries with linker flags such as -Wl,-whole-archive / -Wl,-no-whole-archive in the link command.

This is needed for imported targets, and probably for regular targets too.

There could be 2 target properties for this: LINK_PRE_FLAG, LINK_POST_FLAG

I've found an ugly and probably not robust workaround to surround *one* library, but it does not work for more (because the flags are only added once in the link line), as shown in this post:
http://www.cmake.org/pipermail/cmake/2009-March/028348.html [^]

No tags attached.
Issue History
2009-04-29 06:55Alexandre FeblotNew Issue
2009-04-29 09:35Bill HoffmanStatusnew => assigned
2009-04-29 09:35Bill HoffmanAssigned To => Brad King
2009-04-29 10:22Brad KingNote Added: 0016245
2009-04-29 11:43Alexandre FeblotNote Added: 0016247
2009-04-29 12:33Brad KingNote Added: 0016248
2009-04-29 12:38Brad KingSeveritymajor => feature
2009-04-29 15:31Alexandre FeblotNote Added: 0016252
2009-04-29 15:33Alexandre FeblotNote Added: 0016253
2009-04-30 08:54Brad KingNote Added: 0016267
2009-04-30 09:19Alexandre FeblotNote Added: 0016268
2012-08-13 10:36Brad KingStatusassigned => backlog
2012-08-13 10:36Brad KingNote Added: 0030494
2013-11-02 11:18Stephen KellyNote Added: 0034330
2016-06-10 14:27Kitware RobotNote Added: 0041549
2016-06-10 14:27Kitware RobotStatusbacklog => resolved
2016-06-10 14:27Kitware RobotResolutionopen => moved
2016-06-10 14:30Kitware RobotStatusresolved => closed

Notes
(0016245)
Brad King   
2009-04-29 10:22   
I propose the names LINK_INTERFACE_PRE_FLAGS and LINK_INTERFACE_POST_FLAGS since they affect things that link to the target rather than the target itself.

The proper place to evaluate them is in cmComputeLinkInformation::AddTargetItem where the target file path is added to the command line.

I still need to think about how this interacts with install(EXPORT). Flags are specific to the compiler used by the importing project, so it is probably not appropriate for an exporting project to put these flags on its exported targets. Furthermore, in the whole-archive case, some importing projects may want the whole archive and some may not.
(0016247)
Alexandre Feblot   
2009-04-29 11:43   
*** Not sure about how you understand it, but there should be a different PRE_FLAGS/POST_FLAG setting for each library used in an executable target link.

See this little example:

# in libraries CMakeLists:
set_target_properties(LIBA PROPERTIES PRE_FLAGS <preflagForLibA>
                                      POST FLAG <postFlagForlibA>)
set_target_properties(LIBB PROPERTIES PRE_FLAGS <preflagForLibB>
                                      POST FLAG <postFlagForlibB>)
# in exes CMakeLists:
target_link_libraries(EXE1 LIBA LIBB LIBC ...)
target_link_libraries(EXE2 LIBA LIBB LIBC ...)


*** After thinking a little more, this settings should/could also be executable-dependant, although I have not needed this yet.
To take into account this executable-dependant requirement, I see 2 solutions:

1) Overwite the properties in each executable CMakeLists.

2) Use dynamic variable like these, (which I find ugly):

LINK_INTERFACE_PRE_FLAGS_<library>
LINK_INTERFACE_POST_FLAGS_<library>

i.e.:

# in exes CMakeLists:
set_target_properties(EXE1 PROPERTIES PRE_FLAGS_LIBA <preflagForLibAInExe1>
                                      POST FLAG_LIBA <postFlagForlibAInExe1>
                                      PRE_FLAGS_LIBB <preflagForLibBInExe1>
                                      POST FLAG_LIBB <postFlagForlibBInExe1>)
set_target_properties(EXE2 PROPERTIES PRE_FLAGS_LIBA <preflagForLibAInExe2>
                                      POST FLAG_LIBA <postFlagForlibAInExe2>
                                      PRE_FLAGS_LIBB <preflagForLibBInExe2>
                                      POST FLAG_LIBB <postFlagForlibBInExe2>)
target_link_libraries(EXE1 LIBA LIBB LIBC ...)
target_link_libraries(EXE2 LIBA LIBB LIBC ...)


Note: I just used shorter property names to make it easy in the example.
(0016248)
Brad King   
2009-04-29 12:33   
In the case of whole-archive, the entire archive will be copied into the target. IMO this should be a deliberate act by the creator of that target, and not done through a chain of dependencies. In other words, the archive (e.g. 'whole') should appear on the target_link_libraries line:

  target_link_libraries(myexe whole)

and not just brought in through the link interface of a library:

  target_link_libraries(mylib whole) # copy 'whole' into mylib?
  target_link_libraries(myexe mylib) # copy 'whole' into myexe? duplicates?

Therefore the feature you request is not necessary. One can just write

  target_link_libraries(myexe -Wl,--whole-archive whole -Wl,--no-whole-archive)

CMake will preserve the flags and library in order. If 'whole' depends on anything else (e.g. zlib) then its dependencies will be added at the end.
(0016252)
Alexandre Feblot   
2009-04-29 15:31   
"IMO this should be a deliberate act by the creator of that target, and not done through a chain of dependencies"

Well, as you say ;-)
But this is not always possible. My entire system is built on taking advantage of the dependency chain to generate the link, with 360 project libs and about 50 third party libs used in 60 different executables.
In this project, when describing an executable top dependencies, we have no idea of what will be linked through the dependency chain. That's exactly the beauty of the system: Just describe first level dependencies of each lib and let cmake do the job.
But, it turns out that a few third party libs need to be forced to be fully included, because some of their symbols will be required by a dlopen'ed shared lib.

I think IHMO my situation is not totally absurd and not so specific, and the feature request makes sens here. What do you think about it?
(0016253)
Alexandre Feblot   
2009-04-29 15:33   
I forgot to mention that I also use the dependency chain mechanism for third party libs, by describing each of them as an imported target, and setting it's dependency property.
(0016267)
Brad King   
2009-04-30 08:54   
What kind of targets are your intermediate dependencies?

  add_library(whole STATIC ...)
  set_target_properties(whole PROPERTIES ...) # requested link flag properties

  # case 1
  add_library(myArchive STATIC ...)
  target_link_libraries(myArchive whole) # doesn't really link
  add_executable(myExeA ...)
  target_link_libraries(myExeA myArchive) # links myArchive, copies 'whole'

  # case 2
  add_library(myShared SHARED ...)
  target_link_libraries(myShared whole) # copies 'whole' into myShared
  # uh, oh...objects from 'whole' are not -fPIC
  add_executable(myExeS ...)
  target_link_libraries(myExeS myShared) # links myShared, copies 'whole'
  # uh, oh...objects from 'whole' appear twice

You never have case 2?
(0016268)
Alexandre Feblot   
2009-04-30 09:19   
Right, I only have to deal with case 1 for now.
(0030494)
Brad King   
2012-08-13 10:36   
Sending issues I'm not actively working on to the backlog to await someone with time for them.

If an issue you care about is sent to the backlog when you feel it should have been addressed in a different manner, please bring it up on the CMake mailing list for discussion. Sign up for the mailing list here, if you're not already on it:

 http://www.cmake.org/mailman/listinfo/cmake [^]

It's easy to re-activate a bug here if you can find a CMake developer or contributor who has the bandwidth to take it on.
(0034330)
Stephen Kelly   
2013-11-02 11:18   
In case 2, users could be required to set the POSITION_INDEPENDENT_CODE target property to detect/diagnose that case.
(0041549)
Kitware Robot   
2016-06-10 14:27   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.