介绍#
展示一个hello world示例,它使用不同的文件夹来存储源文件和头文件。
本教程中的文件包括:
B-hello-headers$ tree
.
├── CMakeLists.txt
├── include
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
-
[CMakeLists.txt] - 包含你希望运行的 CMake 命令。
# Set the minimum version of CMake that can be used # To find the cmake version run # $ cmake --version cmake_minimum_required(VERSION 3.5) # Set the project name project (hello_headers) # Create a sources variable with a link to all cpp files to compile set(SOURCES src/Hello.cpp src/main.cpp ) # Add an executable with the above sources add_executable(hello_headers ${SOURCES}) # Set the directories that should be included in the build command for this target # when running g++ these will be included as -I/directory/path/ target_include_directories(hello_headers PRIVATE ${PROJECT_SOURCE_DIR}/include )
-
[include/Hello.h] - 要包含的标题文件。
#ifndef __HELLO_H__ #define __HELLO_H__ class Hello { public: void print(); }; #endif
-
[src/Hello.cpp] - 要编译的源文件。
#include <iostream> #include "Hello.h" void Hello::print() { std::cout << "Hello Headers!" << std::endl; }
-
[src/main.cpp] - 主源文件。
#include "Hello.h" int main(int argc, char *argv[]) { Hello hi; hi.print(); return 0; }
概念#
目录路径#
CMake 语法指定了许多变量,这些变量可用于帮助在项目或源代码树中找到有用的目录。其中一些包括:
变量 | 信息 |
---|---|
CMAKE_SOURCE_DIR | 根源目录 |
CMAKE_CURRENT_SOURCE_DIR | 如果使用子项目和目录,则为当前源目录。 |
PROJECT_SOURCE_DIR | 当前 cmake 项目的源目录。 |
CMAKE_BINARY_DIR | 根二进制文件生成目录。这是运行cmake命令的目录。 |
CMAKE_CURRENT_BINARY_DIR | 你当前所处的生成目录。 |
PROJECT_BINARY_DIR | 当前项目的生成目录。 |
源文件变量#
创建包含源码文件的变量可使你更清楚地了解这些文件,并轻松将其添加到多个命令中,例如,add_executable()功能。
# Create a sources variable with a link to all cpp files to compile
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
file(GLOB SOURCES "src/*.cpp")
头文件目录#
当你有不同的头文件目录时,可以使用target_include_directories()
函数让编译器知道它们编译此目标时,会将这些目录添加到带有-i
标志的编译指令中,例如-i/directory/path
target_include_directories(target
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
PRIVATE标识符指定include的范围,这对库很重要,这些内容将在下一个示例中进行说明。有关该功能的更多详细信息,请访问这里
构建示例#
标准输出#
构建示例的标准输出内容如下所示:
$ mkdir build
$ cd build
$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build
$ make
Scanning dependencies of target hello_headers
[ 50%] Building CXX object CMakeFiles/hello_headers.dir/src/Hello.cpp.o
[100%] Building CXX object CMakeFiles/hello_headers.dir/src/main.cpp.o
Linking CXX executable hello_headers
[100%] Built target hello_headers
$ ./hello_headers
Hello Headers!
详细输出#
在前面的示例中,当运行make命令时,输出仅显示构建的状态。要查看用于调试目的的完整输出,可以在运行make时添加VERBOSE=1标志。
VERBOSE 输出如下所示。可以看到,include目录已经被添加到了编译命令中。
$ make clean
$ make VERBOSE=1
/usr/bin/cmake -H/home/matrim/workspace/cmake-examples/01-basic/hello_headers -B/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
make -f CMakeFiles/hello_headers.dir/build.make CMakeFiles/hello_headers.dir/depend
make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
cd /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/matrim/workspace/cmake-examples/01-basic/hello_headers /home/matrim/workspace/cmake-examples/01-basic/hello_headers /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles/hello_headers.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
make -f CMakeFiles/hello_headers.dir/build.make CMakeFiles/hello_headers.dir/build
make[2]: Entering directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 1
[ 50%] Building CXX object CMakeFiles/hello_headers.dir/src/Hello.cpp.o
/usr/bin/c++ -I/home/matrim/workspace/cmake-examples/01-basic/hello_headers/include -o CMakeFiles/hello_headers.dir/src/Hello.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/hello_headers/src/Hello.cpp
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 2
[100%] Building CXX object CMakeFiles/hello_headers.dir/src/main.cpp.o
/usr/bin/c++ -I/home/matrim/workspace/cmake-examples/01-basic/hello_headers/include -o CMakeFiles/hello_headers.dir/src/main.cpp.o -c /home/matrim/workspace/cmake-examples/01-basic/hello_headers/src/main.cpp
Linking CXX executable hello_headers
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_headers.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/hello_headers.dir/src/Hello.cpp.o CMakeFiles/hello_headers.dir/src/main.cpp.o -o hello_headers -rdynamic
make[2]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
/usr/bin/cmake -E cmake_progress_report /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 1 2
[100%] Built target hello_headers
make[1]: Leaving directory `/home/matrim/workspace/cmake-examples/01-basic/hello_headers/build'
/usr/bin/cmake -E cmake_progress_start /home/matrim/workspace/cmake-examples/01-basic/hello_headers/build/CMakeFiles 0