Как используется CMake? [закрытый]
Как известно, трудно получить какую-либо полезную информацию о CMake в качестве новичка. До сих пор я видел несколько учебников о том, как настроить некоторые очень простой проект или другой. Однако ни один из них не объясняет причины ничего что показано в них, всегда оставляя много отверстий для заполнения.
Что означает вызов CMake на CMakeLists значит? Он должен быть вызван один раз на дерево сборки или что? Как использовать разные настройки для каждой сборки если все они используют одни и те же CMakeLists из одного источника?
Зачем каждому подкаталогу нужны свои собственные CMakeLists? Имеет ли смысл использовать CMake в CMakeLists в корне проекта? Если да, то в каких случаях? В чем разница между указанием того, как построить исполняемый файл или библиотеку из CMakeLists в их собственном подкаталоге, и тем, как это сделать в CMakeLists в корне всего источника?
Могу ли я сделать проект для Eclipse и другой для Visual Studio, просто изменив-G опция при вызове CMake? Это даже то, как он используется?
ни один из учебников, страниц документации или вопросов/ответов, которые я видел до сих пор, не дает никакого полезного представления о том, как использовать CMake. Примеры просто не доскональны. Независимо от того, какие учебники я читаю, я чувствую, что мне не хватает чего-то важного.
есть много вопросов, которые задают новички CMake, такие как я, которые не задают это явно, но которые делают очевидным тот факт, что, как newbs, у них нет идея, как бороться с CMake или что с этим делать, поэтому, хотя такой вопрос может показаться слишком широким, я думаю, что стоит оставить его и ответить на него.
2 ответов:
что такое CMake для?
согласно Википедии:
CMake is [...] программное обеспечение для управления процессом сборки программного обеспечения использование независимого от компилятора метода. Он предназначен для поддержки иерархии каталогов и приложения, которые зависят от нескольких библиотеки. Он используется в сочетании с собственными средами сборки например, make, Xcode от Apple и Microsoft Visual Studio.
с CMake, вы больше не необходимо поддерживать отдельные настройки, характерные для вашей среды компилятора/сборки. У вас есть один конфигурации, и это работает для много средах.
CMake может создать решение Microsoft Visual Studio, проект Eclipse или лабиринт Makefile из то же самое файлы, ничего не меняя в них.
учитывая кучу каталогов с кодом в них, CMake управляет всеми зависимостями, строит заказы и другие задачи, которые необходимо выполнить перед компиляцией проекта. На самом деле он ничего не компилирует. Чтобы использовать CMake, вы должны сказать это (используя файлы конфигурации, называемые CMakeLists.txt) какие исполняемые файлы вам нужно скомпилировать, на какие библиотеки они ссылаются, какие каталоги есть в вашем проекте и что находится внутри них, а также любые детали, такие как флаги или что-нибудь еще вам нужно (CMake довольно мощный).
если это правильно настроено, вы затем используете CMake для создания всех файлы, которые ваша" родная среда сборки " по выбору должна выполнять свою работу. В Linux, по умолчанию, это означает Makefiles. Поэтому, как только вы запустите CMake, он создаст кучу файлов для собственного использования плюс некоторые
Makefiles. все, что вам нужно сделать после этого, это ввести "make" в консоли из корневой папки каждый раз, когда вы закончите редактирование кода, и bam, скомпилированный и связанный исполняемый файл будет сделан.как работает CMake? Что он делает?
вот пример настройки проекта что я буду использовать во всем:
simple/ CMakeLists.txt src/ tutorial.cxx CMakeLists.txt lib/ TestLib.cxx TestLib.h CMakeLists.txt build/содержимое каждого файла показано и обсуждается позже.
CMake настраивает ваш проект в соответствии с root
CMakeLists.txtвашего проекта, и делает это в любом каталоге, который вы выполнилиcmakeв консоли. Выполнение этого из папки, которая не является корнем вашего проекта, создает то, что называется из-за источник build, что означает файлы, созданные во время компиляции (obj файлы, lib-файлы, исполняемые файлы, вы знаете) будут помещены в указанную папку, хранящуюся отдельно от фактического кода. Это помогает уменьшить беспорядок и предпочтительно по другим причинам, которые я не буду обсуждать.я не знаю, что произойдет, если вы выполните
cmakeна любой другой, кроме корняCMakeLists.txt.в этом примере, так как я хочу, чтобы все это размещалось внутри
build/папка, сначала я должен перейти туда, а затем передать CMake каталог, в котором кореньCMakeLists.txtпроживает.cd build cmake ..по умолчанию, это устанавливает все с помощью Makefiles, как я уже сказал. Вот как теперь должна выглядеть папка сборки:
simple/build/ CMakeCache.txt cmake_install.cmake Makefile CMakeFiles/ (...) src/ CMakeFiles/ (...) cmake_install.cmake Makefile lib/ CMakeFiles/ (...) cmake_install.cmake Makefileчто все эти файлы?единственное, о чем вам нужно беспокоиться, это Makefile и папки проекта.
обратите внимание на
src/иlib/папки. Они были созданы, потому чтоsimple/CMakeLists.txtуказывает на них с помощью командыadd_subdirectory(<folder>). Этот команда говорит CMake искать в указанной папке для другогоCMakeLists.txtфайл и выполните команду это скрипт, поэтому каждый подкаталог добавлен таким образом должны есть внутри. В этом проектеsimple/src/CMakeLists.txtописывает, как построить фактический исполняемый файл иsimple/lib/CMakeLists.txtописывает, как построить библиотеку. Каждая цель, что aCMakeLists.txtописание будет размещено по умолчанию в его подкаталоге в дереве сборки. Итак, после быстрогоmakeв консоли сделано из
build/некоторые файлы добавлены:simple/build/ (...) lib/ libTestLib.a (...) src/ Tutorial (...)проект построен, и исполняемый файл готов к выполнению. что вы делаете, если хотите, чтобы исполняемые файлы помещались в определенную папку?установите соответствующую переменную CMake или измените свойства конкретной цели. Подробнее о переменных CMake позже.
как мне сказать CMake, как построить мой проект?
вот содержание, объяснил, каждого файла в исходном каталоге:
simple/CMakeLists.txt:cmake_minimum_required(VERSION 2.6) project(Tutorial) # Add all subdirectories in this project add_subdirectory(lib) add_subdirectory(src)минимальная требуемая версия всегда должна быть установлен, по данным предупреждением, то CMake бросает, когда вы не. Используйте все, что вашей версии CMake это.
имя вашего проекта может быть использовано позже, и намеки на то, что вы можете управлять более чем одним проектом из тех же файлов CMake. Но я не буду углубляться в это.
Как упоминалось ранее,
add_subdirectory()добавляет папку в проект, что означает, что CMake ожидает, что у него будетCMakeLists.txtв этом, он будет работать, прежде чем продолжить. Кстати, если у вас есть определенная функция CMake, вы можете использовать ее из другихCMakeLists.txtв подкаталогах, но вы должны определить до вы используетеadd_subdirectory()или он не найдет его. CMake это умнее, о библиотеках, хотя, так что это, вероятно, единственный раз, когда вы столкнетесь с этой проблемой.
simple/lib/CMakeLists.txt:add_library(TestLib TestLib.cxx)чтобы сделать свой собственный библиотека, вы даете ей имя, а затем перечисляете все файлы, из которых она построена. Простой. Если ему нужен другой файл,
foo.cxx, чтобы быть скомпилированным, вы бы вместо этого написалиadd_library(TestLib TestLib.cxx foo.cxx). Это также работает для файлов в других каталогах, напримерadd_library(TestLib TestLib.cxx ${CMAKE_SOURCE_DIR}/foo.cxx). Подробнее о переменной CMAKE_SOURCE_DIR позже.еще одна вещь, которую вы можете сделать с этим, это указать, что вы хотите общую библиотеку. Пример:
add_library(TestLib SHARED TestLib.cxx). Не бойтесь, это то, где CMake начинает делать вашу жизнь проще. Так ли это общий или нет, теперь все, что вам нужно обработать, чтобы использовать библиотеку, созданную таким образом, - это имя, которое вы дали ей здесь. Имя этой библиотеки теперь TestLib, и вы можете ссылаться на него из в любом месте в проект. CMake найдет его.есть ли лучший способ перечислить зависимости?определенно да. Проверьте ниже для получения дополнительной информации этот.
simple/lib/TestLib.cxx:#include <stdio.h> void test() { printf("testing...\n"); }
simple/lib/TestLib.h:#ifndef TestLib #define TestLib void test(); #endif
simple/src/CMakeLists.txt:# Name the executable and all resources it depends on directly add_executable(Tutorial tutorial.cxx) # Link to needed libraries target_link_libraries(Tutorial TestLib) # Tell CMake where to look for the .h files target_include_directories(Tutorial PUBLIC ${CMAKE_SOURCE_DIR}/lib)команда
add_executable()работает точно так же, какadd_library(), за исключением, конечно, будет генерировать исполняемый файл. Этот исполняемый файл теперь можно ссылаться в качестве цели для таких вещей, какtarget_link_libraries(). Начиная с учебника.cxx использует код, найденный в библиотеке TestLib, вы указываете на это CMake, как показано на рисунке.аналогично .H-файлы #включено любыми источниками в
add_executable()что это не в том же каталоге, что и источник, нужно как-то добавить. Если бы не ,lib/TestLib.hне будет найден при компиляции учебника, так что весьlib/папка добавляется в каталоги include для поиска #includes. Вы также можете увидеть командуinclude_directories()который действует аналогичным образом, за исключением того, что вам не нужно указывать цель, поскольку он прямо устанавливает ее глобально для всех выполнимые программы. Еще раз, я объясню CMAKE_SOURCE_DIR позже.
simple/src/tutorial.cxx:#include <stdio.h> #include "TestLib.h" int main (int argc, char *argv[]) { test(); fprintf(stdout, "Main\n"); return 0; }обратите внимание, как "TestLib.файл H", включен. Нет необходимости включать полный путь; CMake заботится обо всем, что за кулисами благодаря
target_include_directories().Технически говоря, в простом исходном дереве, как это можно обойтись без
CMakeLists.txts подlib/иsrc/и просто добавляя что-то вродеadd_executable(Tutorial src/tutorial.cxx)доsimple/CMakeLists.txt. Это зависит от вас и вашего потребности проекта.что еще я должен знать, чтобы правильно использовать CMake?
(АКА темы, относящиеся к вашему пониманию)
поиск и использование пакетов:ответ на этот вопрос это объясняет лучше, чем я когда-либо мог.
объявление переменных и функций, использование потока управления и т. д.: проверить в этом уроке это объясняет основы того, что CMake должен предложение, а также хорошее введение в целом.
CMake переменные: есть много, так что ниже приведен ускоренный курс, чтобы вы на правильном пути. CMake wiki-это хорошее место, чтобы получить более подробную информацию о переменных и якобы другие вещи, а также.
вы можете редактировать некоторые переменные, не перестраивая дерево сборки. Используйте ccmake для этого (он редактирует
CMakeCache.txtfile). Не забывайconfigure, когда сделано с изменениями, а затемgenerate makefiles с обновленной конфигурацией.читать ранее упомянутом учебнике сведения об использовании переменных, но короче:
set(<variable name> value)для изменения или создания переменной.${<variable name>}использовать его.
CMAKE_SOURCE_DIR: корневой каталог источник. В предыдущем примере, это всегда равен/simpleCMAKE_BINARY_DIR: корневой каталог построение. В предыдущем примере это равноsimple/build/, но если вы запускалиcmake simple/из такой папки, какfoo/bar/etc/, тогда все ссылки наCMAKE_BINARY_DIRв этом дереве сборки станет/foo/bar/etc.CMAKE_CURRENT_SOURCE_DIR- каталог, в котором токCMakeLists.txtв. Это означает, что он изменяется во всем: печать этого изsimple/CMakeLists.txtдоходность/simple, и печать его изsimple/src/CMakeLists.txtдоходность/simple/src.CMAKE_CURRENT_BINARY_DIR: вы поняли идею. Этот путь будет зависеть не только от папка, в которой находится сборка, но также и на текущем скрипта.почему это важно? Исходные файлы, очевидно, не будет в дереве сборки. Если вы попробуете что-то вроде
target_include_directories(Tutorial PUBLIC ../lib)в предыдущем примере этот путь будет относительно дерева сборки, то есть это будет похоже на запись${CMAKE_BINARY_DIR}/lib, который будет смотреть внутрьsimple/build/lib/. Нет .H файлы там; в лучшем случае вы найдетеlibTestLib.a. Ты хочешь${CMAKE_SOURCE_DIR}/libвместо.
CMAKE_CXX_FLAGS: флаги для передачи компилятору, в данном случае компилятору C++. Также стоит отметитьCMAKE_CXX_FLAGS_DEBUG, который будет использоваться, еслиCMAKE_BUILD_TYPEустановлен для отладки. Есть еще такие; проверьте Вики CMake.CMAKE_RUNTIME_OUTPUT_DIRECTORY: скажите CMake, где разместить все исполняемые файлы при сборке. Это глобальная настройка. Вы можете, например, установить его вbin/и там все аккуратно разложено.EXECUTABLE_OUTPUT_PATHпохож, но устарел, если вы наткнетесь на него.CMAKE_LIBRARY_OUTPUT_DIRECTORY: аналогично, глобальная настройка, чтобы сказать CMake, куда поместить все файлы библиотеки.целевые свойства: вы можете установить свойства, которые влияют только на одну цель, будь то исполняемый файл или библиотека (или архив... вы поняли идею). вот хороший пример о том, как его использовать (с
set_target_properties().есть ли простой способ добавить источники к цели автоматически? использовать GLOB чтобы перечислить все в данном каталоге под той же переменной. Пример синтаксиса -
FILE(GLOB <variable name> <directory>/*.cxx).вы можете указать различные типы сборки? да, хотя я не уверен, как это работает или ограничивает. Вероятно, это требует некоторого if / then'Ning, но CMake предлагает некоторую базовую поддержку без настройки чего-либо, например, по умолчанию для
CMAKE_CXX_FLAGS_DEBUG, например. Вы можете либо установить свой тип сборки от внутри черезset(CMAKE_BUILD_TYPE <type>)или вызывая CMake из консоли с соответствующими флагами, напримерcmake -DCMAKE_BUILD_TYPE=Debug.есть хорошие примеры проектов, которые используют CMake? Википедия имеет список проектов с открытым исходным кодом, которые используют CMake, если вы хотите посмотреть на это. Онлайн учебники были не что иное, как разочарование для меня до сих пор в этом отношении, однако этот вопрос переполнения стека имеет довольно прохладный и простой для понимания настройки CMake. Это стоит посмотреть.
использование переменных из CMake в вашем коде: вот быстрый и грязный пример (взято из какой-то другой учебник):
simple/CMakeLists.txt:project (Tutorial) # Setting variables set (Tutorial_VERSION_MAJOR 1) set (Tutorial_VERSION_MINOR 1) # Configure_file(<input> <output>) # Copies a file <input> to file <output> and substitutes variable values referenced in the file content. # So you can pass some CMake variables to the source code (in this case version numbers) configure_file ( "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_SOURCE_DIR}/src/TutorialConfig.h" )
simple/TutorialConfig.h.in:// Configured options and settings #define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@полученный файл, созданный с помощью CMake, например,
simple/src/TutorialConfig.h:// Configured options and settings #define Tutorial_VERSION_MAJOR 1 #define Tutorial_VERSION_MINOR 1с умным использованием этих Вы можете делать классные вещи, как отключение библиотеки и тому подобное. Я рекомендую взглянуть на что учебник поскольку есть некоторые немного более продвинутые вещи, которые рано или поздно будут очень полезны в более крупных проектах.
для всего остального переполнение стека переполнено конкретными вопросами и краткими ответами, что отлично подходит для всех, кроме непосвященных.
вот некоторые (трудно найти, как и все о CMake) видео:
- http://ftp.heanet.ie/mirrors/fosdem-video/2008/maintracks/FOSDEM2008-cmake.ogg
- http://www.kitware.com/media/protrainingwebinars.php#introcmake
надеюсь, это поможет (и позор CMake и его плохая документация,#^&! ):)
Comments