Как получить путь к объектным файлам с помощью CMake как для генератора многоконфигурации, так и для файла makefile?
Я хотел бы сгенерировать файл определения модуля на основе всех символов, доступных в объектных файлах в динамическом режиме (подумайте о gendef GTKMM).
Для этого я бы хотел add_custom_command
за PRE_LINK
шаг цели. Тем не менее, похоже, что нет простого способа получить путь ко всем объектным файлам с помощью CMake, который бы работал для простых make-файлов, а также для генераторов с несколькими конфигурациями, таких как Visual Studio.
Прямо сейчас у меня есть следующее
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
)
Однако это довольно неловко и громоздко, так как я должен использовать выражение генератора по моему мнению. Есть ли лучший способ добиться этого эффекта, т.е. вызывать определенную внешнюю программу для каждой конфигурации сборки?
Это ошибка CMake (функция?), Что для простых make-файлов все объектные файлы идут в CMakeFiles/tgt.dir
папка, в то время как для многоконфигурационных генераторов все идет к брату CMakeFiles, т.е. tgt.dir/$<CONFIG>
? Я пропустил какую-то простую переменную, которая указала бы мне прямо в нужное место?
2 ответа
Превращаю мой комментарий в ответ
Проекты Makefile, сгенерированные CMake, имеют совершенно иную внутреннюю структуру, чем решения / проекты, сгенерированные для Visual Studio. Я думаю, что это не ошибка и не особенность, эти структуры просто оптимизированы для использования.
И, насколько я знаю, нет простого внутреннего способа CMake получить список объектных файлов или путь к каталогу промежуточных файлов, например, с помощью чтения целевого свойства.
Итак, я взял ваш пример кода и провел некоторое тестирование альтернатив с использованием CMake 3.3.2, используя Visual Studio 14 2015
а также NMake Makefiles
генераторы.
альтернативы
Одно связанное обсуждение списка рассылки CMake под названием "CMake: существует ли элегантный способ получить список объектных файлов, участвующих в библиотеке?" предлагает использовать промежуточную статическую библиотеку:
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)
Вы можете добавить специфичные для среды сборки элементы к вашему
PRE_LINK
шаг: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} )
Рекомендации
Список скомпилированных объектных файлов можно извлечь с помощью$<TARGET_OBJECTS>
выражение генератора . Хотя его основной целью было извлечение объектных файлов из целевой библиотеки OBJECT, на самом деле он работает для всех других целевых библиотек и исполняемых файлов:
add_executable(main main.cpp foo.c)
add_custom_target(list_objects ALL
COMMAND echo "Objects:" $<TARGET_OBJECTS:main>
VERBATIM
)
После сборки он будет печатать
Objects: /home/tester/tests/cmake/build/CMakeFiles/main.dir/main.cpp.o;/home/tester/tests/cmake/build/CMakeFiles/main.dir/foo.c.o
Обратите внимание, что выражения генератора не могут быть напечатаны черезmessage
команда. Но они могут выступать в качестве аргументов для некоторых других команд, в которых задокументировано использование выражений-генераторов. Более подробную информацию о печати выражений генератора смотрите в этом вопросе .