I'm using CMake 3.5.2 generating for Linux / OSX / Visual Studio.

I'm creating a shared library.  This shared library is constructed
mostly from other libraries (which are also built in other directories
by this cmake setup).

I have been doing this for a long time and it worked fine:

  add_library(mylibrary SHARED foo.cpp foo.h bar.cpp bar.h ...)
  target_link_libraries(mylibrary PRIVATE mylib1 mylib2 VerData ...)

Fine.  Now the problem is that I need to generate a link map and I have
a script that parses the object files in mylibrary to create the link
map (the link map is only created/used on Linux of course).

Well, I can't find any way to get a listing of the .o files that are
generated by compiling the .cpp files in the add_library() call above.

So, instead I decided to turn those files into a library, themselves,
then I can use $<TARGET_FILE:mylibrary> with my add_custom_command()
that runs the link map generator script.

However, then I have something like this:

  add_library(libIntern STATIC foo.cpp foo.h bar.cpp bar.h ...)
  add_library(mylibrary SHARED linkmap)
  target_link_libraries(mylibrary PRIVATE libIntern mylib1 mylib2 VerData ...)

  add_custom_command(OUTPUT linkmap COMMAND genmap $<TARGET_FILE:libIntern> ...)
  set_property(TARGET mylibrary APPEND PROPERTY LINK_DEPENDS linkmap)

But this doesn't work because since libIntern is a static library only
the symbols that are referenced somewhere else are included, and no
symbols are actually referenced anymore since there are no source files
in the library.

So then I thought, well, I'll use an OBJECT library for the internal
one:

  add_library(libIntern OBJECT foo.cpp foo.h bar.cpp bar.h ...)
 
add_library(mylibrary SHARED $<TARGET_OBJECTS:libIntern>)
 
target_link_libraries(mylibrary PRIVATE mylib1 mylib2 VerData ...)

  add_custom_command(OUTPUT linkmap COMMAND genmap
$<TARGET_FILE:libIntern> ...)
  set_property(TARGET mylibrary APPEND
PROPERTY LINK_DEPENDS linkmap)

That worked for mylibrary... but of course I can't use $<TARGET_FILE:> anymore 
with an OBJECT library.  And I can't use $<TARGET_OBJECTS:> in my custom 
command either.  In fact I can't find any way to get a list of the object files 
that are part of libIntern.

So then I finally said "whatever" and created another static library out of the 
OBJECT library, just for use with my linkmap generating script:

  add_library(libIntern OBJECT foo.cpp foo.h bar.cpp bar.h ...)
  add_library(mylibrary SHARED linkmap $<TARGET_OBJECTS:libIntern>)
  target_link_libraries(mylibrary PRIVATE mylib1 mylib2 VerData ...)

  add_library(internStatic STATIC $<TARGET_OBJECTS:libIntern>)
  add_custom_command(OUTPUT linkmap COMMAND genmap $<TARGET_FILE:internStatic> 
...)
  set_property(TARGET mylibrary APPEND PROPERTY LINK_DEPENDS linkmap)

This is not nice but it does work...

Except for one thing.  Some of the files in foo.cpp ... depend on a header file 
which is generated as part of the build, using a separate custom command, and I 
handle this by compiling a little static library that needs this header file:

  add_custom_command(OUTPUT verdata.h COMMAND ...)
  set_source_files_properties(verdata.h PROPERTIES HEADER_FILE_ONLY TRUE)
  add_library(VerData STATIC Version.cpp Version.h)
  set_property(SOURCE Version.cpp APPEND PROPERTY OBJECT_DEPENDS verdata.h)

Then the VerData library is added to target_link_libraries() everywhere.  
Coming from a strictly makefile background it doesn't seem to me that this 
should be sufficient, but in fact it appears to work.

But in my new setup you can see that the OBJECT library no longer depends on 
the VerData library, which means that the auto-generated header file is not 
ensured to be created before the compilation of the objects in libIntern.  And 
in fact, I get compilation errors because the verdata.h file is not generated 
before these compilations (particularly in Xcode, for some reason).

And, I don't know how to solve this problem: I can't find any way to add a new 
prerequisite to the the libIntern OBJECT library to ensure that the VerData 
library is built first.  I can't add a target_link_libraries() to an OBJECT 
library.  I sure don't want to have to explicitly set the OBJECT_DEPENDS 
property on every single source file!


All I want to do is call a script passing the object files to generate a link 
map before I create my shared library, and I've gone all the way down this 
rabbit hole...

Help!
-- 

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

Reply via email to