Различные флаги компиляции для одного и того же файла в разных целях

Я хотел бы включить .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()

и во время компиляции я делаю вещи, только если установлены оба параметра.

Это совершенно не зависит от области каталогов, а что нет.