Подтвердить что ты не робот

Каталог вывода/создания CMake

Я новичок в CMake, прочитал несколько уроков о том, как его использовать, и написал несколько сложных 50 строк сценария CMake, чтобы создать программу для 3 различных компиляторов. Это, вероятно, завершает все мои знания в CMake.

Теперь моя проблема в том, что у меня есть некоторый исходный код, к папке которого я не хочу прикасаться/возиться при создании программы. Я хочу, чтобы все выходные файлы и папки CMake и make помещались в ../Compile/, поэтому я изменил несколько переменных в моем сценарии CMake для этого, и какое-то время это работало, когда я делал что-то подобное на своем ноутбуке:

Compile$ cmake ../src
Compile$ make

Где с этим у меня был чистый вывод в папке, в которой я сейчас нахожусь, и это именно то, что я ищу.

Теперь я перешел на другой компьютер и перекомпилировал CMake 2.8.11.2, и я почти вернулся к исходной точке! Он всегда компилирует это в папку src, где находится мой CMakeLists.txt.

Часть, где я выбираю каталог в моем скрипте CMake, выглядит так:

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

И теперь это всегда заканчивается:

-- Build files have been written to: /.../src

Я что-то упустил?

4b9b3361

Ответ 1

Там немного нужно установить все переменные, которые вы устанавливаете. CMake устанавливает их на разумные значения по умолчанию. Вам определенно не следует изменять CMAKE_BINARY_DIR или CMAKE_CACHEFILE_DIR. Относитесь к ним только для чтения.

Сначала удалите существующий проблемный файл кэша из каталога src:

cd src
rm CMakeCache.txt
cd ..

Затем удалите все команды set() и выполните:

cd Compile
rm -rf *
cmake ../src

Пока вы находитесь за пределами исходного каталога при запуске CMake, он не будет изменять исходный каталог, если ваш CMakeList явно не сообщит об этом.

Если у вас все получилось, вы можете посмотреть, куда CMake помещает вещи по умолчанию, и только если вы не удовлетворены местоположениями по умолчанию (например, значением по умолчанию EXECUTABLE_OUTPUT_PATH), измените только те, которые вам нужны. И попробуйте выразить их относительно CMAKE_BINARY_DIR, CMAKE_CURRENT_BINARY_DIR, PROJECT_BINARY_DIR и т.д.

Если вы посмотрите документацию CMake, вы увидите переменные, разделенные на семантические разделы. За исключением особых случаев, вы должны рассматривать все перечисленные в разделе "Переменные, которые предоставляют информацию" только для чтения внутри CMakeLists.

Ответ 2

Похоже, вы хотите сборку из исходного кода. Есть несколько способов создать сборку вне исходного кода.

  1. Делай то, что ты делал, беги

    cd /path/to/my/build/folder
    cmake /path/to/my/source/folder
    

    что заставит cmake сгенерировать дерево сборки в /path/to/my/build/folder для исходного дерева в /path/to/my/source/folder.

    После того, как вы его создали, cmake запоминает, где находится исходная папка - так что вы можете повторно запустить cmake в дереве сборки с помощью

    cmake /path/to/my/build/folder
    

    или даже

    cmake .
    

    если ваш текущий каталог уже является папкой сборки.

  2. Используйте некоторые недокументированные параметры, чтобы установить исходные файлы и папки для сборки:

    cmake -B/path/to/my/build/folder -H/path/to/my/source/folder
    

    который будет делать то же самое, что и (1), но без использования текущего рабочего каталога.

CMake помещает все свои выходные данные в дерево сборки по умолчанию, поэтому, если вы не используете ${CMAKE_SOURCE_DIR} или ${CMAKE_CURRENT_SOURCE_DIR} в файлах cmake, он не должен касаться дерева исходных ${CMAKE_CURRENT_SOURCE_DIR}.

Самая большая вещь, которая может пойти не так, если вы ранее создали дерево сборки в вашем исходном дереве (т.е. у вас есть встроенная сборка). После того, как вы это сделали, вступает в силу вторая часть (1) выше, и cmake не вносит никаких изменений в источник или места сборки. Таким образом, вы не можете создать сборку вне исходного кода для исходного каталога со сборкой из исходного кода. Вы можете легко это исправить, удалив (как минимум) CMakeCache.txt из исходного каталога. Есть несколько других файлов (в основном в каталоге CMakeFiles), которые CMake генерирует, которые вы также должны удалить, но они не заставят cmake трактовать исходное дерево как дерево сборки.

Поскольку сборки из исходного кода часто более желательны, чем сборки из исходного кода, вы можете изменить свой cmake так, чтобы он требовал сборок из исходного кода:

# Ensures that we do an out of source build

MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${CMAKE_BINARY_DIR}" insource)
     GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${PARENTDIR}" insourcesubdir)
    IF(insource OR insourcesubdir)
        MESSAGE(FATAL_ERROR "${MSG}")
    ENDIF(insource OR insourcesubdir)
ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
    "${CMAKE_PROJECT_NAME} requires an out of source build."
)

Приведенный выше макрос MacroOutOfSourceBuild из широко используемого модуля MacroOutOfSourceBuild. Существует множество источников для MacroOutOfSourceBuild.cmake в Google, но я не могу найти оригинал, и он достаточно короткий, чтобы включить его полностью.

К сожалению, cmake обычно записывает несколько файлов к моменту запуска макроса, поэтому, хотя он не позволит вам фактически выполнить сборку, вам все равно придется удалить CMakeCache.txt и CMakeFiles.

Может оказаться полезным установить пути, в которые записываются двоичные, разделяемые и статические библиотеки - в этом случае посмотрите, как сделать вывод cmake в каталог 'bin'? (Отказ от ответственности, у меня есть лучший голос на этот вопрос... но, как я знаю об этом).

Ответ 3

По состоянию на CMake Wiki:

CMAKE_BINARY_DIR, если вы строите в исходном коде, это то же самое, что и CMAKE_SOURCE_DIR, в противном случае это каталог верхнего уровня вашего дерева сборки

Сравните эти две переменные, чтобы определить, была ли запущена сборка из источника.

Ответ 4

Превращаю мой комментарий в ответ:

В случае, если кто-то сделал то, что я сделал, то началось с помещения всех файлов сборки в исходный каталог:

cd src
cmake .

cmake поместит кучу файлов сборки и файлов кэша (CMakeCache.txt, CMakeFiles, cmake_install.cmake и т.д.) в cmake_install.cmake src.

Чтобы перейти на сборку вне исходного кода, мне пришлось удалить все эти файлы. Тогда я мог бы сделать то, что @Angew рекомендовал в своем ответе:

mkdir -p src/build
cd src/build
cmake ..

Ответ 5

Прежде всего, вы не должны передавать имя сборки dir в вашем скрипте. строка с.. /Compile должна быть изменена.

Это потому, что это до пользователя, где компилировать.

Вместо этого используйте одну из предопределенных переменных: http://www.cmake.org/Wiki/CMake_Useful_Variables (ищите CMAKE_BINARY_DIR и CMAKE_CURRENT_BINARY_DIR)