个人的总结:
一、一个普通项目的CMakeLists.txt用到这些就足够了
一般的项目只需要用到下面这些语句,基本上已经满足需求了。其它的一些指令,用到的时候再查就行。
cmake_minimum_required(VERSION 3.5.0) # 设置cmake最低版本,(可以不用写)
project(TestProject) # 设置项目名称
set(CMAKE_CXX_STANDARD 11) # 设置c++版本
# caffe
set(CAFFE_ROOT ${CMAKE_SOURCE_DIR}/3rdparty/caffe) #CMAKE_SOURCE_DIR表示最顶层CMakeLists.txt的文件夹路径
# 1.设置包含(头文件)目录
include_directories(${CAFFE_ROOT}/include) #PROJECT_SOURCE_DIR指当前CMakeLists.txt的文件夹路径
# 2.设置连接库文件目录(lib)
link_directories(${CAFFE_ROOT}/lib)
# 将opencv_core追加到REDIS_TEST_LINK_LIB变量中
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_core)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_imgproc)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_imgcodecs)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_highgui)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC caffe)
# 3.添加源文件.
aux_source_directory(./redis REDIS_SRC) # 搜索路径下所有源代码文件,并保存到REDIS_SRC变量中
# 4.生成可执行文件
add_executable(redis_test redis_test.cpp ${REDIS_SRC}) #参数1:生成可执行文件的名称;参数2:指定生成可执行文件,需要用到的源文件
# 5.为可执行文件添加链接库(方式1)
target_link_libraries(redis_test ${REDIS_TEST_LINK_LIB}) #参数1:目标文件;参数2:指定的链接库
二、添加连接库的两种方式:
结论:这里推荐第2种方式,这种方式比较清晰明了,可执行需要用到什么链接库直接list增加即可,增删都比较清楚。
方法1这种方式,当链接库比较多时,会看起来比较杂乱,不容易维护,漏掉了链接库也不太好查看。
# 方式1.直接将所有链接库依次放在target_link_libraries参数中
target_link_libraries(redis_test caffe opencv_core opencv_imgproc opencv_imgcodecs opencv_highgui)
# 方式2.通过list的方式将所有的链接库指定到一个变量中
# step1.先将可执行文件所有需要添加的库,指定到一个变量中
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_core)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_imgproc)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_imgcodecs)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC opencv_highgui)
list(APPEND REDIS_TEST_LINK_LIB PUBLIC caffe)
# step2.然后直接在target_link_libraries中添加上面的变量即可
target_link_libraries(redis_test ${REDIS_TEST_LINK_LIB}) #参数1:目标文件;参数2:指定的链接库
# 结论:这里推荐第2种方式,这种方式比较清晰明了,可执行需要用到什么链接库直接list增加即可,增删都比较清楚
# 方法1这种方式,当链接库比较多时,会看起来比较杂乱,不容易维护,漏掉了链接库也不太好查看。
三、设置头文件目录和链接库文件目录的两种方式
结论:个人一般使用的方法2,因为方法1的方式经常会找不到依赖包(当依赖包没有安装系统默认环境下时)。
方式1:通过find的方式在系统的几个默认路径中寻找
方式1.通过find的方式在系统的几个默认路径中寻找
# find_package查找依赖包.
# (理想情况下find_package()能够把依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到,后续只管用就好了。
# 但实际中往往CMake失败就是出在find_package()的失败上,find_package往往会找不到依赖包或找到的版本不是我们想要的.
# 因此,我一般直接手动指定头文件和库文件路径)
find_package(BLAS REQUIRED)
# find_path会在系统几个默认路径下寻找指定头文件,如果找到了,将路径保存到参数1中
find_path(CURL_INCLUDE_DIR curl.h
HINTS /data_1/Clion_project/3rdparty/curl/include/curl
PATH_SUFFIXES include) # 寻找curl.h的路径,HINTS:指定推荐的路径,PATH_SUFFIXES:增加路径下的子文件夹搜索
# find_library查找指定的库文件
find_library(CURL_LIBRARIES curl
HINTS /data_1/Clion_project/3rdparty/curl
PATH_SUFFIXES lib lib64)
方法2:手动指定头文件和库文件路径
# 设置包含(头文件)目录
include_directories(${CAFFE_ROOT}/include) #PROJECT_SOURCE_DIR指当前CMakeLists.txt的文件夹路径
# 设置连接库文件目录(lib)
link_directories(${CAFFE_ROOT}/lib)
四、使用.cmake文件实现模块化
1、dependencies.cmake文件
第一步,可以将项目需要用到的依赖包全部在dependencies.cmake文件中导入,这样可以使CMakeLists.txt中更加简洁清爽,避免一堆指令堆杂在一起。
#dependencies.cmake文件
# caffe
set(CAFFE_ROOT ${CMAKE_SOURCE_DIR}/3rdparty/caffe) #CMAKE_SOURCE_DIR表示最顶层CMakeLists.txt的文件夹路径
include_directories(${CAFFE_ROOT}/include) #PROJECT_SOURCE_DIR指当前CMakeLists.txt的文件夹路径
link_directories(${CAFFE_ROOT}/lib)
# cuda
include_directories(${CMAKE_SOURCE_DIR}/3rdparty/cuda/include)
link_directories(${CMAKE_SOURCE_DIR}/3rdparty/cuda/lib)
link_directories(${CMAKE_SOURCE_DIR}/3rdparty/cuda/lib/stubs)
# protobuf
set(PROTOBUF_ROOT ${CMAKE_SOURCE_DIR}/3rdparty/protobuf)
include_directories(${PROTOBUF_ROOT}/include)
link_directories(${PROTOBUF_ROOT}/lib)
第二步,在CMakeLists.txt中直接include上面的dependencies.cmake即可。
# CMakeLists.txt文件
# include Dependencies
include(cmake/Dependencies.cmake)
五、 多个目录,多个cmakelist源文件联合使用
#目录结构
#./demo/
# ./CMakeLists.txt
# ./main.cpp
# ./math/src/
# ./CMakeLists.txt
# ./math.cpp
# 根目录下CMakeLists.txt如下
# 添加./math/src子目录
add_subdirectory(math/src) #add_subdirectory指明本项目包含一个子目录/math/src,这样子目录下的CMakeLists.txt文件和源代码也会被处理
# ./math/src 目录下的CMakeLists.txt文件如下:
aux_source_directory(. DIR_LIB_SRCS)
add_library(MathFunctions ${DIR_LIB_SRCS})