Переход на CMake - один источник, 48 DLL - PullRequest
0 голосов
/ 12 марта 2019

Я поддерживаю библиотеку геометрии C ++, которая скомпилирована в двух разных вариантах из одного и того же исходного кода с использованием #defines, а именно для 2D / 2.5D. Эти два варианта скомпилированы для Win32 / x64 и как версии Debug / Release. Таким образом, для каждой из VS2008, 2010, 2012, 2013, 2015 и 2017 годов создано 8 библиотек DLL. В настоящее время я использую решение Visual Studio, созданное вручную: enter image description here

и Пакетная сборка. Это работает, но я бы предпочел использовать CMake для компиляции DLL через командную строку. Нет необходимости создавать решение для Visual Studio IDE, поскольку исходный код разработан под Linux.

До сих пор я, скорее, пользователь CMake, поэтому я хотел бы спросить, имеет ли смысл приведенное ниже решение:

  1. Создайте один файл CMakeLists.txt, который содержит два вызова add_library, один для 2D и один для 2.5D. Используя SET_TARGET_PROPERTIES должно быть возможно передать различные #defines.
  2. Команда "cmake -G" Visual Studio 11 "-A x64 -DCMAKE_BUILD_TYPE = Release .." должна, например, создать два варианта DLL для VS2012 / x64 / Release.
  3. Для VS 2008-2017, Debug / Release, Win32 / x64 потребовалось бы 24 таких вызова, и я поместил бы их в скрипт.

В: Имеет ли смысл вышесказанное?

В: Как можно написать сценарий для 24 вызовов CMake, когда необходимо изменить оболочку или хотя бы переменные окружения для соответствия различным компиляторам?

В: Верно ли, что Debug / Release, Win32 / 64 не могут быть указаны внутри CMakeLists.txt и, следовательно, должны быть переданы команде cmake?

На всякий случай: библиотека используется во многих проектах, и пользователям действительно нужна поддержка старых компиляторов. Возможно не для VS2008, но VS2010 все еще очень популярен.

1 Ответ

1 голос
/ 13 марта 2019

Имеет ли смысл вышесказанное?

Да.

Как можно написать 24 вызова CMake, когда необходимо изменить оболочку или хотя бы переменные окружения для соответствия различным компиляторам?

Просто один за другим?

cmake -S . -B 17_64_R -G "Visual Studio 15 2017" -A x64 -D CMAKE_BUILD_TYPE=Release
cmake --build 17_64_R --target all
cmake -S . -B 17_64_D -G "Visual Studio 15 2017" -A x64 -D CMAKE_BUILD_TYPE=Debug
cmake --build 17_64_D --target all
... and so on ...
cmake -S . -B 08_32_D -G "Visual Studio 9 2008" -A Win32 -D CMAKE_BUILD_TYPE=Debug
cmake --build 08_32_D --target all

Правильно ли, что Debug / Release, Win32 / 64 не могут быть указаны внутри CMakeLists.txt и, следовательно, должны быть переданы команде cmake?

Нет, вы можете. Правильно, что эта информация не должна указываться в конфигурации cmake. Cmake - это инструмент для настройки сборки, поэтому он останется переносимым на разные архитектуры. Почему тогда вы решили ограничить cmake для генерации только одной конфигурации, если целью использования cmake является переносимость? (Наиболее распространенный ответ: использовать богатые функции cmake для создания правильной системы сборки). Это не хорошая практика. Но вы всегда можете set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_GENERATOR "Visual Studio 17"), а иногда и можете, но только для проверки конфигурации cmake.

один для 2D и один для 2.5D. Используя SET_TARGET_PROPERTIES должно быть возможно передать различные # определения.

Это выглядело бы странно. Просто добавьте в CMakeLists.txt:

  add_executable(final_executable ...)

  # then below
  if(${FLAVOR} STREQUAL "2D")
      target_compile_definitions(final_executable
           PUBLIC
              FLAVOR_2D=1
              SOME_OTHER_MACRO_YOU_WOULD_LIKE_TO_SET="2D FLAVOR"
       )
       target_link_libraries(final_executable PUBLIC 2d_library)
       # ... and so on ...
  elif(${FLAVOR} STREQUAL "2.5D")
      target_compile_definitions(final_executable
           PUBLIC
              FLAVOR_2_5D=1
              SOME_OTHER_MACRO_YOU_WOULD_LIKE_TO_SET="2.5D FLAVOR"
       )
       target_link_libraries(final_executable PUBLIC 2_5d_library)
  else()
      message(FATAL_ERROR "You must specify FLAVOR to be 2D or 2.5D")
  endif()

Затем вы настраиваете систему сборки:

  # for 2D configuration
  cmake ... -D FLAVOR="2D" ...
  # for 2.5D configuration
  cmake ... -D FLAVOR="2.5D" ...

Нет необходимости использовать set_target_properties при настройке макросов. И вам не следует этого делать, для этого есть команды cmake. Есть target_compile_definitions, target_inlude_directories, target_link_libraries и, наконец, на новейшем cmake target_link_options (который только что был сделан с target_link_libraries на старых версиях). Даже target_sources давайте добавим источники. Обычно set_target_properties используется для продвинутых вещей, таких как interprocedural_optimization и тому подобное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...