CMake는 어떻게 사용됩니까? [닫은]
초보자로서 CMake에 대한 유용한 정보를 얻는 것은 악명이 높습니다. 지금까지 매우 기본적인 프로젝트 나 다른 프로젝트를 설정하는 방법에 대한 몇 가지 자습서를 보았습니다. 그러나 이것들 중 어느 것도 그 안에 표시된 모든 것의 추론을 설명하지 않으며 항상 많은 구멍을 채울 수 있습니다.
CMakeLists에서 CMake를 호출하는 것은 무엇을 의미 합니까? 빌드 트리 당 한 번 호출해야합니까? 모두 동일한 소스의 동일한 CMakeLists.txt 파일을 사용하는 경우 각 빌드에 대해 다른 설정을 사용하려면 어떻게해야합니까? 각 하위 디렉토리에 자체 CMakeLists 파일이 필요한 이유는 무엇입니까? 프로젝트의 루트가 아닌 CMakeLists.txt에서 CMake를 사용하는 것이 합리적입니까? 그렇다면 어떤 경우에? 자체 하위 디렉터리의 CMakeLists 파일에서 실행 파일 또는 라이브러리를 빌드하는 방법을 지정하는 방법과 모든 소스의 루트에있는 CMakeLists 파일에서 수행하는 방법의 차이점은 무엇입니까? -G
CMake를 호출 할 때 옵션을 변경하여 Eclipse 용 프로젝트와 Visual Studio 용 프로젝트를 만들 수 있나요 ? 그것이 어떻게 사용 되는가?
지금까지 본 튜토리얼, 문서 페이지 또는 질문 / 답변 중 어느 것도 CMake 사용 방법을 이해하는 데 유용한 통찰력을 제공하지 않습니다. 예제는 완전하지 않습니다. 어떤 튜토리얼을 읽어도 중요한 것을 놓치고있는 것 같습니다.
저와 같은 CMake 초보자는 이것을 명시 적으로 묻지 않는 많은 질문이 있지만, 이는 초보자로서 CMake를 어떻게 처리해야하는지 또는 무엇을 만들어야하는지 전혀 모른다는 사실을 분명히합니다.
CMake는 무엇입니까?
Wikipedia에 따르면 :
CMake는 컴파일러 독립적 인 방법을 사용하여 소프트웨어의 빌드 프로세스를 관리하는 [...] 소프트웨어입니다. 여러 라이브러리에 의존하는 디렉토리 계층 구조 및 애플리케이션을 지원하도록 설계되었습니다. make, Apple의 Xcode 및 Microsoft Visual Studio와 같은 기본 빌드 환경과 함께 사용됩니다.
CMake를 사용하면 더 이상 컴파일러 / 빌드 환경에 특정한 별도의 설정을 유지할 필요가 없습니다. 당신은 하나 개의 구성을하고, 그 작동 많은 환경.
CMake는 같은 파일에서 아무것도 변경하지 않고 동일한 파일 에서 Microsoft Visual Studio 솔루션, Eclipse 프로젝트 또는 Makefile 미로를 생성 할 수 있습니다.
코드가 포함 된 여러 디렉터리가있는 경우 CMake는 프로젝트를 컴파일하기 전에 수행해야하는 모든 종속성, 빌드 순서 및 기타 작업을 관리합니다. 실제로 아무것도 컴파일하지 않습니다. CMake를 사용하려면 CMakeLists.txt라는 구성 파일을 사용하여 컴파일해야하는 실행 파일, 링크 된 라이브러리, 프로젝트에있는 디렉터리 및 내부에있는 내용, 플래그와 같은 세부 정보를 알려야합니다. 또는 필요한 다른 것 (CMake는 매우 강력합니다).
이것이 올바르게 설정된 경우 CMake를 사용하여 선택한 "기본 빌드 환경"이 작업을 수행하는 데 필요한 모든 파일을 만듭니다. Linux에서는 기본적으로 Makefile을 의미합니다. 따라서 CMake를 실행하면 자체적으로 사용할 파일과 Makefile
. 그 후에해야 할 일은 코드 편집을 마칠 때마다 루트 폴더에서 콘솔에 "make"를 입력하는 것입니다. 그러면 컴파일되고 연결된 실행 파일이 만들어집니다.
CMake는 어떻게 작동합니까? 그것은 무엇을합니까?
다음은 전체적으로 사용할 프로젝트 설정의 예입니다.
simple/
CMakeLists.txt
src/
tutorial.cxx
CMakeLists.txt
lib/
TestLib.cxx
TestLib.h
CMakeLists.txt
build/
각 파일의 내용은 나중에 표시되고 설명됩니다.
CMake는 프로젝트의 루트 CMakeLists.txt
에 따라 프로젝트 cmake
를 설정하고 콘솔에서 실행 한 모든 디렉터리 에서 수행 합니다. 프로젝트의 루트가 아닌 폴더에서이 작업을 수행하면 소스 외부 빌드 라고하는 것이 생성됩니다. 즉, 컴파일 중에 생성 된 파일 (obj 파일, lib 파일, 실행 파일)이 해당 폴더에 배치됩니다. , 실제 코드와 별도로 유지됩니다. 혼란을 줄이는 데 도움이되며 다른 이유로도 선호됩니다.
cmake
루트 이외의 다른 곳에서 실행하면 어떻게되는지 모르겠습니다 CMakeLists.txt
.
이 예제에서는 모든 build/
파일을 폴더 안에 배치하기를 원하므로 먼저 거기로 이동 한 다음 루트가있는 디렉터리를 CMake에 전달해야 CMakeLists.txt
합니다.
cd build
cmake ..
기본적으로 이것은 내가 말했듯이 Makefile을 사용하여 모든 것을 설정합니다. 다음은 빌드 폴더의 모습입니다.
simple/build/
CMakeCache.txt
cmake_install.cmake
Makefile
CMakeFiles/
(...)
src/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
lib/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
이 모든 파일은 무엇입니까? 걱정해야 할 것은 Makefile과 프로젝트 폴더뿐입니다 .
Notice the src/
and lib/
folders. These have been created because simple/CMakeLists.txt
points to them using the command add_subdirectory(<folder>)
. This command tells CMake to look in said folder for another CMakeLists.txt
file and execute that script, so every subdirectory added this way must have a CMakeLists.txt
file within. In this project, simple/src/CMakeLists.txt
describes how to build the actual executable and simple/lib/CMakeLists.txt
describes how to build the library. Every target that a CMakeLists.txt
describes will be placed by default in its subdirectory within the build tree. So, after a quick
make
in console done from build/
, some files are added:
simple/build/
(...)
lib/
libTestLib.a
(...)
src/
Tutorial
(...)
The project is built, and the executable is ready to be executed. What do you do if you want the executables put in a specific folder? Set the appropriate CMake variable, or change the properties of a specific target. More on CMake variables later.
How do I tell CMake how to build my project?
Here are the contents, explained, of each file in the source directory:
simple/CMakeLists.txt
:
cmake_minimum_required(VERSION 2.6)
project(Tutorial)
# Add all subdirectories in this project
add_subdirectory(lib)
add_subdirectory(src)
The minimum required version should always be set, according to the warning CMake throws when you don't. Use whatever your version of CMake is.
The name of your project can be used later on, and hints towards the fact you can manage more than one project from the same CMake files. I won't delve into that, though.
As mentioned before, add_subdirectory()
adds a folder to the project, which means CMake expects it to have a CMakeLists.txt
within, which it will then run before continuing. By the way, if you happen to have a CMake function defined you can use it from other CMakeLists.txt
s in subdirectories, but you have to define it before you use add_subdirectory()
or it won't find it. CMake is smarter about libraries, though, so this is likely the only time you will run into this kind of problem.
simple/lib/CMakeLists.txt
:
add_library(TestLib TestLib.cxx)
To make your very own library, you give it a name and then list all the files it's built from. Straightforward. If it needed another file, foo.cxx
, to be compiled, you would instead write add_library(TestLib TestLib.cxx foo.cxx)
. This also works for files in other directories, for instance add_library(TestLib TestLib.cxx ${CMAKE_SOURCE_DIR}/foo.cxx)
. More on the CMAKE_SOURCE_DIR variable later.
Another thing you can do with this is specify that you want a shared library. The example: add_library(TestLib SHARED TestLib.cxx)
. Fear not, this is where CMake begins to make your life easier. Whether it's shared or not, now all you need to handle to use a library created in this way is the name you gave it here. The name of this library is now TestLib, and you can reference it from anywhere in the project. CMake will find it.
Is there a better way to list dependencies? Definitely yes. Check down below for more on this.
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)
The command add_executable()
works exactly the same as add_library()
, except, of course, it will generate an executable instead. This executable can now be referenced as a target for things like target_link_libraries()
. Since tutorial.cxx uses code found in the TestLib library, you point this out to CMake as shown.
Similarly, any .h files #included by any sources in add_executable()
that are not in the same directory as the source have to be added somehow. If not for the target_include_directories()
command, lib/TestLib.h
would not be found when compiling Tutorial, so the entire lib/
folder is added to the include directories to be searched for #includes. You might also see the command include_directories()
which acts in a similar fashion, except that it does not need you to specify a target since it outright sets it globally, for all executables. Once again, I'll explain CMAKE_SOURCE_DIR later.
simple/src/tutorial.cxx
:
#include <stdio.h>
#include "TestLib.h"
int main (int argc, char *argv[])
{
test();
fprintf(stdout, "Main\n");
return 0;
}
Notice how the "TestLib.h" file is included. No need to include the full path: CMake takes care of all that behind the scenes thanks to target_include_directories()
.
Technically speaking, in a simple source tree like this you can do without the CMakeLists.txt
s under lib/
and src/
and just adding something like add_executable(Tutorial src/tutorial.cxx)
to simple/CMakeLists.txt
. It's up to you and your project's needs.
What else should I know to properly use CMake?
(AKA topics relevant to your understanding)
Finding and using packages: The answer to this question explains it better than I ever could.
Declaring variables and functions, using control flow, etc.: check out this tutorial that explains the basics of what CMake has to offer, as well as being a good introduction in general.
CMake variables: there are plenty, so what follows is a crash course to get you on the right track. The CMake wiki is a good place to get more in-depth information on variables and ostensibly other things as well.
You may want to edit some variables without rebuilding the build tree. Use ccmake for this (it edits the CMakeCache.txt
file). Remember to c
onfigure when done with the changes and then g
enerate makefiles with the updated configuration.
Read the previously referenced tutorial to learn about using variables, but long story short: set(<variable name> value)
to change or create a variable. ${<variable name>}
to use it.
CMAKE_SOURCE_DIR
: The root directory of source. In the previous example, this is always equal to/simple
CMAKE_BINARY_DIR
: The root directory of the build. In the previous example, this is equals tosimple/build/
, but if you rancmake simple/
from a folder such asfoo/bar/etc/
, then all references toCMAKE_BINARY_DIR
in that build tree would become/foo/bar/etc
.CMAKE_CURRENT_SOURCE_DIR
: The directory in which the currentCMakeLists.txt
is in. This means it changes throughout: printing this fromsimple/CMakeLists.txt
yields/simple
, and printing it fromsimple/src/CMakeLists.txt
yields/simple/src
.CMAKE_CURRENT_BINARY_DIR
: You get the idea. This path would depend not only on the folder the build is in, but also on the currentCMakeLists.txt
script's location.
Why are these important? Source files will obviously not be in the build tree. If you try something like target_include_directories(Tutorial PUBLIC ../lib)
in the previous example, that path will be relative to the build tree, that is to say it will be like writing ${CMAKE_BINARY_DIR}/lib
, which will look inside simple/build/lib/
. There are no .h files in there; at most you will find libTestLib.a
. You want ${CMAKE_SOURCE_DIR}/lib
instead.
CMAKE_CXX_FLAGS
: Flags to pass on to the compiler, in this case the C++ compiler. Also worth noting isCMAKE_CXX_FLAGS_DEBUG
which will be used instead ifCMAKE_BUILD_TYPE
is set to DEBUG. There are more like these; check out the CMake wiki.CMAKE_RUNTIME_OUTPUT_DIRECTORY
: Tell CMake where to put all executables when built. This is a global setting. You can, for instance, set it tobin/
and have everything neatly placed there.EXECUTABLE_OUTPUT_PATH
is similar, but deprecated, in case you stumble upon it.CMAKE_LIBRARY_OUTPUT_DIRECTORY
: Likewise, a global setting to tell CMake where to put all library files.
Target properties: you can set properties that affect only one target, be it an executable or a library (or an archive... you get the idea). Here is a good example of how to use it (with set_target_properties()
.
Is there an easy way to add sources to a target automatically? Use GLOB to list everything in a given directory under the same variable. Example syntax is FILE(GLOB <variable name> <directory>/*.cxx)
.
Can you specify different build types? Yes, though I'm not sure about how this works or the limitations of this. It probably requires some if/then'ning, but CMake does offer some basic support without configuring anything, like defaults for the CMAKE_CXX_FLAGS_DEBUG
, for instance. You can either set your build type from within the CMakeLists.txt
file via set(CMAKE_BUILD_TYPE <type>)
or by calling CMake from console with the appropriate flags, for example cmake -DCMAKE_BUILD_TYPE=Debug
.
Any good examples of projects that use CMake? Wikipedia has a list of open-source projects that use CMake, if you want to look into that. Online tutorials have been nothing but a letdown to me so far in this regard, however this Stack Overflow question has a pretty cool and easy-to-understand CMake setup. It's worth a look.
Using variables from CMake in your code: Here's a quick and dirty example (adapted from some other tutorial):
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@
The resulting file generated by CMake, simple/src/TutorialConfig.h
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR 1
#define Tutorial_VERSION_MINOR 1
With clever use of these you can do cool things like turning off a library and such. I do recommend taking a look at that tutorial as there are some slightly more advanced things that are bound to be very useful on larger projects, sooner or later.
For everything else, Stack Overflow is brimming with specific questions and concise answers, which is great for everyone except the uninitiated.
Here are some (hard-to-find, as everything about CMake) videos:
- http://ftp.heanet.ie/mirrors/fosdem-video/2008/maintracks/FOSDEM2008-cmake.ogg
- http://www.kitware.com/media/protrainingwebinars.php#introcmake
Hopefully this helps (and shame to CMake and its poor documentation, #^&! ) :)
참고URL : https://stackoverflow.com/questions/26007566/how-is-cmake-used
'development' 카테고리의 다른 글
ByteBuffer의 flip 메소드의 목적은 무엇입니까? (0) | 2020.09.25 |
---|---|
jQuery로 div의 가시 높이 가져 오기 (0) | 2020.09.25 |
React 컴포넌트에서 this.setState를 여러 번 사용하면 어떻게 되나요? (0) | 2020.09.25 |
Webpack 대 webpack-dev-server 대 webpack-dev-middleware 대 webpack-hot-middleware 대 etc (0) | 2020.09.25 |
C #에서 목록을 사용할 수없는 이유 (0) | 2020.09.25 |