Переключение между GCC и Clang / LLVM с помощью CMake
у меня есть несколько проектов, построенных с использованием CMake, и я хотел бы иметь возможность легко переключаться между использованием GCC или Clang/LLVM для их компиляции. Я считаю (поправьте меня, если я ошибаюсь!) что для использования Clang мне нужно установить следующее:
SET (CMAKE_C_COMPILER "/usr/bin/clang")
SET (CMAKE_C_FLAGS "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_CXX_COMPILER "/usr/bin/clang++")
SET (CMAKE_CXX_FLAGS "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET (CMAKE_AR "/usr/bin/llvm-ar")
SET (CMAKE_LINKER "/usr/bin/llvm-ld")
SET (CMAKE_NM "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")
есть ли простой способ переключения между этими и переменными GCC по умолчанию, предпочтительно как общесистемное изменение, а не специфическое для проекта (т. е. не просто добавление их в CMakeLists проекта.txt)?
кроме того, это необходимо использовать llvm-* программы, а не системные значения по умолчанию при компиляции с использованием clang вместо gcc? Какая разница?
9 ответов:
CMake чтит переменные среды
CCиCXXпри обнаружении компилятора C и C++ для использования:$ export CC=/usr/bin/clang $ export CXX=/usr/bin/clang++ $ cmake .. -- The C compiler identification is Clang -- The CXX compiler identification is Clangконкретные флаги компилятора можно переопределить, поместив их в системный файл CMake и указав CMAKE_USER_MAKE_RULES_OVERRIDE переменную. Создайте файл
~/ClangOverrides.txtследующего содержания:SET (CMAKE_C_FLAGS_INIT "-Wall -std=c99") SET (CMAKE_C_FLAGS_DEBUG_INIT "-g") SET (CMAKE_C_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") SET (CMAKE_C_FLAGS_RELEASE_INIT "-O4 -DNDEBUG") SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g") SET (CMAKE_CXX_FLAGS_INIT "-Wall") SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g") SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Os -DNDEBUG") SET (CMAKE_CXX_FLAGS_RELEASE_INIT "-O4 -DNDEBUG") SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")суффикс _INIT заставит CMake инициализировать соответствующий
*_FLAGSпеременная с заданным значение. Затем вызовите cmake следующим образом:$ cmake -DCMAKE_USER_MAKE_RULES_OVERRIDE=~/ClangOverrides.txt ..наконец, чтобы принудительно использовать LLVM binutils, установите внутреннюю переменную
_CMAKE_TOOLCHAIN_PREFIX. Эта переменная считаетсяCMakeFindBinUtilsмодуль:$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..собрав все это вместе, вы можете написать оболочку оболочки, которая устанавливает переменные среды
CCиCXXа затем вызывает cmake с указанными переопределениями переменных.
общесистемное изменение C++ на Ubuntu:
sudo apt-get install clang sudo update-alternatives --config c++напечатает что-то вроде этого:
Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/bin/g++ 20 auto mode 1 /usr/bin/clang++ 10 manual mode 2 /usr/bin/g++ 20 manual modeзатем просто выберите clang++.
вы можете использовать команду option:
option(USE_CLANG "build application with clang" OFF) # OFF is the defaultа затем оберните настройки Clang-компилятора в if () s:
if(USE_CLANG) SET (...) .... endif(USE_CLANG)таким образом, он отображается как опция cmake в инструментах gui-конфигурации.
чтобы сделать его общесистемным, вы можете, конечно, использовать переменную окружения в качестве значения по умолчанию или остаться с ответом Ферруччо.
общесистемное изменение C на Ubuntu:
sudo update-alternatives --config ccобщесистемное изменение C++ на Ubuntu:
sudo update-alternatives --config c++для каждого из вышеперечисленных параметров нажмите номер выбора (1) и введите, чтобы выбрать Clang:
Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/bin/gcc 20 auto mode 1 /usr/bin/clang 10 manual mode 2 /usr/bin/gcc 20 manual mode Press enter to keep the current choice[*], or type selection number:
вам определенно не нужно использовать различные различные программы llvm-ar и т. д.:
SET (CMAKE_AR "/usr/bin/llvm-ar") SET (CMAKE_LINKER "/usr/bin/llvm-ld") SET (CMAKE_NM "/usr/bin/llvm-nm") SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump") SET (CMAKE_RANLIB "/usr/bin/llvm-ranlib")они предназначены для работы с внутренним форматом llvm и как таковые не полезны для сборки вашего приложения.
как Примечание-O4 вызовет LTO в вашей программе, которую вы, возможно, не захотите (это значительно увеличит время компиляции) и clang по умолчанию в режиме c99, так что флаг также не обязательно нужен.
вы можете использовать следующий синтаксис:
$ENV{environment-variable}в своемCMakeLists.txtдля доступа к переменным окружения. Вы можете создать сценарии, которые инициализируют набор переменных среды соответствующим образом и просто имеют ссылки на эти переменные в вашемCMakeLists.txtфайлы.
для этого можно использовать файловый механизм toolchain cmake, см. например здесь. Вы пишете файл toolchain для каждого компилятора, содержащий соответствующие определения. Во время настройки вы запускаете, например,
cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/clang-toolchain.cmake ..и вся информация компилятора будет установлена во время вызова project() из файла toolchain. Хотя в документации упоминается только в контексте кросс-компиляции, он также работает для разных компиляторов на одном и том же система.
если компилятор по умолчанию выбрал
cmakeиgccи установленоclang, вы можете использовать простой способ для компиляции вашего проекта сclang:$ mkdir build && cd build $ CXX=clang++ CC=clang cmake .. $ make -j2
согласно справки из
cmake:-C <initial-cache> Pre-load a script to populate the cache. When cmake is first run in an empty build tree, it creates a CMakeCache.txt file and populates it with customizable settings for the project. This option may be used to specify a file from which to load cache entries before the first pass through the project's cmake listfiles. The loaded entries take priority over the project's default values. The given file should be a CMake script containing SET commands that use the CACHE option, not a cache-format file.вы можете создавать файлы, такие как
gcc_compiler.txtиclang_compiler.txtto включает в себя все относительные конфигурации в синтаксисе CMake.Clang пример (clang_compiler.txt):
set(CMAKE_C_COMPILER "/usr/bin/clang" CACHE string "clang compiler" FORCE)затем запустите его как
GCC:
cmake -C gcc_compiler.txt XXXXXXXXлязг:
cmake -C clang_compiler.txt XXXXXXXX