LINUX.ORG.RU

Пара вопросов об использовании CMake

 ,


2

1

Редко имею дело с CMake, поэтому многих связанных с CMake вещей, не понимаю. Буду признателен за разъяснения или указания где именно можно найти нужную информацию.

Первый непонятный момент. Допустим, есть простая ситуация: Linux и всего два компилятора — gcc и clang. Мне нужно пользоваться то тем, то другим. При этом компилироваться как в release-режиме, так и в debug. Правильно ли я понимаю, что каноническим решением является вот такое:

cd ~/develop/my-project
mkdir build_gcc_release
cd build_gcc_release
cmake -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release ..
cd ..
mkdir build_gcc_debug
cd build_gcc_debug
cmake -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Debug ..
mkdir build_clang_release
cd build_clang_release
cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Release ..
cd ..
mkdir build_clang_debug
cd build_clang_debug
cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Debug ..

Второй непонятный момент. Допустим, мне нужно использовать три внешних проекта (p1, p2, p3), у которых сборка делается через CMake. При этом я хочу, чтобы результаты компиляции всех трех подпроектов (т.е. исполнимые файлы и so-ки) сбрасывались в одни и те же каталоги. Т.е. вместо того, чтобы иметь что-то вроде p1/build/lib b p1/build/bin, p2/build/lib и p2/build/bin, p3/build/lib и p3/build/bin, я хочу иметь my-project/build/lib и my-project/build/bin.

Правильно ли я понимаю, что в этом случае у меня получается что-то вроде:

cd ~/develop/my-project
wget https://p1.home/download/p1-some-ver.tar.gz
tar -xf p1-some-ver.tar.gz
cd p1-some-ver
mkdir build_gcc_release
cd build_gcc_relese
cmake -DCMAKE_INSTALL_PREFIX=~/develop/my-project/build -DCMAKE_BUILD_TYPE=Release ..
make install
cd ../..

wget https://p3.home/download/p2-some-ver.tar.gz
tar -xf p2-some-ver.tar.gz
cd p2-some-ver
mkdir build_gcc_release
cd build_gcc_relese
cmake -DCMAKE_INSTALL_PREFIX=~/develop/my-project/build -DCMAKE_BUILD_TYPE=Release ..
make install
cd ../..

...
Т.е. я создаю compiler-specific makefiles для каждого из подпроектов, но при этом для всех подпроектов указываю общее значение CMAKE_INSTALL_PREFIX?

★★★★★

первый: можно или так, или почитать про include и вынести все, что нужно в отдельные файлы. потом, например

cmake -DCOMPILER_SET=gcc.cmake

второй:

да, либо опять же разрулить в скрпитах можно (смотри find_package)

anonymous
()

Правильно ли я понимаю, что каноническим решением является вот такое

Да.

По второму: если это куски одного проекта, которые без этого проекта не особо нужны, то каноничным решением будет add_subdirectory и набор option; если это самостоятельные проекты, то каноничного будет ставить их отдельно и пилить для них Find${whatever} или pkg- модули.

Stil ★★★★★
()

По второму вопросу можно еще воспользоваться ExternalProject_Add и указать в INSTALL_COMMAND параметре нужный DESTDIR.

m0rph ★★★★★
()
Ответ на: комментарий от anonymous

или почитать про include и вынести все, что нужно в отдельные файлы

Тут не очень понятно. Как я понимаю, cmake даже для одного компилятора, но для разных режимов сборки должен сгенерировать независимые наборы make-файлов (с разными командными строками внутри). А посему для release/debug напрашиваются разные каталоги (build_release/build_debug), в каждом из которых свои наборы make-файлов.

И как в этом случае поможет gcc.cmake, по который вы говорите, не понятно, к сожалению.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

И как в этом случае поможет gcc.cmake, по который вы говорите, не понятно, к сожалению.

это не про директории, это про настройку окружения. директории нужно отдельные, да

у меня например так сборка, схематично

cd ../build_android
cmake -DCOMPILER_SET=gcc_android.cmake ../project
cd ../build_mips
cmake -DCOMPILER_SET=gcc_mips.cmake ../project
...

и тд. Естественно каждый отдельно собирается. А сейчас вообще докер юзаю и не парюсь :D

anonymous
()
Ответ на: комментарий от anonymous

директории нужно отдельные, да

Вопрос был как раз про директории.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от Stil

если это куски одного проекта, которые без этого проекта не особо нужны, то каноничным решением будет add_subdirectory и набор option;

А можно чуть подробнее?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

сдается мне, товарищ предлагает «прям на месте» собирать эти сторонние проекты. Я так с lua делаю, например. Собираю вместе со своим проектом в статическую либу.

anonymous
()

Первый - правильно.

Во втором есть варианты.

Например, можно сделать эти проекты продпроектами одного большого проекта. Я, например, регулярно так поступаю с gmock :)

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Например, можно сделать эти проекты продпроектами одного большого проекта. Я, например, регулярно так поступаю с gmock :)

Если речь про что-то вроде git submodules или hg subrepos, то вопрос не в том, как именно доставать исходники подпроектов. Вопрос в том, как поступать с корневыми CMakeFiles.txt этих подпроектов. И чтобы результаты сборки всех подпроектов оказывались бы в одном и том же месте.

eao197 ★★★★★
() автор топика
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от eao197

Не не не, речь как раз про CMake скрипты - просто исользуй add_subdirectory.

Один мета проект сделаешь он будет настройки сборки и установки шарить для подпроектов. Аналог sln в студии, только круче.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Т.е., если у меня будет что-то вроде:

my-project/
`- p1/
   `- CMakeLists.txt
`- p2/
   `- CMakeLists.txt
...
`- CMakeLists.txt
Где в моем CMakeLists.txt будут инструкции:
add_subdirectory(p1)
add_subdirectory(p2)
...
то это будет просто работать даже если в p1/CMakeLists.txt будет какой-нибудь хардкор с find_package и пр.?

eao197 ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Да, про это и речь.

Вроде бы такой способ работает. Теоретически, могут быть фокусы, если проекты ожидают пересекающийся набор опций, у которых одинаковые имена, но разные значения (например, p1 ожидает WITH_SRV=ON, а p2 — WITH_SRV=OFF). Но это пока маловероятно.

eao197 ★★★★★
() автор топика
Ответ на: комментарий от eao197

в точку

только если это будут не поддиректории каталога в котором лежит файл проекта, надо будет одно дополнительное телодвижение сделать, не помню ща какое - CMake ругнётся, эту ругань надо будет погуглить.

pon4ik ★★★★★
()
Ответ на: комментарий от eao197

Что-то типа

option(WITH_Foo "build with foo" ON)
option(WITH_Bar "build with bar" OFF)

add_subdirectory("${CMAKE_SOURCE_DIR}/src/Core")

if (WITH_Foo)
    add_subdirectory("${CMAKE_SOURCE_DIR}/src/Foo")
endif()
if (WITH_Bar)
    add_subdirectory("${CMAKE_SOURCE_DIR}/src/Bar")
endif()
Stil ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.