项目链接:
cmake-examples
目标:
CMakeList.txt
# 设置最小的CMake版本
# 可以通过命令查询环境中 cmake 的版本 cmake --version
cmake_minimum_required(VERSION 3.0)
# 设置项目名称
project(hello_cmake)
# 添加一个可执行程序
add_executable(hello_cmake "main.cpp")
编译
cmake ..
目标:
文件目录:
.
├── CMakeLists.txt
├── include
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
在main.cpp 中引用 Hello.h
如果不在CMake中导入头文件,就会报错提示找不到 Hello.h 的头文件
CMake 地址相关的宏
Variable | Info |
---|---|
CMAKE_SOURCE_DIR | The root source directory |
CMAKE_CURRENT_SOURCE_DIR | The current source directory if using sub-projects and directories. |
PROJECT_SOURCE_DIR | The source directory of the current cmake project. |
CMAKE_BINARY_DIR | The root binary / build directory. This is the directory where you ran the cmake command. |
CMAKE_CURRENT_BINARY_DIR | The build directory you are currently in. |
PROJECT_BINARY_DIR | The build directory for the current project. |
假如项目的路径是: D:\workSpace\cmake-examples\01-basic\B-hello-headers
Variable | Info |
---|---|
CMAKE_SOURCE_DIR | D:/workSpace/cmake-examples/01-basic/B-hello-headers |
CMAKE_CURRENT_SOURCE_DIR | D:/workSpace/cmake-examples/01-basic/B-hello-headers |
PROJECT_SOURCE_DIR | D:/workSpace/cmake-examples/01-basic/B-hello-headers |
CMAKE_BINARY_DIR | D:/workSpace/cmake-examples/01-basic/B-hello-headers/build |
CMAKE_CURRENT_BINARY_DIR | D:/workSpace/cmake-examples/01-basic/B-hello-headers/build |
PROJECT_BINARY_DIR | D:/workSpace/cmake-examples/01-basic/B-hello-headers/build |
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(HelloHeaders)
message("This is a message with a pipe symbol: ||")
message(====================================================================)
message("|CMAKE_SOURCE_DIR |" ${CMAKE_SOURCE_DIR} "|")
message("|CMAKE_CURRENT_SOURCE_DIR |" ${CMAKE_CURRENT_SOURCE_DIR} "|")
message("|PROJECT_SOURCE_DIR |" ${PROJECT_SOURCE_DIR} "|")
message("|CMAKE_BINARY_DIR |" ${CMAKE_BINARY_DIR} "|")
message("|CMAKE_CURRENT_BINARY_DIR |" ${CMAKE_CURRENT_BINARY_DIR} "|")
message("|PROJECT_BINARY_DIR |" ${PROJECT_BINARY_DIR} "|")
message(====================================================================)
set(SOURCE
src/Hello.cpp
src/main.cpp
)
add_executable(HelloHeaders ${SOURCE})
# 添加头文件
# PRIVATE 表示只为当前的目标添加头文件目录,不会影响其他目标
target_include_directories(HelloHeaders
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
目标: 使用CMake打包静态库。在windows 下,将某一个模块,打包成静态库。将会生成:
在其他代码里就可以导入头文件,链接.lib文件来调用模块中的功能。
文件目录:
├── CMakeLists.txt
├── include
│ └── static
│ └── Hello.h
└── src
├── Hello.cpp
└── main.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(hello_library)
############################################################
# 创建静态库
############################################################
add_library(hello_library_lib STATIC src/Hello.cpp)
# 导入include 头文件目录
target_include_directories(hello_library_lib
PUBLIC
${PROJECT_SOURCE_DIR}/include)
############################################################
# 创建可执行文件
############################################################
add_executable(hello_library_exe
src/main.cpp)
# 链接静态库
target_link_libraries(hello_library_exe
PRIVATE
hello_library_lib)
添加一个静态库
add_library(hello_library_lib STATIC src/Hello.cpp)
导入头文件
# 导入include 头文件目录
target_include_directories(hello_library_lib
PUBLIC
${PROJECT_SOURCE_DIR}/include)
在这里使用了 PUBLIC 的作用域,这将使得include目录在如下场景被使用:
作用域的含义:
TIPS:
#include "static/Hello.h"
链接库
add_executable(hello_binary
src/main.cpp
)
target_link_libraries( hello_binary
PRIVATE
hello_library
)
动态库,在Windows下会生成:
在CMake上只有一点不同就是:
# 生成动态库
add_library(hello_libary_dll
SHARED
src/Hello.cpp)
在到处动态库时,在windows平台下,需要在要到处的类前面加上一个宏 __declspec, 如果不加,将不会生成 .lib文件,在windows平台下会导入出错的。
#ifndef __HELLO_H__
#define __HELLO_H__
class __declspec( dllexport ) Hello
{
public:
void print();
};
#endif
目的: 在编译后,我们希望我们编译的目标, 头文件或者配置文件等移动到相关的目录下,这时候在CMake中就有了 Installing 的概念。基础的安装位置是由变量 **CMAKE_INSTALL_PREFIX ** 控制的。我们在使用 cmake 编译时可以加上这个参数:
cmake .. -DCMAKE_INSTALL_PREFIX=/install/location
比如我这里默认的安装路径为:
CMAKE_INSTALL_PREFIX | C:/Program Files (x86)/HelloHeaders |
---|
# - Install 二进制文件
install (TARGETS cmake_examples_inst_bin DESTINATION bin)
# - Install Library
install (TARGETS cmake_examples_inst LIBRARY DESTINATION lib)
# -install Header files
# - copy include directory to CMAKE_INSTALL_PREFIX/include
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)
# - Config
# - Copy config file to CMAKE_INSTALL_PREFIX/etc
install (FILES cmake-examples.conf DESTINATION etc)
Windows install 编译结果
1>-- Install configuration: "Debug"
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/bin/cmake_examples_inst_bin.exe
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/lib/cmake_examples_inst.lib
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/bin/cmake_examples_inst.dll
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/include
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/include/installing
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/include/installing/Hello.h
1>-- Installing: D:/workSpace/cmake-examples/01-basic/E-installing/install_dir/etc/cmake-examples.conf
Note: 如果安装目录在C盘,并且没有用管理员权限,不会运行成功。!!!!
CMake 提供了内置的编译类型:
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message("Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
CMake 支持设置编译选项,并且提供如下方式:
target_compile_definitions(cmake_examples_compile_flags
PRIVATE EX3
)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
以导入Boost 库为例:
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
检查是否已经找到库了
许多的包都会包含一个变量 XXX_FOUND ,用来表示这个包是否在系统中是可用的。
比如:
if(Boost_FOUND)
message ("boost found")
include_directories(${Boost_INCLUDE_DIRS})
else()
message (FATAL_ERROR "Cannot find Boost")
endif()