5

I would like to generate a module definition file based on all symbols available in object files in dynamic fashion (think of GTKMM's gendef).

For this, I would like to add_custom_command for PRE_LINK step of a target. However, it looks like there is no easy way to get path to all object files with CMake that would work for plain makefiles as well as for multi-configuration generators like Visual Studio.

Right now, I have the following

add_custom_command(TARGET tgt PRE_LINK
COMMAND gendef ${CMAKE_CURRENT_BINARY_DIR}/tgt.def $<TARGET_FILE_NAME:tgt> ${CMAKE_CURRENT_BINARY_DIR}/$<$<BOOL:${CMAKE_BUILD_TYPE}>:${CMAKE_FILES_DIRECTORY}>/tgt.dir/${CMAKE_CFG_INTDIR}/*.obj
)

However this is quite awkward and bulky as I have to use generator expression in my opinion. Is there a better way to achieve this effect, i.e. call a certain external program for each build configuration?

Is it a CMake bug (feature?) that for plain makefiles, all object files go to CMakeFiles/tgt.dir folder while for multiconfiguration generators all goes to a sibling of CMakeFiles, i.e. tgt.dir/$<CONFIG>? Did I miss some simple variable that would point me to the right place directly?

Florian
  • 39,996
  • 9
  • 133
  • 149
mlt
  • 1,595
  • 2
  • 21
  • 52
  • I had a similar request myself in the past. And as far as I know there is no easy way to get the list of object files. I assume you were aware of ["CMake: Is there an elegant way to get list of object files participating into a library?"](http://cmake.3232098.n2.nabble.com/Is-there-an-elegant-way-to-get-list-of-object-files-participating-into-a-library-tp6071240.html). Have you tried the intermediate static library approach? Or you could think of object libraries and support [0016041: Add support for $ in add_custom_command()](https://cmake.org/Bug/view.php?id=16041). – Florian Apr 03 '16 at 19:54

2 Answers2

1

Turning my comment into an answer

Makefile projects generated by CMake have a totally different internal structure then solutions/projects generated for Visual Studio. I think this is neither a bug nor a feature, those structures are just optimized for their usecases.

And as far as I know there is no easy CMake internal way to get the list of object files or the path to the intermediate files directory with e.g. reading a target property.

So I have taken your code example and have done some testing for alternatives with CMake 3.3.2 using Visual Studio 14 2015 and NMake Makefiles generators.

Alternatives

  1. One related discussion on the CMake mailing list named "CMake: Is there an elegant way to get list of object files participating into a library?" does suggest using an intermediate static library:

    add_library(tgtlib STATIC tgt.c)
    add_custom_command(
        OUTPUT tgt.def
        COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> $<TARGET_FILE:tgtLib> 
    )
    file(WRITE dummy.c "")
    add_library(tgt SHARED dummy.c tgt.def)
    target_link_libraries(tgt tgtlib)
    
  2. You could add build environment specific elements to your PRE_LINK step:

    if(CMAKE_CONFIGURATION_TYPES)
        set(_obj_files "$(IntermediateOutputPath)*.obj")
    else()
        set(_obj_files "$?")
    endif()
    add_custom_command(
        TARGET MainProject 
        PRE_LINK
        COMMAND gendef tgt.def $<TARGET_FILE_NAME:tgt> ${_obj_files}
    )
    

References

Florian
  • 39,996
  • 9
  • 133
  • 149
0

List of compiled object files could be extracted via $<TARGET_OBJECTS> generator expression. While its primary purpose was to extract object files from OBJECT library target, it actually works for all other library and executable targets:

add_executable(main main.cpp foo.c)

add_custom_target(list_objects ALL
  COMMAND echo "Objects:" $<TARGET_OBJECTS:main>
  VERBATIM
  )

Upon building it would print

Objects: /home/tester/tests/cmake/build/CMakeFiles/main.dir/main.cpp.o;/home/tester/tests/cmake/build/CMakeFiles/main.dir/foo.c.o

Note, that generator expressions cannot be printed via message command. But they may appear as arguments for some other commands, which have documented usage of generator expressions. For more details about printing generator expressions, see that question.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153