一、项目构成
目录
.
├── CMakeLists.txt
├── include
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
include
//Hello.h
#ifndef __HELLO_H__
#define __HELLO_H__
class Hello
{
public:
void print();
};
#endif
src
//1.Hello.cpp
#include <iostream>
#include "Hello.h"
void Hello::print()
{
std::cout << "Hello Headers!" << std::endl;
}
//2.main.cpp
#include "Hello.h"
int main(int argc, char *argv[])
{
Hello hi;
hi.print();
return 0;
}
CMakeLists.txt
#最低版本需求
cmake_minimum_required(VERSION 3.2)
#设置项目名称
project(hello_headers)
#创建一个名为SOURCES的变量,来包含所有的cpp文件用以编译
set(SOURCES
src/Hello.cpp
src/main.cpp)
#添加具有上述源的可执行文件
add_executable(hello_headers ${SOURCES})
#设置在运行g++时应包含在此目标的build命令中的目录,这些目录将作为-I/directory/path包含/
target_include_directories(hello_headers
PRIVATE
${PROJECT_SOURCE_DIR}/include)
二、项目分析
介绍
显示了一个hello world示例,该示例对源文件和包含文件使用不同的文件夹。
本教程中的文件包括:
.
├── CMakeLists.txt
├── include
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
- CMakeLists.txt - 包含要运行的CMake命令.
- include/Hello.h- 要包含的头文件.
- src/Hello.cpp - 要编译的源文件.
- src/main.cpp - 包含main的源文件.
概念
Directory Paths
CMake语法指定了许多可用于帮助在项目或源代码树中查找有用的目录(官方地址)。其中包括:
变量名称 | 含义 |
---|---|
CMAKE_SOURCE_DIR | 源目录的根目录 |
CMAKE_CURRENT_SOURCE_DIR | 当前源目录(如果使用子项目和目录) |
PROJECT_SOURCE_DIR | 当前cmake项目的源目录 |
CMAKE_BINARY_DIR | 根二进制/生成目录(运行cmake命令的目录) |
CMAKE_CURRENT_BINARY_DIR | 当前所在的生成目录 |
PROJECT_BINARY_DIR | 当前项目的生成目录 |
Source Files Variable
用于创建包含源文件的变量,并轻松地将它们添加到多个命令中,例如:
#创建一个源变量,其中包含指向要编译的所有cpp文件的链接
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(${PROJECT_NAME} ${SOURCES})
注意:在SOURCES变量中设置特定文件名的另一种方法是使用GLOB命令和使用通配符模式匹配查找文件。如:
file(GLOB SOURCES “src/*.cpp”)
对于现代CMake,不建议对源使用变量。相反,通常在add_xxx函数中直接声明源。这对于glob命令尤其重要,如果添加新的源文件,glob命令可能不会始终显示正确的结果。
Including Directories
当项目中有不同的include文件夹时,可以使用target_include_directories() 函数。编译此目标时,这将使用-I标志将这些目录添加到编译器中,例如I/directory/path
。target_include_directories()使用示例:
target_include_directories(target
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
PRIVATE标识符指定包含的范围。这对于库很重要,将在下一个示例中解释。有关该功能的更多详细信息,请参阅:https://cmake.org/cmake/help/v3.0/command/target_include_directories.html。
三、项目构建
Standard Output(标准输出)
构建此示例的标准输出如下所示:
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers> mkdir build
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers> cd build
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build> cmake -G "MinGW Makefiles" ..
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: D:/Qt/Qt5.12.2/Tools/mingw730_32/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/Qt/Qt5.12.2/Tools/mingw730_32/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build> mingw32-make
[ 33%] Building CXX object CMakeFiles/hello_headers.dir/src/Hello.cpp.obj
[ 66%] Building CXX object CMakeFiles/hello_headers.dir/src/main.cpp.obj
[100%] Linking CXX executable hello_headers.exe
[100%] Built target hello_headers
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build> ./hello_headers
Hello Headers!
Verbose Output(详细输出)
在前面的示例中,当运行mingw32-make命令时,输出仅显示生成的状态。要查看完整输出以进行调试,可以在运行mingw32-make时添加 VERBOSE=1标识。详细的输出如下所示,并且对输出的检查表明,将添加目录添加到C++编译器逗号中。
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build> mingw32-make clean
(base) PS D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build> mingw32-make VERBOSE=1
"C:\Program Files\CMake\bin\cmake.exe" -SD:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers -BD:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build --check-build-system CMakeFiles\Makefile.cmake 0
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build\CMakeFiles D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build\\CMakeFiles\progress.marksD:/Qt/Qt5.12.2/Tools/mingw730_32/bin/mingw32-make -f CMakeFiles\Makefile2 all
mingw32-make[1]: Entering directory 'D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build'
D:/Qt/Qt5.12.2/Tools/mingw730_32/bin/mingw32-make -f CMakeFiles\hello_headers.dir\build.make CMakeFiles/hello_headers.dir/depend
mingw32-make[2]: Entering directory 'D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build'
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_depends "MinGW Makefiles" D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build\CMakeFiles\hello_headers.dir\DependInfo.cmake --color=
mingw32-make[2]: Leaving directory 'D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build'
D:/Qt/Qt5.12.2/Tools/mingw730_32/bin/mingw32-make -f CMakeFiles\hello_headers.dir\build.make CMakeFiles/hello_headers.dir/build
mingw32-make[2]: Entering directory 'D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build'
[ 33%] Building CXX object CMakeFiles/hello_headers.dir/src/Hello.cpp.obj
D:\Qt\Qt5.12.2\Tools\mingw730_32\bin\g++.exe @CMakeFiles/hello_headers.dir/includes_CXX.rsp -MD -MT CMakeFiles/hello_headers.dir/src/Hello.cpp.obj -MF CMakeFiles\hello_headers.dir\src\Hello.cpp.obj.d -o CMakeFiles\hello_headers.dir\src\Hello.cpp.obj -c D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\src\Hello.cpp
[ 66%] Building CXX object CMakeFiles/hello_headers.dir/src/main.cpp.obj
D:\Qt\Qt5.12.2\Tools\mingw730_32\bin\g++.exe @CMakeFiles/hello_headers.dir/includes_CXX.rsp -MD -MT CMakeFiles/hello_headers.dir/src/main.cpp.obj -MF CMakeFiles\hello_headers.dir\src\main.cpp.obj.d -o CMakeFiles\hello_headers.dir\src\main.cpp.obj -c D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\src\main.cpp
[100%] Linking CXX executable hello_headers.exe
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\hello_headers.dir\link.txt --verbose=1
"C:\Program Files\CMake\bin\cmake.exe" -E rm -f CMakeFiles\hello_headers.dir/objects.a
D:\Qt\Qt5.12.2\Tools\mingw730_32\bin\ar.exe qc CMakeFiles\hello_headers.dir/objects.a @CMakeFiles\hello_headers.dir\objects1.rsp
D:\Qt\Qt5.12.2\Tools\mingw730_32\bin\g++.exe -Wl,--whole-archive CMakeFiles\hello_headers.dir/objects.a -Wl,--no-whole-archive -o hello_headers.exe -Wl,--out-implib,libhello_headers.dll.a -Wl,--major-image-version,0,--minor-image-version,0 @CMakeFiles\hello_headers.dir\linklibs.rsp
mingw32-make[2]: Leaving directory 'D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build'
[100%] Built target hello_headers
mingw32-make[1]: Leaving directory 'D:/Solutions/cmakeStudy/cmake-examples/01-basic/B-hello-headers/build'
"C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start D:\Solutions\cmakeStudy\cmake-examples\01-basic\B-hello-headers\build\CMakeFiles 0