windows使用cmake开发C++注意事项记录

本文详细介绍了在C++项目中如何管理库引用,包括直接引用OpenCV库的步骤,以及处理多个包相互依赖的情况。通过CMakeLists.txt配置头文件和库路径,使用ADD_SUBDIRECTORY导入子目录的CMakeLists,并编写Findxxx.cmake文件来查找和配置库。同时,文章讲解了共享库的导出方法,以及在Visual Studio 2019中按依赖顺序编译和安装各个包的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,库引用

如引用OpenCV,最快捷的方式是在官网下载如opencv-3.4.10-vc14_vc15.exe的exe程序,运行后即可获得编译后的opencv。

在CMakeLists.txt中配置opencv的头文件目录和lib文件即include_directories和target_link_libraries即可完成引用。

include_directories和target_link_libraries可都使用绝对路径,避免出错。用OpenCV_DIR,${OpenCV_LIBRARIES} ,${OpenCV_INCLUDE_DIRS}等来配置可能会出错。

其他库的引用同样,只需在 include_directoriestarget_link_libraries命令中分别配置库的绝对路径即可。

二,多个包相互依赖

比如下图目录结构:

base包和sock包都是作为共享库,sock依赖base,dcm包依赖base和sock。

1)在根目录的CMakeLists.txt中配置

ADD_SUBDIRECTORY(src/package/base)
ADD_SUBDIRECTORY(src/package/sock)
ADD_SUBDIRECTORY(src/package/dcm)

理解:ADD_SUBDIRECTORY相当于将子目录CMakeLists.txt中的脚本导入到根目录的CMakeLists.txt,在根目录的build文件夹下执行cmake ..的时候,cmake的source对象是根目录的CMakeLists.txt。

此时无论是在子目录的CMakeLists.txt中还是Findxxx.cmake文件中引用全局变量CMAKE_SOURCE_DIR,其值都是根目录的路径。而PROJECT_SOURCE_DIR所指的是所在的CMakeLists.txt的路径。

2)配置Findxxx.cmake文件的路径,在执行find_package时cmake会去CMAKE_MODULE_PATH中的路径中寻找包的cmake文件

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)

3)编写Findxxx.cmake

该文件最基本的作用时定义包xxx的头文件目录变量和lib文件路径变量,最简单如下

message("==================start find base package=================")
if(NOT DEFINED base_DIR)
	message("not define package dir ")
else()
	message("package dir is ${base_DIR} ")
endif()

message("cmake src dir is ${CMAKE_SOURCE_DIR} ")

set(base_LIB_DIR "${CMAKE_SOURCE_DIR}/install/lib")
set(base_INC_DIR "${base_DIR}/include")

if((NOT EXISTS "${base_INC_DIR}") OR (NOT EXISTS "${base_LIB_DIR}"))
	message("this module include or lib path not exsit")
endif()

FIND_LIBRARY(base_LIBS NAMES base PATHS "${base_LIB_DIR}")
if(base_LIBS)
	set(base_FOUND TRUE)
	set(base_INCLUDE_DIRS ${base_INC_DIR})
	set(base_LIBRARIES ${base_LIBS})
	# mark_as_advanced(base_FOUND base_INCLUDE_DIRS base_LIBRARIES)
else()
	message("can not found lib")
endif()

上面时base包的cmake文件,在dcm包的CMakeLists.txt中就可以使用下面命令来引用base包

find_package(base)

include_directories(${base_INCLUDE_DIRS})

target_link_libraries(${PROJECT_NAME}_lib PUBLIC
    ${base_LIBRARIES} 

}

4)配置lib和exe安装目录,在根目录CMakeLists.txt中设置CMAKE_INSTALL_PREFIX包含的路径

set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)

5)在子项目的CMakeLists.txt配置targets的安装路径,如下

INSTALL(TARGETS ${PROJECT_NAME} 
    RUNTIME DESTINATION lib
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
)

因为根目录CMakeLists.txt配置了CMAKE_INSTALL_PREFIX,这里的文件夹lib是在CMAKE_INSTALL_PREFIX目录下的,所以该子项目的targets会被安装到MedicalApp/install/lib目录下。

TARGETS 可指定多个。

三,共享库导出

base和sock作为共享库供dcm包使用,在base和sock的头文件中,对于所有导出函数,在函数前加_declspec(dllexport),如下:

对于所有导出类,在类名前加上

#ifdef OS_WIN
    _declspec(dllexport)
#endif

如下:

以上对类和函数的添加都是在头文件中,源文件中不需要添加

四,包编译

由于sock依赖base,dcm依赖base和sock,所以在用vs2019编译及安装时,顺序依次是base,sock,dcm

1)在vs2019中,选择"视图"->"终端",执行如下

cd build

cmake ..

2)在MedicalApp\build\src\package\base目录下打开base.sln,选择"INSTALL"右键"生成",结束后会生成base.dll和base.lib,并且已经拷贝到MedicalApp\install\lib目录下

3)接下来对sock包和dcm包依次执行上面步骤,最终在MedicalApp\install\lib目录下,如下图:

其中opencv_world3410d.dll是手动拷贝过来的,exe运行时需要

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值