一、最简单的应用
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