一、最简单的应用

1、环境

gcc -v
gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04.1)

cmake -version
cmake version 3.22.1

make -v
GNU Make 4.3

2、项目简介

在项目主工程目录下只有main.cpp,gorun.sh,testadd,CMakeLists.txt,执行./gorun.sh即可编译和执行程序。

├── CMakeLists.txt
├── gorun.sh
├── main.cpp
└── testadd
    ├── add.cpp
    ├── add.h
    └── CMakeLists.txt

2.1 testadd目录下的所有文件内容

该目录下的函数testadd,就是实现两变量相加,返回所得的参数。

2.1.1 add.cpp

#include"add.h"

int testadd(int a,int b){
    return a+b;
}

2.1.2 add.h

#ifndef __TESTADD_H_
#define __TESTADD_H_
#include <stdio.h>


int testadd(int a,int b);

#endif // __TESTADD_H_

2.1.3 CMakeLists.txt

add_library(testadd_executable   add.cpp )

target_include_directories(testadd_executable PUBLIC .)

add_library:命令用于将库添加到项目中。它的功能是定义一个库目标,并将源代码文件与该目标关联起来。
target_include_directories:命令用于为特定目标(可执行文件或库)指定头文件搜索路径。它告诉构建系统在编译指定目标时应该搜索哪些目录以查找头文件
这个地方target_include_directories(testadd_executable PUBLIC .)是可以保证testadd_executable 可以查找到当前目录下的所有头文件

2.2 主目录下的所有文件内容

2.2.1 main.cpp

输入两个变量,将计算所得的结构进行打印。

#include "add.h"
int main()
{
    int a = 3;
    int b = 4;
    int sum = 0;
    sum = testadd(a, b);
    printf("%s %d sum = %d\n", __func__, __LINE__,sum);
}

2.2.2 gorun.sh

在项目的主目录下直接执行./gorun.sh,就可以对项目进行编译和执行编译所得的可执行文件test_cmake。
提示:在执行前需要线修改gorun.sh的 权限
chmod 777 gomake.sh

mkdir -p build/
pushd build/
cmake ..
make -j8
popd
cd build
./test_cmake

mkdir:新建文件夹
-p 确保新建的目录存在
pushd 进入到指定的文件目录
cmake … 在当前目录的上一级目录执行cmake
make 编译代码
-j8 多线程进行编译
popd 编译结束后 将刚才push进去的目录释放出来
cd build 进入到build目录下
./test_cmake 执行项目生成的可执行文件

2.3.3 CMakeLists.txt

cmake_minimum_required(VERSION 3.15)

project(test_cmake VERSION 0.1.0) 

SET(SRC_LIST main.cpp)


add_subdirectory(testadd) 

add_executable(${PROJECT_NAME} ${SRC_LIST})



target_link_libraries(${PROJECT_NAME} PUBLIC testadd_executable)


target_include_directories(${PROJECT_NAME} PUBLIC
                           ${PROJECT_BINARY_DIR}
                           ${PROJECT_SOURCE_DIR}/testadd 
                           )

语句解释:

cmake_minimum_required(VERSION 3.15):
指定要求的CMake的最低版本为3.15。这意味着运行CMake脚本的CMake版本必须为3.15或更高版本。

project(test_cmake VERSION 0.1.0):
定义了项目名称为"test_cmake",并指定项目的版本号为0.1.0。
该命令还会自动定义一些与项目相关的变量,例如${PROJECT_NAME}。

SET(SRC_LIST main.cpp):
定义了一个变量SRC_LIST,并将其设置为main.cpp。该变量将用于指定生成可执行文件的源文件列表。

add_subdirectory(testadd):
将子目录testadd添加到构建过程中。这意味着CMake将进入testadd目录,
并继续处理该目录下的CMakeLists.txt文件。

add_executable(${PROJECT_NAME} ${SRC_LIST}):
定义了一个可执行文件目标,名称为${PROJECT_NAME}(即"test_cmake"),
并将源文件列表${SRC_LIST}与该目标关联起来。这将生成一个名为"test_cmake"的可执行文件。

target_link_libraries(${PROJECT_NAME} PUBLIC testadd_executable):
将目标${PROJECT_NAME}与名为testadd_executable的库进行链接。
通过使用PUBLIC关键字,表示将链接库的依赖关系公开给${PROJECT_NAME}的使用者。

target_include_directories(${PROJECT_NAME} PUBLIC ...):
为${PROJECT_NAME}目标添加头文件搜索路径。通过使用PUBLIC关键字,
表示将这些头文件搜索路径公开给${PROJECT_NAME}的使用者。
这里添加了${PROJECT_BINARY_DIR}(构建目录)和
${PROJECT_SOURCE_DIR}/testadd(testadd子目录)作为头文件搜索路径。

PROJECT_BINARY_DIR:该变量指向当前项目的构建目录,
即在运行CMake时生成的Makefile和其他构建文件的存放位置。
构建目录是在运行CMake时指定的build目录或者在命令行中通过-B选项指定的目录。

PROJECT_SOURCE_DIR:该变量指向当前项目的源代码目录,
即CMakeLists.txt文件所在的目录。通常情况下,它是指定项目根目录的路径。

二、添加复杂的库mp4v2

1、链接:https://github.com/TechSmith/mp4v2/tree/3.0.4

2、现在所得的目录:


3、找到我们真正需要用到的,将下面四个目录添加中主项目的mp4v2my目录下。

得到的工程目录:

4、在mp4v2my目录下添加CMakeLists.txt


if(WIN32)
   set(OSSPEC_SRC
        libplatform/io/File_win32.cpp
        libplatform/io/FileSystem_win32.cpp
        libplatform/number/random_win32.cpp
        libplatform/process/process_win32.cpp
        libplatform/time/time_win32.cpp
        libplatform/platform_win32.cpp
   )
else()
   set(OSSPEC_SRC
        libplatform/io/File_posix.cpp
        libplatform/io/FileSystem_posix.cpp
        libplatform/number/random_posix.cpp
        libplatform/process/process_posix.cpp
        libplatform/time/time_posix.cpp
       )
endif()
set(SOURCE_FILES
        ${OSSPEC_SRC}
        libplatform/io/File.cpp
        libplatform/io/FileSystem.cpp
        libplatform/prog/option.cpp
        libplatform/sys/error.cpp
        libplatform/time/time.cpp)

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/libutil  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/bmff  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/itmf  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/qtff  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src  LIBMP4v2)


add_library(mp4v2my1  ${SOURCE_FILES} ${LIBMP4v2})

target_include_directories(mp4v2my1 PUBLIC .)

详细的解释说明:

//第一个部分有选项编译,是因为这个库的特殊性,在不同的环境里面需要引用的源代码不一样,
//这个地方是直接参考在官网下载的文件得到的,不用过多纠结,
if(WIN32)
   set(OSSPEC_SRC
        libplatform/io/File_win32.cpp
        libplatform/io/FileSystem_win32.cpp
        libplatform/number/random_win32.cpp
        libplatform/process/process_win32.cpp
        libplatform/time/time_win32.cpp
        libplatform/platform_win32.cpp
   )
else()
   set(OSSPEC_SRC
        libplatform/io/File_posix.cpp
        libplatform/io/FileSystem_posix.cpp
        libplatform/number/random_posix.cpp
        libplatform/process/process_posix.cpp
        libplatform/time/time_posix.cpp
       )
endif()

//set(SOURCE_FILES ...):这行代码定义了一个变量 SOURCE_FILES,
它包含了一系列源文件的路径。${OSSPEC_SRC}是一个变量,
表示一些特定操作系统相关的源文件路径。其他行的 libplatform/io/File.cpp、
libplatform/io/FileSystem.cpp等是具体的源文件路径 


set(SOURCE_FILES
        ${OSSPEC_SRC}
        libplatform/io/File.cpp
        libplatform/io/FileSystem.cpp
        libplatform/prog/option.cpp
        libplatform/sys/error.cpp
        libplatform/time/time.cpp)


/aux_source_directory(dir VAR):
这个函数会自动将指定目录 dir 中的源文件添加到变量 VAR 中。
在这段代码中,它被多次调用,
分别将 ${CMAKE_CURRENT_SOURCE_DIR}/libutil、
${CMAKE_CURRENT_SOURCE_DIR}/src/bmff、
${CMAKE_CURRENT_SOURCE_DIR}/src/itmf、
${CMAKE_CURRENT_SOURCE_DIR}/src/qtff、
${CMAKE_CURRENT_SOURCE_DIR}/src 目录中的源文件添加到变量 LIBMP4v2 中

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/libutil  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/bmff  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/itmf  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/qtff  LIBMP4v2)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src  LIBMP4v2)

//add_library(mp4v2my1 ...):
这行代码定义了一个名为 "mp4v2my1" 的库,
并将 SOURCE_FILES 和 LIBMP4v2 中的源文件添加到该库中。


add_library(mp4v2my1  ${SOURCE_FILES} ${LIBMP4v2})


//target_include_directories(mp4v2my1 PUBLIC ...):
这行代码指定了目标库 "mp4v2my1" 的头文件搜索路径。
在这里,. 表示当前目录,即与CMakeLists.txt文件所在的目录。
使用 PUBLIC 关键字表示这些头文件路径将被公开,
允许其他使用该库的目标可以访问这些头文件

target_include_directories(mp4v2my1 PUBLIC .)

5、将新添加的目录 告知主目录

在主目录的CMakeLists.txt添加下面语句

# 添加一个子目录
add_subdirectory(mp4v2my)

6、调用最新的库mp4v2my1

我们在testadd目录下调用最新的库mp4v2my1

1、在testadd目录的CMakeLists.txt 添加:

target_link_libraries(testadd_executable mp4v2my1)

意思就是编译testadd_executable 需要依赖mp4v2my1

2、我们还需要将新添加的库的头文件路径告诉testadd目录
在testadd目录的CMakeLists.txt 添加:

target_include_directories(testadd_executable PUBLIC
                           ${PROJECT_SOURCE_DIR}/mp4v2my/include/mp4v2
                           )

最后testadd目录的CMakeLists.txt

add_library(testadd_executable   add.cpp )
target_link_libraries(testadd_executable mp4v2my1)
target_include_directories(testadd_executable PUBLIC
                           ${PROJECT_SOURCE_DIR}/mp4v2my/include/mp4v2
                           )

三、直接引用已经编译好的库

1、按照上面的例子编译好一个库libtest_executableqq.a,直接待bulid目录下找到对应的库

2、将.a库文件和对应的头文件放在同一个目录testqq下,将其放在主目录下

3、在主目录目录下新建一个cmake目录,里面添加一个文件project.cmake,里面填上下面的内容,意思就是将libtest_executableqq.a库重新命名为SOC_LIBS

SET(SOC_LIBS
    libtest_executableqq.a 
)

4、在需要引用该库的文件的CMakeLists.txt文件下添加,这个和正常自己添加源代码的库时的添加方法时一样的,

target_link_libraries(${PROJECT_NAME} PUBLIC  ${SOC_LIBS})

还需要将包含库文件的目录告诉主目录,使用的语句如下

LINK_DIRECTORIES(
   ${CMAKE_SOURCE_DIR}/testqq
)

5、引用project.cmake,在主目录下的CMakeLists.txt开头添加下面语句

include(${CMAKE_SOURCE_DIR}/cmake/project.cmake)

6、常用的库文件

我们还可以在project.cmake里面添加项目语句,将一下常用的公共库添加到项目当中

SET(SYSTEM_LINK_LIB
    -lpthread
    -lrt
    -ldl
    -lm
)

-lpthread: 这是链接POSIX线程库的选项。POSIX线程库提供了多线程编程的支持。
-lrt: 这是链接实时库的选项。实时库提供了一些与时间、定时器和信号相关的功能。
-ldl: 这是链接动态加载库的选项。动态加载库允许程序在运行时动态加载和链接共享库。
-lm: 这是链接数学库的选项。数学库提供了各种数学函数和操作的支持

特别提示:

当目前是文件是.cpp文件时,如果你引用的库文件时.c文件 编辑时,
那么在引用头文件的时候需要使用,否者会提示没有定义函数!!!

extern "C" {
#include "testqq.h"
}

本文项目链接:
https://download.csdn.net/download/qq_43441284/87816449