cmake对第三方库的支持方式

一、介绍

在程序开发的过程中,往往会引入库(动态库和静态库)。有时会只有其中一种,有时可能会二者混用。在这种情况下,就引出了一个问题,如何在工程中对库进行支持(这里不涉及库的版本管理,也就是不处理DLL HELL之类的问题)。这个有很多种方式,不同的平台和不同的开发工具,有着不同的处理手段。比如在VS上和在Idea上都有不同,而不同的语言可能处理也有不同,这些都需要开发者自己根据实际情况来处理。
这里只提在Linux上使用Cmake进行第三方库管理的一些方法。

二、四种形式

在Linux使用第三库的方式,如果采用Cmake构建管理的话,主要有以下几种:
1、直接编译编译
这是最常用的一种方式,开发者都用过。老的方式使用方法一般是:

mkdir build
cd build 
cmake ..
make -j5
make install

不过高版本的CMake支持了下面的更简单的方式:

cmake -B build -DCMAKE_PREFIX_PATH=/home/fpc/Qt65/6.5.0/gcc_64   (通过 -S 可以 指定编译路径 -G指定构造方式 如Ninja)
cmake --build build -j5(--parallel 5)

B站上的大哥把这个叫做现代CMake,有道理。
这种方式比较适合初学者或者对项目管理简单的地方。优点是容易理解,好操作;缺点是需要手动在项目的CMake文件进行库的编译链接控制和管理。类似于下面:

find_package (库名称 1.6.0 REQUIRED)

add_executable (myapp main.cpp)
target_link_libraries (myapp 库名称)

如果有版本不同的或者不同的机器不同的开发环境,团队间配合时可能出现一些意想不到的问题。这种问题的特点是随机且不容易发现,所以在稍微大一些项目中如果采用这种方式 ,就必须有严格的库版本管理和依赖管理说明。可是大家都明白,靠人,往往是靠不住的。

2、CMake配合git submodules子模块控制

这种方法适用于团队间的源码级的有效管理,不适合只提供库的第三方,而且,第三方库和其它工程为平行关系,即第三库不属于某个工程,一定注意。在合适的路径下使用:

增加子模块:
cd examples
git submodule add http://xxx.xxx/libname.git
下载子模块:
git clone --recursive   git@xxxxxx/parent_libname.git
或者没有使用 --recursive 下载完成后,进入子目录执行:
git submodule update --init

然后在工程项目的总CMakeLists.txt文件中增加:

add_subdirectory(${CMAKE_SOURCE_DIR}/examples/libname)

在应用第三方库的项目CMakeLists.txt中增加:

add_dependencies(SUPRA_Lib libname)
TARGET_INCLUDE_DIRECTORIES(SUPRA_Lib
        PUBLIC ${SUPRA_Lib_INCLUDEDIRS} libname_include
)

target_link_libraries(SUPRA_Lib ${SUPRA_Lib_LIBRARIES} libname_path)

这种方式可以紧绑定库,不为外界影响。源码级管理,方便控制。缺点也很明显,带着一大堆的外部的库如果升级比较麻烦,同时,每一个使用的项目都得增加上面的依赖项目等。

3、直接加到工程子目录
这和上面的不同在于,这个第三方库真得成为了某个工程的子目录,也就是说add_subdirectory在某个项目的CMakeLists.txt下,比如谷歌的glog就提供了这样的方式:

add_subdirectory(${CMAKE_SOURCE_DIR}/examples/libname)
target_link_libraries(firt libname)

就是这么简单豪放,直接就可以用,不用处理什么头文件还有add_dependencies啊find_package之类的。缺点是可能不如分成模块划分更清晰一些,大工程可能有点让人维护上不方便。

4、使用外部工程的方法
这个的使用详细方法可以参考一下CMake的文档,这里给出一个例子:

include(ExternalProject)

SET(NodeEditor_DIR "${CMAKE_CURRENT_BINARY_DIR}/NodeEditor")
SET(NodeEditor_GIT_REPOSITORY "https://github.com/goeblr/nodeeditor.git" CACHE STRING "")
SET(NodeEditor_GIT_TAG "3bcba3740d68932f3ffaa4b3dc73e624fe51e2db" CACHE STRING "")
ExternalProject_Add( 
	NodeEditor
	PREFIX "${NodeEditor_DIR}"
	
	LOG_DOWNLOAD TRUE
	LOG_UPDATE TRUE
	LOG_CONFIGURE TRUE
	LOG_BUILD TRUE
	LOG_INSTALL TRUE
	
	SOURCE_DIR "${NodeEditor_DIR}"
	BINARY_DIR "${NodeEditor_DIR}_build"
	STAMP_DIR "${NodeEditor_DIR}_stamp"
	TMP_DIR "${NodeEditor_DIR}_tmp"
	#--Download step--------------
	GIT_REPOSITORY ${NodeEditor_GIT_REPOSITORY}
	GIT_TAG ${NodeEditor_GIT_TAG}
	#--Configure step-------------
	CMAKE_ARGS
	  -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
	  -DCMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
	  -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
	  -DCMAKE_BUILD_TYPE=Release
	  -DBUILD_EXAMPLES=OFF
	  -DQt5_DIR=${Qt5_DIR}
	  -DCMAKE_INSTALL_PREFIX=${NodeEditor_DIR}_install
	  -DNODE_EDITOR_STATIC=
	#--Build step-----------------
	#BUILD_ALWAYS 0
	#--Install step-----------------
	INSTALL_DIR=${NodeEditor_DIR}_install
)
SET(NodeEditor_LIBRARIES "nodes")
INCLUDE_DIRECTORIES(SUPRA_GUI "${NodeEditor_DIR}_install/include")
LINK_DIRECTORIES(SUPRA_GUI "${NodeEditor_DIR}_install/lib")

然后还在当前工程中:

TARGET_LINK_LIBRARIES(SUPRA_GUI
	${NodeEditor_LIBRARIES})
add_dependencies(SUPRA_GUI SUPRA_Lib NodeEditor)

这种方式并不简单,但应用灵活,可以说凡是可以用到的代码都可以如此操作。缺点也很明显,复杂啊,而且还要处理很多和编译无关的东西。

三、总结

CMake目前看应该是C++工程应用中的主流模式了。用它的好处是比写MakeFile要简单多了,更适合于开发者理解,相对来说简单很多。缺点是这玩意儿宏定义太多,各种错误也不好理解,如果遇到一些稀奇古怪的问题,可能老手都得流泪。瑕不掩瑜,勤学多用,主动避开一些坑儿,就会发现CMake还是挺不错的一种工具。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 。 cmake_minimum_required(VERSION 3.0) # Add asio find_package(asio REQUIRED) include_directories(${asio_INCLUDE_DIR}) # Add boost find_package(Boost REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) # Add websocketpp find_package(websocketpp REQUIRED) include_directories(${websocketpp_INCLUDE_DIR}) # Add source files add_executable(main main.cpp) # Link libraries to executable target_link_libraries(main ${asio_LIBRARY} ${Boost_LIBRARIES} ${websocketpp_LIBRARY}) ### 回答2: 在CMakeLists.txt中添加第三方库asio、boost和websocketpp,可以按照以下步骤进行操作: 1. 导入CMake模块,以支持使用find_package命令查找库的位置。 ```cmake cmake_minimum_required(VERSION 3.0) project(MyProject) ``` 2. 查找并包含asio库。 ```cmake find_package(Boost REQUIRED COMPONENTS system) include_directories(${BOOST_INCLUDE_DIRS}) # 或者手动指定asio库的路径 # set(ASIO_INCLUDE_DIR /path/to/asio) # include_directories(${ASIO_INCLUDE_DIR}) ``` 3. 查找并包含boost库。 ```cmake find_package(Boost REQUIRED COMPONENTS system) include_directories(${BOOST_INCLUDE_DIRS}) ``` 4. 查找并包含websocketpp库。 ```cmake # 通过git下载websocketpp源码 execute_process(COMMAND git clone https://github.com/zaphoyd/websocketpp.git) # 设置websocketpp库的路径 set(WEBSOCKETPP_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/websocketpp) include_directories(${WEBSOCKETPP_INCLUDE_DIR}) ``` 5. 配置源代码文件和可执行文件。 ```cmake # 添加源代码文件 add_executable(MyExecutable main.cpp) # 链接库 target_link_libraries(MyExecutable Boost::system) ``` 这样,CMakeLists.txt中添加的代码就可以支持在项目中使用asio、boost和websocketpp库了。在进行编译时,CMake会自动查找并链接这些库。记得将路径替换为实际安装的库的正确路径。 ### 回答3: 在使用CMake编写CMakeLists.txt文件时,我们可以通过以下步骤添加第三方库asio、boost和websocketpp: 1. 下载、安装并配置asio库、boost库和websocketpp库,确保可以正确地找到它们的安装路径。 2. 在项目的根目录下创建一个名为CMakeLists.txt的文件。 3. 在CMakeLists.txt文件中添加以下内容: ``` cmake_minimum_required(VERSION 3.0) # 指定CMake的最低版本 project(MyProject) # 设置项目名称 # 设置编译选项,如编译器标志等 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # 设置C++编译标志 # 添加包含目录 include_directories(/path/to/asio/include) # 替换为你的asio库的包含目录 include_directories(/path/to/boost/include) # 替换为你的boost库的包含目录 include_directories(/path/to/websocketpp/include) # 替换为你的websocketpp库的包含目录 # 添加链接库目录 link_directories(/path/to/asio/lib) # 替换为你的asio库的链接库目录 link_directories(/path/to/boost/lib) # 替换为你的boost库的链接库目录 link_directories(/path/to/websocketpp/lib) # 替换为你的websocketpp库的链接库目录 # 添加源文件 add_executable(MyExecutable main.cpp) # 替换为你的源文件 # 链接库 target_link_libraries(MyExecutable asio boost websocketpp) # 添加所需的链接库 ``` 注意替换对应的路径和库名称。 4. 保存并关闭CMakeLists.txt文件。 5. 打开终端,进入项目的根目录。 6. 创建一个名为build的文件夹,作为构建目录。 7. 在终端中执行以下命令: ``` cmake -S . -B ./build # 生成构建文件 cmake --build ./build # 编译项目 ``` 上述命令将在build文件夹中生成构建文件,并通过构建文件编译项目。 8. 编译完成后,可在build文件夹中找到生成的可执行文件。 9. 运行可执行文件,该应用程序将会使用asio、boost和websocketpp库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值