CMake:Tutorial-Step2

Step2 :Adding a Library (添加一个库)

在工程里添加一个库。现在的工程结构如下:
+
CMake:Tutorial-Step2_第1张图片

我们目的是将MathFunctions/文件夹内的头文件MathFunctions.h和源代码mysqrt.cxx编译成一个库,外部的tutorial.cxx再使用这个库的功能。

0 子文件夹内的CMakeLists.txt

在包含要编译成库的源码的路径下添加一个CMakeLists.txt:

add_library(MathFunctions mysqrt.cxx)# 把当前文件夹下的mysqrt.cxx 编译名为MathFunctions的库。

1 顶层文件夹内的CMakeLists.txt

为了这个编译好的库能被顶层的CMakeLists.txt 找到 ,需要在顶层的CMakeList.txt 内添加一些语句并修改一些语句确保编译后的库可以被引用,

  1. 提前告知所要编译的库的源代码文件夹,类似于代码中include头文件所以add_subdirectory(子文件夹名)add_executable(工程名 主程序源代码文件)之前;
  2. add_executable()之后指定目标要链接的库 target_link_libraries(),目标需要由add_library() 或者add_executable()生成;
  3. 修改 target_include_directories()指定目标包含的头文件路径,包含子目录文件夹;

target_include_directories() :

target_link_directories( [BEFORE]
   [items1...]
  [ [items2...] ...])

其中INTERFACE|PUBLIC|PRIVATE

#add the mathfunction library
add_subdirectory(MathFunctions)

#add the executable
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC MathFunctions)

#add the include directories 
target_include_directories(Tutorial PUBLIC 
			"${PROJECT_BINARY_DIR}"
			"${PROJECT_BINARY_DIR}/MathFunctions"
    			)

2 添加编译选项

在大型工程项目中可能需要添加一些是否必要选用自己写的库还是其他库,即需要在顶层CMakeLists.txt给出一个可选择的编译选项开关。

其中option( "" [value])给出一个选项。如果[value]这个参数没有给定,缺省的值为OFF.

0 创建选项:

添加在 configure_file()命令之前。

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

# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)

当使用ccmake或者gui的时候会弹出该选项。

1 使用if语句让编译和链接自编写库都变得可调节

(make it conditional)

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}
                           )

其中,list()命令主要用于对列表进行操作,如下:

Reading
  list(LENGTH  )
  list(GET   [ ...] )
  list(JOIN   )
  list(SUBLIST    )

Search
  list(FIND   )

Modification
  list(APPEND  [...])
  list(FILTER  {INCLUDE | EXCLUDE} REGEX )
  list(INSERT   [...])
  list(POP_BACK  [...])
  list(POP_FRONT  [...])
  list(PREPEND  [...])
  list(REMOVE_ITEM  ...)
  list(REMOVE_AT  ...)
  list(REMOVE_DUPLICATES )
  list(TRANSFORM   [...])

Ordering
  list(REVERSE )
  list(SORT  [...])

list 的子命令APPEND,INSERT等等这些都是列表的操作

需要注意的是cmake的列表是由 ;隔开的字符串。例如可以用 set()来生成cmake的列表:

set (var a b c d e)会生成一个list有5个元素:a;b;c;d;e

set(var "a b c d e")会生成一个list或一个字符串,其中有1个元素。

对于APPEND即在list尾部加上该元素。在这里使用EXTRA_LIBS 变量来包含所有后续可供选择的,会被链接到主程序的库们,使用EXTRA_INCLUDES 变量同理包含上述库所在的路径。这是一个很经典(老式)方法,后面tutorial会介绍更现代(新式)的方法。

使用EXTRA_LIBSEXTRA_INCLUDES包含了要添加的库名和库源码所在路径之后相应的 target_link_libraries()target_include_directories()中使用对EXTRA_LIBSEXTRA_INCLUDES的引用。

2 修改源码

配置文件都修改完之后修改源码主程序中对库的依赖,

1修改Tutorial.cxx,

其中需要修改头文件包含和函数部分,使用宏来完成:

#ifdef USE_MYMATH
#  include "MathFunctions.h"
#endif
...
#ifdef USE_MYMATH
  const double outputValue = mysqrt(inputValue);
#else
  const double outputValue = sqrt(inputValue);
#endif
2修改TutorialConfig.h.in
#cmakedefine USE_MYMATH

3 编译 测试

新建build文件夹在其中进行编译:

mkdir build
cd build
cmake ../    #若想要关闭自编库的引入,cmake ../ -DUSE_MYMATH=OFF
cmake --build .
./Tutorial 9

Note:

我在测试时使用命令行可以关掉USE_MYMATH,但是ccmake的时候没能看到这个选项。

你可能感兴趣的:(cmake,C++,c++,cmake)