a3Cmake使用教程

13、add_subdirectory

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
 

这个指令用于向当前的工程添加存放源文件的目录,并可以指定中间二进制和目标二进制存放的位置。 EXCLUDE_FROM_ALL参数的含义是将这个目录从编译的过程中排除,比如,工程中的example,可以就需要工程构建完成后,再进入example目录单独进行构建。
有这样一种情况。自己写了一个库,需要写测试程序。类似如下结构
 

hello-world/
├── CMakeLists.txt
├── main.c
├── test
│   ├── CMakeLists.txt
│   └── main.c
├── hello
│   ├── CMakeLists.txt
│   ├── hello.c
│   └── hello.h
└── world
    ├── CMakeLists.txt
    ├── world.c
    └── world.h

hello/ 目录生成 libhello.so,world/ 目录生成 libworld.so,test/ 目录存储测试程序,测试上述两个库功能是否正常。请注意 test/ 与 hello/ 和 world/ 的目录层级关系。我们只关注 test/CMakeLists.txt 文件。第一反应,是这么写:
 

cmake_minimum_required(VERSION 3.5)
​
project(test C) 
​
#库目录
set(TOP_DIR ${CMAKE_CURRENT_LIST_DIR}/../)
​
add_subdirectory(${TOP_DIR}/hello)
add_subdirectory(${TOP_DIR}/world)
​
add_executable(${PROJECT_NAME} main.c)
​
target_link_libraries(${PROJECT_NAME} PRIVATE hello)
target_link_libraries(${PROJECT_NAME} PRIVATE world)
​
target_include_directories(${PROJECT_NAME} PRIVATE ${TOP_DIR}/hello)
target_include_directories(${PROJECT_NAME} PRIVATE ${TOP_DIR}/world)

编译结果:

-- The C compiler identification is GNU 5.3.1
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
CMake Error at CMakeLists.txt:10 (add_subdirectory):
  add_subdirectory not given a binary directory but the given source
  directory "/home/sdc/pro/hello-world/hello" is not a subdirectory of
  "/home/sdc/pro/hello-world/test".  When specifying an out-of-tree source a
  binary directory must be explicitly specified.
​
CMake Error at CMakeLists.txt:11 (add_subdirectory):
  add_subdirectory not given a binary directory but the given source
  directory "/home/sdc/pro/hello-world/world" is not a subdirectory of
  "/home/sdc/pro/hello-world/test".  When specifying an out-of-tree source a
  binary directory must be explicitly specified.
​
-- Configuring incomplete, errors occurred!
See also "/home/sdc/pro/hello-world/test/build/CMakeFiles/CMakeOutput.log".

add_subdirectory 发生错误。
错误原因: hello/ 目录不是 test/ 的子目录。
解决方法: 显式指定 binary directory。
在使用 add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])命令时,如果 source_dir 不是当前目录(CMakeLists.txt 所在目录,例子中的 test/ 目录)的子目录,那么就需要显式指定 [binary_dir] 参数,用于存储 source_dir 相关文件。
修改CMakeLists.txt 文件中的 add_subdirectory()命令为如下方式即可:
 

#指定 [binary_dir] 参数
add_subdirectory(${TOP_DIR}/hello hello_binary_dir)
add_subdirectory(${TOP_DIR}/world world_binary_dir)
 

**说明:**例子中的 hello/ 和world/ 目录与 test/ 目录是平级关系。实际上,只要不是上下级关系(比如,hello/ 和 world/ 目录在其他目录下或者是 test/ 目录的上级),在使用 add_subdirectory() 时都需要指定 [binary_dir] 参数。
 

第二季 测试的例子

、从“Hello, world!”开始
了解cmake的基本原理并在系统中安好cmake后,我们就可以用cmake来演示那个最经典的”Hello, world!”了。

第一步,我们给这个项目起个名字——就叫HELLO吧。因此,第一部为项目代码建立目录hello,与此项目有关的所有代码和文档都位于此目录下。

第二步,在hello目录下建立一个main.c文件,其代码如下:
 

#include 

int main(void)

{

    printf("Hello,World\n");

    return 0;
}

至此,整个hello项目就已经构建完毕,可以进行编译了。

第三步,在hello目录下建立一个新的文件CMakeLists.txt,它就是 cmake所处理的“代码“。其实,使用cmake管理项目本身也是在编程,所以称之为“代码(或脚本)”并不为过。在CMakeLists.txt文件中输入下面的代码(#后面的内容为代码行注释):
        #cmake最低版本需求,不加入此行会受到警告信息
 

#cmake最低版本需求,不加入此行会受到警告信息
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

#项目名称
PROJECT(HELLO)

 #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
 AUX_SOURCE_DIRECTORY(. SRC_LIST)

 #生成应用程序 hello (在windows下会自动生成hello.exe)
 ADD_EXECUTABLE(hello ${SRC_LIST})

第四步,编译项目。为了使用外部编译方式编译项目,需要先在目录hello下新建一个目录build(也可以是其他任何目录名)。现在,项目整体的目录结构为:
        hello/
        |– CMakeLists.txt
        |– build /
        |– main.c
 

在windows下,cmake提供了图形界面,设定hello为source目录,build为二进制目录,然后点击configure即可开始构建,之后进入build目录运行make命令编译。

在linux命令行下,首先进入目录build,然后运行命令(注:后面的“..”不可缺少):

该命令使cmake检测编译环境,并生成相应的makefile。接着,运行命令make进行编译。编译后,生成的所有中间文件和可执行文件会在build目录下。 下面是我在ubuntu上的运行过程:
 

-- Configuring done
-- Generating done
-- Build files have been written to: /home/zc/fs4412/train/lianXunFactory/a10Cmake/HELLO/hello/build

1

 ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  Makefile

2

make
Scanning dependencies of target hello
[ 50%] Building C object CMakeFiles/hello.dir/main.c.o
[100%] Linking C executable hello
[100%] Built target hello

3

ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  hello  Makefile

4

./hello
Hello,World

第一个问题:上面,我们提到了一个名词,叫外部编译方式。其实,cmake还可以直接在当前目录进行编译,无须建立build目录。但是,这种做法会将所有生成的中间文件和源代码混在一起,而且cmake生成的makefile无法跟踪所有的中间文件,即无法使用”make distclean”命令将所有的中间文件删除。因此,我们推荐建立build目录进行编译,所有的中间文件都会生成在build目录下,需要删除时直接清空该目录即可。这就是所谓的外部编译方式。
 

第二个问题: cmake 的手册详解:http://www.cnblogs.com/coderfenghc/archive/2012/06/16/CMake_ch_01.html

第三个问题:在Linux中使用cmake 构建应用程序: http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/

CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法。在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:
 

编写 CmakeLists.txt。

执行命令“cmake PATH”或者“ccmake PATH”生成 Makefile ( PATH 是 CMakeLists.txt 所在的目录 )。

使用 make 命令进行编译。

你可能感兴趣的:(数据库,c++)