Различные флаги компиляции для одного и того же файла в разных целях
Я хотел бы включить .cpp файл в две разные цели (став двумя VS-проектами после запуска CMake). Я хотел бы установить разные COMPILE_FLAGS для этих проектов.
Однако, когда я делаю
SET_TARGET_PROPERTIES(myfile.cpp PROPERTIES COMPILE_FLAGS "flags1")
ADD_EXECUTABLE(project1 myfile.cpp)
SET_TARGET_PROPERTIES(myfile.cpp PROPERTIES COMPILE_FLAGS "flags2")
ADD_EXECUTABLE(project2 myfile.cpp)
"flags2" применяется для обоих проектов, поэтому кажется, что свойства переписаны в строке 3 и не рассматриваются в строке 2. Является ли это правдой или я что-то упускаю? Есть ли способ решить это?
Спасибо!
Ответы
Ответ 1
Примените команду set_target_properties
к проектам, а не к исходным файлам:
add_executable(project1 myfile.cpp)
set_target_properties(project1 PROPERTIES COMPILE_FLAGS "flags1")
add_executable(project2 myfile.cpp)
set_target_properties(project2 PROPERTIES COMPILE_FLAGS "flags2")
Флаги, установленные на целевой, будут применяться ко всем источникам в пределах цели.
Ответ 2
Если вы придерживаетесь одной цели для каждой философии подкаталога, вы можете сделать следующее с помощью add_definitions
, чтобы добавить свои флаговые компиляции.
# in ./CMakeLists.txt
add_subdirectory(project1)
add_subdirectory(project2)
# in ./project1/CMakeLists.txt:
add_definitions("flags1")
add_executable(project1 ../myfile.cpp)
# in ./project2/CMakeLists.txt:
add_definitions("flags2")
add_executable(project2 ../myfile.cpp)
add_definitions
применяется ко всем файлам, скомпилированным в этом подкаталоге и под ним. Вы можете применять флаги к определенным файлам, используя следующее:
set_source_files_properties(myfile.cpp PROPERTIES COMPILE_FLAGS "flags")
Ответ 3
Я решу эту проблему следующим образом. В CMakeLists.txt:
set_target_properties (test1 PROPERTIES COMPILE_DEFINITIONS "TARGET_ID=1")
set_target_properties (test2 PROPERTIES COMPILE_DEFINITIONS "TARGET_ID=9")
set_source_files_properties (source1.cpp PROPERTIES COMPILE_DEFINITIONS "FILE_ID=7")
set_source_files_properties (source2.cpp PROPERTIES COMPILE_DEFINITIONS "FILE_ID=4")
В некотором заголовочном файле:
#if TARGET_ID==1 && FILE_ID==7
#define SPECIAL_VALUE 17
#elif TARGET_ID==1 && FILE_ID==4
#define SPECIAL_VALUE 14
#elif TARGET_ID==9 && FILE_ID==7
#define SPECIAL_VALUE 97
#elif TARGET_ID==9 && FILE_ID==4
#define SPECIAL_VALUE 94
#endif
Кроме того, включите вышеупомянутый заголовок как в source1.cpp, так и source2.cpp и скомпилируйте
Я думаю, что у CMake нет более приемлемого решения
Ответ 4
У меня была одна и та же проблема (как указать предустановленные зависимые заголовки заголовка в одном исходном файле). К счастью, эффект set_source_files_properties - это только текущий каталог (CMAKE_CURRENT_SOURCE_DIR). Я смог использовать это, чтобы придумать следующее:
In source directory:
CMakeLists.txt:
add_subdirectory(lib_varient_1)
add_subdirectory(lib_varient_2)
LibSources.cmake:
set(SOURCES
"${CMAKE_CURRENT_LIST_DIR}/Source1.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Source2.cpp"
...)
set_source_files_properties(${SOURCES} PROPERTIES
COMPILE_FLAGS "/Yu\"stdafx.h\""
"/Fp\"${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch\"")
set_source_files_properties(${SOURCES} PROPERTIES
OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch")
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/stdafx.cpp
PROPERTIES COMPILE_FLAGS "/Yc\"stdafx.h\""
"/Fp\"${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch\"")
set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/stdafx.cpp
PROPERTIES OBJECT_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/stdafx.pch")
add_library(lib_varient_${VARIENT} ${SOURCES} stdafx.cpp)
In lib_varient_1
CMakeLists.txt:
set(VARIENT 1)
include(../LibSources)
In lib_varient_2
CMakeLists.txt:
set(VARIENT 2)
include(../LibSources)
Это работает, потому что set_source_files_properties влияет только на текущий файл CMakeLists.txt. Вложенный файл будет иметь разные значения для ${VARIENT} и ${CMAKE_CURRENT_BINARY_DIR}, поскольку он включен из двух разных файлов CMakeLists.txt. Вы также можете установить различные флаги компиляции, определения препроцессора или включить пути в каждый из файлов переменных CMakeLists.txt до включения файла LibSources.cmake.
Ответ 5
Я решил эту проблему, используя 2 флага, один для исходного файла, один для цели.
macro(enable_on_source target src)
set_source_files_properties(${src}
PROPERTIES COMPILE_OPTIONS "-OptionModule")
set_target_properties(${target}
PROPERTIES COMPILE_OPTIONS "-OptionTarget")
endmacro()
и во время компиляции я делаю вещи, только если установлены оба параметра.
Это совершенно не зависит от области каталогов, а что нет.