Cmake项目构建工具——中篇(复杂项目结构)

目录

1.gcc处理复杂项目

 2.Cmake处理复杂项目

2.1.搜索file

2.2.包含头文件路径

3.库文件

3.1.制作库文件

3.2.链接静态库

3.3.链接动态库

4.预处理

5.参考资料、视频


当一个项目中由多个.c文件组成时,再直接使用gcc指令编译会比较复杂。

Cmake项目构建工具——中篇(复杂项目结构)_第1张图片

// add.c
int add(int a,int b)
{
        return a+b;
}

//sub.c

int sub(int a,int b)
{
        return a-b;
}

//fun.h
#ifndef __FUN_H
#define __FUN_H

int add(int a,int b);
int sub(int a,int b);

#endif
//main.c
#include 
#include "fun.h"

int main(void)
{
        printf("1+2 = %d\n",add(1,2));
        printf("2-1 = %d\n",sub(2,1));
        return 0;
}

1.gcc处理复杂项目

将上面的main.c编译成可执行文件,可以用下面的gcc指令。

gcc -o main main.c ./fun/add.c ./fun/sub.c -I./fun 

-I(大写)是为了指定.h文件的路径,可预见项目结构越复杂,gcc指令也越复杂,也不方面对项目进行管理。

gcc的编译流程可以分为下面的情况:

Cmake项目构建工具——中篇(复杂项目结构)_第2张图片

可执行文件是由多个.o(可以重定位的目标文件)链接一起为可执行文件。

对于main.c 想要编译出可执行文件,可以分别生成main.o ,add.o,sub.o文件,再链接成main.exe。

 Cmake项目构建工具——中篇(复杂项目结构)_第3张图片

gcc -o main  main.o ./fun/add.o ./fun/sub.o

 2.Cmake处理复杂项目

对于复杂的项目,我们可以使用Cmake来构建。

#CMakeLists.txt
cmake_minimum_required(VERSION 3.5.0)
project(test1)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/fun/*.c ./main.c) #搜索.c文件
include_directories(./fun)   #添加.h文件路径
set(EXECUTABLE_OUTPUT_PATH ..)
add_executable(app  ${SRC})

下面介绍一下CMakeLists.txt中用到的几个函数。

2.1.搜索file

file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
  • GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。

  • GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。

  • CMAKE_CURRENT_SOURCE_DIR:CMakeLists.txt所在的文件路径

2.2.包含头文件路径

有时候.h文件不在当前目录下,在gcc中需要添加.h文件的路径,在cmake中可以用include_directories包含。

include_directories(.h文件的路径)

3.库文件

库文件分为静态库与动态库,在linux中静态库后缀.a,动态库后缀.so。库文件名 = lib+"自定义名字"+.a/.so。

Cmake项目构建工具——中篇(复杂项目结构)_第4张图片

3.1.制作库文件

add_library(库名 STATIC/SHARED 源文件)
  • STATIC  静态  默认值
  • SHARED 动态 

#指定静态库/动态库的路径
set(LIBRARY_OUTPUT_PATH 路径)

#CmakeList.txt 示例
cmake_minimum_required(VERSION 3.5.0)
project(test2)

file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
set(LIBRARY_OUTPUT_PATH ..)  #相对于Makefile的路径
add_library(fun STATIC ${SRC})  #制作库文件 libfun.a

3.2.链接静态库

Cmake项目构建工具——中篇(复杂项目结构)_第5张图片

link_directories() #指定路径


link_libraries( [...]) #链接静态库

#staic 可以是全名 lib+库名+.a
#或者 库名

#示例
cmake_minimum_required(VERSION 3.5.0)
project(test1)
include_directories(./fun)
link_directories(./fun) #指定库文件路径
link_libraries(fun)   #链接库文件
set(EXECUTABLE_OUTPUT_PATH ..)
add_executable(app  main.c)

3.3.链接动态库

target_link_libraries(
     
     ... 
    [ ...]...)
  • 表示指定加载库的文件
  • target_link_libraries()可以用来链接动态库,也可以用于链接静态库
#示例
cmake_minimum_required(VERSION 3.5.0)
project(test1)
include_directories(./fun)
link_directories(./fun)  #指定动态库地址
add_executable(app  main.c)
target_link_libraries(app libfun.so)  #链接动态库

4.预处理

预处理关键是#,在我们的调试过程中常用到printf观察结果,但发行版本又需要把调试代码剔除,这时可以用#ifdef #endif。

//C例子
void main(void)
{
    #ifdef DEBUG
    printf("DEBUG");
    #endif
}

当程序中出现宏DEBUG时才执行printf("DEBUG"),在gcc指令中可以用 -D添加宏定义:-DDEBUG,在cmake中使用 add_definitions(-DDEBUG)。

5.参考资料、视频

CMake 保姆级教程【C/C++】

你可能感兴趣的:(学习,linux,测试工具,c++)