跟着官方教程学CMAKE(二)引用库

第二步 引用一个库

这个真的是很小白,很入门了,当然也是因为我菜,不写的透彻一点,以后我也会看不懂。

官方提供了初始的代码,方便学习的人改动。
初始代码

构建库

这个例子是源码提供的库,那么当然需要指定编译和链接两个步骤。

首先在MathFunctions子文件夹中,建立一个一行的CMakeLists.txt文件,里面加入一行

add_library(MathFunctions mysqrt.cxx)

它的申明是这样的

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2 ...])

我们先试着看一下这个add_library()命令是干什么的,在这个目录下输入

mkdir build;cd build;cmake ..

这个时候会在build文件夹下面生成一个CMakeFiles的文件夹,里面又有一个MathFunctions.dir的文件夹,里面可以找到mysqrt.o,没错,这个“cmake”编译出的二进制文件,这个时候回到build文件夹,里面应该有一个Makefile文件,执行

make

你就会发现libMathFunctions.a这个静态库文件了,它就是刚才那个.o文件打包来的,当然不同平台文件名也应该不一样,在Linux上会显示libxxx.a,windows上就会是xxx.lib。

所以,这个命令的作用就是通过指定的[source]按照指定的方式[STATIC | SHARED | MODULE]来生成对应的库<name>,EXCLUDE_FROM_ALL这个参数是用来排除不想编译的文件的,先不考虑。

当然,这是个静态库,根据上面的函数申明,除此之外还可以编译成动态库,只需要改成

add_library(MathFunctions SHARED mysqrt.cxx)

这样按照刚才的步骤来,生成就会是libxxx.so文件了,而MODULE这个选项也是生成的动态库的,但一般都是用于运行时链接多用于类似于dlopen这样的函数来加载打开。

引用库

回到第二步的顶层文件夹,在CmakeLists.txt文件中的add_executable()命令前面加上

add_subdirectory(MathFunctions)

当cmake运行到这个命令时,就会引用MathFunctions中的CMakeList.txt文件了,这意味着当构建项目时,刚才生成的库不会再生成在MathFunctions这个文件夹下了,而是会生成在顶层CMakeLists.txt的构建文件夹下面。

到目前为止,还没有链接到生成的库文件,现在在add_executable()下面加入

target_link_libraries(Tutorial PUBLIC MathFunctions)

这个时候就相当于把生成的库文件加入编译选项了,但是还没有指定头文件路径,修改把target_include_directories()命令

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

这样,就指定头文件的路径了。
__这样就可以了?__当然不行,看一下tutorial.cxx,因为这个时候用的压根不是我们刚才编译的库,而是编译器提供的库,现在我们来指定用哪个库。

加入构建选项

如果有使用过cmake编译一些类似opencv的同学注意到,在用cmake-gui构建的时候,会有很多构建选项,我们也可以提供构建选项,来决定最终编译的时候用哪个库。
在顶层的CMakeLists.txt文件中的configure_file()命令上面加入

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

这个命令创建了一个叫做USE_MYMATH的宏,默认值是ON
这个时候就可以在使用cmake-gui的时候看到这个选项了,但实际上,这个宏还没有用,我们来使用一下这个宏。
把之前的那句add_subdirectory()去掉,然后把代码改为

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(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           ${EXTRA_INCLUDES}
                           )

这个if()、endif()和C语言的预编译选项很类似了,只不过加了个括号。

list(APPEND EXTRA_LIBS MathFunctions)

这个命令我的理解是,LIST()会在当前的CMake作用域中创建一个叫做MathFunctions的变量加入EXTRA_LIBS这个列表。具体的使用方式和说明在这里
LIST的使用

使用这种方式,就不用每添加一个库就写一个target_link_libraries和target_include_directories了。

接下来修改一下源文件
在tutorial.cxx的开头中加入

#ifdef USE_MYMATH
#  include "MathFunctions.h"
#endif

然后修改平方根的那行代码为

#ifdef USE_MYMATH
  const double outputValue = mysqrt(inputValue);
#else
  const double outputValue = sqrt(inputValue);
#endif

然后在TutorialConfig.h.in中加入(这个文件是构建时生成头文件用的,具体看上一步)

#cmakedefine USE_MYMATH

这些改动是为了把构建期的行为,传递到运行期
接下来再构建一下这个项目,编译,OJBK

官方最后留了一个问题如果

configure_file(TutorialConfig.h.in TutorialConfig.h)

这个命令出现在

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

前面,会发生什么。
答案是在最终生成的TutorialConfig.h中并不会生成USE_MYMATH这个宏,而是

/* #undef USE_MYMATH */
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值