cmake 指定头文件路径_CMake教程(一)

2023-05-16

CMake官方文档:

https://cmake.org/cmake/help/v3.17/guide/tutorial/index.html#adding-system-introspection-step-5

CMake的优点

高效 、强大 、开发团队的首选

一、基础

1、按照官网教程准备计算平方根的代码,这里命名为calculatesqrt.cpp

2、编写相应的CMakeLists.txt文件

3、创建build目录

其中源代码可以参考官方github,具体如下

#include 

需要在CMakeLists.txt文件中指定如下几项,cmake版本、工程名、构建目标app的源文件

cmake_minimum_required(VERSION 3.10) 

# set the project name 
project(CalculateSqrt) 

# add the executable 
add_executable(CalculateSqrt hello.cxx) 

现有目录结构如下图所示(忽略.http://h.in文件,后面会讲到)

为构建可执行文件需要执行如下命令

cd build
Cmake ..
Make

执行后在build目录中多了一个可执行文件CalculateSqrt

二、为项目添加版本号和可配置的头文件

虽然可以在源码中指定具体的版本,但是通过CMakeLists.txt来指定项目的版本号则更加的灵活

在CMakelists.txt中首先指定project的版本号,然后添加可配置的同文件,指定C++版本为c++11

cmake_minimum_required(VERSION 3.10) 

# 设定工程名和版本号 
project(CalculateSqrt VERSION 1.0) 
# configure_file的作用将一份文件拷贝到另一个位置并修改它的内容,使得在代码中使用CMake中定义的变量 
# configure_file官方文档:https://cmake.org/cmake/help/latest/command/configure_file.html 
configure_file(CalculateSqrtConfig.h.in CalculateSqrtConfig.h) 

# specify the C++ standard 
set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED True) 

# add the executable 
add_executable(CalculateSqrt calculate.cpp) 

# 指定项目编译的时候需要include的文件路径,PROJECT_BINARY_DIR变量为编译发生的目录,也就是make执行的目录,PROJECT_SOURCE_DIR为工程所在的目录 
# target_include_directories官方文档:https://cmake.org/cmake/help/v3.3/command/target_include_directories.html 
target_include_directories(CalculateSqrt PUBLIC 
                           "${PROJECT_BINARY_DIR}" 
                           ) 

在源代码的同级目录创建http://CalculateSqrtConfig.h.in文件并指定如下内容

// the configured options and settings for CalculateSqrt,@@引用的变量可以通过CMakeLists.txt来设置 
#define CalculateSqrt_VERSION_MAJOR @CalculateSqrt_VERSION_MAJOR@ 
#define CalculateSqrt_VERSION_MINOR @CalculateSqrt_VERSION_MINOR@ 

同时需要在源代码中引入(#include)配置生成的头文件,即CalculateSqrtConfig.h

具体源代码如下

#include <stdio.h> 
#include <stdlib.h> 
#include <string> 
#include <iostream> 
#include <math.h> 
#include "CalculateSqrtConfig.h" 

int main(int argc, char* argv[]){ 
    if(argc<2){ 
        std::cout << argv[0] << " Version " << CalculateSqrt_VERSION_MAJOR << "." 
              << CalculateSqrt_VERSION_MINOR << std::endl; 
        fprintf(stdout, "Uage: %s numbern", argv[0]); 
        return 1; 
    } 
    double inputValue = atof(argv[1]); 
    double outputValue = sqrt(inputValue); 
    fprintf(stdout, "The square root of %g is %gn",inputValue, outputValue); 
    return 0; 
} 

三、为工程添加链接库lib

在本例中我们为工程添加一个lib,这个lib会包含我们自己实现的平方根计算函数,我们将自己定义的平方根计算函数放置在MathFunction目录下,同时在该目录下需要添加一个新的CMakelists.txt文件,具体内容如下

# 使用特定的源码为项目增加lib 
add_library(MathFunctions mysqrt.cpp) 

为了在源码中使用我们自己定义的平方根函数,需要在上层的CMakeLists.txt中做相应的修改

cmake_minimum_required(VERSION 3.10) 

# set the project name 
project(CalculateSqrt VERSION 1.0) 
configure_file(CalculateSqrtConfig.h.in CalculateSqrtConfig.h) 

# specify the C++ standard 
set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED True) 

# add the MathFunctions library,Add a subdirectory to the build,将新加的子目录用于build 
add_subdirectory(MathFunctions) 

# add the executable 
add_executable(CalculateSqrt calculate.cpp) 

# 该指令的作用为将目标文件与库文件进行链接 
# target_link_libraries官方文档:https://cmake.org/cmake/help/latest/command/target_link_libraries.html 
target_link_libraries(CalculateSqrt PUBLIC MathFunctions) 

target_include_directories(CalculateSqrt PUBLIC 
                           "${PROJECT_BINARY_DIR}" 
                           "${PROJECT_SOURCE_DIR}/MathFunctions" 
                           ) 

接下来我们尝试将自己定义的lib更改为可选的,该功能在本例中不是必要的,但是在大型的项目中却是一个比较常见的功能,具体操作如下。首先就是在上层的CMakeLists.txt中增加一个option,然后将lib和include路径增加到EXTRA_LIBS和EXTRA_INCLUDE两个变量中,具体上层的CMakeLists.txt修改为如下

cmake_minimum_required(VERSION 3.10) 

# set the project name 
project(CalculateSqrt VERSION 1.0) 

option(USE_MYMATH "Use tutorial provided math implementation" ON) 

configure_file(CalculateSqrtConfig.h.in CalculateSqrtConfig.h) 

# specify the C++ standard 
set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED True) 

# add the MathFunctions library,Add a subdirectory to the build 
#add_subdirectory(MathFunctions) 
if(USE_MYMATH) 
  add_subdirectory(MathFunctions) 
  list(APPEND EXTRA_LIBS MathFunctions) 
  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions") 
endif() 

# add the executable 
add_executable(CalculateSqrt calculate.cpp) 

target_link_libraries(CalculateSqrt PUBLIC ${EXTRA_LIBS}) 

target_include_directories(CalculateSqrt PUBLIC 
                           "${PROJECT_BINARY_DIR}" 
                           "${EXTRA_INCLUDES}" 
                           ) 

其次需要在可配置的头文件中添加cmakelists.txt中定义的变量USE_MYMATH

// the configured options and settings for CalculateSqrt 
#define CalculateSqrt_VERSION_MAJOR @CalculateSqrt_VERSION_MAJOR@ 
#define CalculateSqrt_VERSION_MINOR @CalculateSqrt_VERSION_MINOR@ 
#cmakedefine USE_MYMATH 

最后我们在源码中include相应的头文件即可

#include <stdio.h> 
#include <stdlib.h> 
#include <string> 
#include <iostream> 
#include <math.h> 
#include "CalculateSqrtConfig.h" 
#ifdef USE_MYMATH 
    #include "MathFunctions.h" 
#endif 

int main(int argc, char* argv[]){ 
    if(argc<2){ 
        std::cout << argv[0] << " Version " << CalculateSqrt_VERSION_MAJOR << "." 
              << CalculateSqrt_VERSION_MINOR << std::endl; 
        fprintf(stdout, "Uage: %s numbern", argv[0]); 
        return 1; 
    } 
    double inputValue = atof(argv[1]); 
    #ifdef USE_MYMATH 
        const double outputValue = mysqrt(inputValue); 
    #else 
        const double outputValue = sqrt(inputValue); 
    #endif 
    fprintf(stdout, "The square root of %g is %gn",inputValue, outputValue); 
    return 0; 
} 

四、为lib增加使用需求

根据不同使用场景,可以对如下命令指定相应的使用需求

  • target_compile_definitions()
  • target_compile_options()
  • target_include_directories()
  • target_link_libraries()

以上文例子为例,在代码中想要调用MathFunctions中的函数,就需要#include对应的代码路径,然而MathFunctions本身不需要#include,所以这里采用INTERFACE来满足该需求,将MathFunctions中的CMakeLists.txt更改为

add_library(MathFunctions mysqrt.cpp) 
target_include_directories(MathFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) 

同时我们可以将上层目录中的CMakeLists.txt中的EXTRA_INCLUDE变量去掉,同时将其从target_include_directiontarget_include_directories中删除

cmake_minimum_required(VERSION 3.10) 

# set the project name 
project(CalculateSqrt VERSION 1.0) 

option(USE_MYMATH "Use tutorial provided math implementation" ON) 

configure_file(CalculateSqrtConfig.h.in CalculateSqrtConfig.h) 

# specify the C++ standard 
set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED True) 

# add the MathFunctions library,Add a subdirectory to the build 
#add_subdirectory(MathFunctions) 
if(USE_MYMATH) 
  add_subdirectory(MathFunctions) 
  list(APPEND EXTRA_LIBS MathFunctions) 
endif() 

# add the executable 
add_executable(CalculateSqrt calculate.cpp) 

target_link_libraries(CalculateSqrt PUBLIC ${EXTRA_LIBS}) 

target_include_directories(CalculateSqrt PUBLIC 
                           "${PROJECT_BINARY_DIR}" 
                           ) 

五、安装和测试

接下来我们会添加install规则和testing到工程,install规则非常简单,对于MathFunctions库来说,我们在MathFunctions/CMakeLists.txt中添加如下两行来实现安装库和头文件

install(TARGETS MathFunctions DESTINATION lib) 
install(FILES MathFunctions.h DESTINATION include) 

对于应用来说,我们在上层的CMakeLists.txt中添加如下两行来实现安装目标文件和可配置头文件

install(TARGETS CalculateSqrt DESTINATION bin) 
install(FILES "${PROJECT_BINARY_DIR}/CalculateSqrtConfig.h" 
  DESTINATION include 
  ) 

这样我们在执行cmake..&&make install之后,指定的库、头文件和目标文件就安装到指定的目录中了,具体如下

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake 指定头文件路径_CMake教程(一) 的相关文章

随机推荐