#c #makefile #cmake
Вопрос:
У меня есть библиотека C, которую я использую в проекте. Он состоит из .c
.h
файлов и src
каталогов и include
каталогов. Я написал CMakeLists.txt
файл, который генерирует Makefile
файл, который компилируется library.so
.
Дело в том, что библиотека также включает .c
файлы для тестов, заголовки совместимости для других операционных систем и другие файлы, которые я на самом деле не использую. Я хотел бы определить, какие файлы src/заголовков на самом деле скомпилированы в .so
библиотеку. Есть ли способ сделать это автоматически, на основе CMakeLists.txt
или Makefile
без просмотра и изучения каждого файла?
Комментарии:
1. Делает
get_target_property(LIB_SOURCES lib_target SOURCES)
ли это свою работу?2. @kaylum Эта команда включает только исходные
.c
файлы, игнорируя заголовки.3. Это зависит от того, как ваш CMakeLists.txt написано. Которые вы не показали, поэтому не можете предоставить дальнейшие комментарии по этому поводу.
4. У Make есть возможность
-n
выполнить предварительный запуск, то есть распечатать все команды без их фактического выполнения. Таким образом, вы сможете увидеть, какие модули будут скомпилированы и связаны. — У компиляторов обычно есть опции для создания списка, в котором указано, какие файлы были включены. Некоторые даже распечатывают прочитанные файлы. — Все дело в чтении документации по вашим инструментам.5. Не уверен, возможно ли это для заголовочных файлов, но для исходных файлов при восстановлении с нуля все файлы .o перечислены в выводе командной строки, и на каждый файл .c приходится один файл .o. Но для заголовков я почти уверен, что cmake не выполняет синтаксический анализатор, который мог бы понять
#ifdef FOO #include <a/b.h> #else #include <c/d.h> #endif
, тем более, что вам не требуется перечислять заголовочные файлы по отдельности, но вы могли бы просто сделать atarget_include_directories
для некоторого dir. Однако могут быть параметры, зависящие от компилятора, которые могут работать;Я знаю, что для VS существует один; не уверен, что его можно установить из cmake
Ответ №1:
Если вы используете gcc
, то вы можете обмануть компилятор, чтобы он сообщил вам, какие исходные файлы он использовал, создав информацию о зависимостях для следующего make
запуска. Если я прав, необходимыми флагами являются:
-MT $@ -MMD -MP -MF $(AUTODEP_DIR)$(notdir $@).d
Это должно привести к foo.cpp
созданию файла foo.o.d
, содержащего строки с целевыми условиями, такие как:
foo.o : foo.cpp bar.hpp baz.hpp
foo.cpp :
bar.hpp :
baz.hpp :
где в первой строке отображается то, что использовалось в качестве исходного кода C/C при компиляции объектного файла, а далее-то, что нужно (ничего или, скорее, невидимая рука программиста, в большинстве случаев) для создания исходных файлов.
clang
и у других компиляторов, конечно, есть свой собственный, возможно, отличающийся набор флагов, но выбрать их не должно быть слишком сложно.