CMAKE学习记录

cmake和autotools是makefile的上层工具,它们的目的是为了产生可移植的makefile,并简化自己动手写makefile时的巨大工作量。

RPATH、RUNPATH、LD_LIBRARY_PATH三者之间,优先级为RPATH > LD_LIBRARY_PATH > RUNPATH。
当RUNPATH存在时,则RPATH失效。
RUNPATH不适用于间接依赖的库。
使用RUNPATH时,可能需要配合使用LD_LIBRARY_PATH来指定依赖库文件的路径。

静态库test1

root@ubuntu:/home/xxxx/test/CMakeTest/static1# cat CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
set(CMAKE_INSTALL_PREFIX /tangtest)
PROJECT(Static1)
#set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-std=c++11")

#指定目录,编译该目录下所有cpp文件
#AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
#ADD_LIBRARY ( test1 ${DIR_TEST1_SRCS})

#指定文件进行编译
set(SRC_LIST test1.cpp)
add_library(test1 STATIC ${SRC_LIST})
install(TARGETS test1 DESTINATION lib)
install(FILES test1.h DESTINATION include)

动态库test2

root@ubuntu:/home/xxxx/test/CMakeTest/static1# cat CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
set(CMAKE_INSTALL_PREFIX /tangtest)
PROJECT(Static1)
#set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-std=c++11")

#指定目录,编译该目录下所有cpp文件
#AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
#ADD_LIBRARY ( test1 ${DIR_TEST1_SRCS})

#指定文件进行编译
set(SRC_LIST test1.cpp)
add_library(test1 STATIC ${SRC_LIST})
install(TARGETS test1 DESTINATION lib)
install(FILES test1.h DESTINATION include)
root@ubuntu:/home/xxxx/test/CMakeTest/static1# cd ../../
root@ubuntu:/home/xxxx/test# cat static2/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

set(CMAKE_INSTALL_PREFIX /tangtest)

PROJECT(Test2)
#set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-std=c++11")

#指定目录,编译该目录下所有cpp文件
#AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
#ADD_LIBRARY ( test1 ${DIR_TEST1_SRCS})

#指定文件进行编译
set(SRC_LIST test2.cpp)
#add_library(test2 STATIC ${SRC_LIST})
add_library(test2 SHARED ${SRC_LIST})

#VERSION 指代动态库版本,SOVERSION 指代 API 版本
SET_TARGET_PROPERTIES(test2 PROPERTIES VERSION 1.2 SOVERSION 1)

install(TARGETS test2 DESTINATION lib)
install(FILES test2.h DESTINATION include)

主程序

#cmake最低版本需求,不加入此行会受到警告信息
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

set(CMAKE_INSTALL_PREFIX /tangtest)

#设置运行时动态库的加载路径,另一种设置使用SET_TARGET_PROPERTIES(tang PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
#set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

#在环境(cmake version 2.8.12.2, g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4) 上验证只能使用CMAKE_CXX_FLAGS设置C++11,使用CMAKE_CXX_STANDARD编译会出错
#set(cmake_cxx_sTANDARD 11)
#set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_FLAGS "-std=c++11")

PROJECT(TANG) #项目名称
#项目名称隐式指定了下面两个变量
MESSAGE(${TANG_BINARY_DIR})#/home/xxx/test/CMakeTest/build
MESSAGE(${TANG_SOURCE_DIR})#/home/xxx/test/CMakeTest

#下面两个变量跟工程名无关,比TANG_BINARY_DIR和TANG_SOURCE_DIR更好用
MESSAGE(${PROJECT_BINARY_DIR})
MESSAGE(${PROJECT_SOURCE_DIR})

#通过修改内置变量EXECUTABLE_OUTPUT_PATH,LIBRARY_OUTPUT_PATH 可以更改可执行程序和库的生成目录
#SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#没有set之前EXECUTABLE_OUTPUT_PATH,LIBRARY_OUTPUT_PATH是没有定义的不可输出
#MESSAGE(${EXECUTABLE_OUTPUT_PATH})
#MESSAGE(${LIBRARY_OUTPUT_PATH})

#指定编译的子目录,子目录里面可以是这个主程序的代码文件,也可以是单独一个库的代码(包含自己的CMkeList.txt)
#默认编译后生成的中间文件和结果文件在build/static1目录下。
#add_subdirectory(static1)
add_subdirectory(static1 /${PROJECT_SOURCE_DIR}/lib/tmp)
#add_subdirectory(static1 ${PROJECT_SOURCE_DIR}/lib/tmp EXCLUDE_FROM_ALL)

#指定外部库的链接路径,必须是在ADD_EXECUTABLE之前指定
#link_directories("${CMAKE_SOURCE_DIR}/../static/")
link_directories("${CMAKE_INSTALL_PREFIX}/lib")

#把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
#AUX_SOURCE_DIRECTORY(. SRC_LIST)

#编译当前目录和子目录的指定cpp
set(SRC_LIST test.cpp src/test0.cpp)

#生成应用程序 tang,工程名的 TANG 和生成的可执行文件 tang 是没有任何关系的
ADD_EXECUTABLE(tang ${SRC_LIST})
#修改输出的名字
SET_TARGET_PROPERTIES(tang PROPERTIES OUTPUT_NAME "HelloTest")
SET_TARGET_PROPERTIES(tang PROPERTIES INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")#同set(CMAKE_INSTALL_RPATH ..)

#对tang这个住程序添加包含路径
#target_include_directories(tang PUBLIC ${CMAKE_SOURCE_DIR}/../static)
target_include_directories(tang PUBLIC ${CMAKE_INSTALL_PREFIX}/include)

#链接库,必须是在ADD_EXECUTABLE之后,因为之前生成的可执行程序名tang还不存在
#TARGET_LINK_LIBRARIES( tang test1 )#test1是通过编译时指定ADD_SUBDIRECTORY使编译主程序的同时编译test1静态库,test1编译之后会在主程序的build目录自动生成test1的编译中间文件和库文件,所以链接时不需要显示指定链接目录,主程序会自动到ADD_SUBDIRECTORY指定的子目录去链接

TARGET_LINK_LIBRARIES( tang test1 test2 )#test2是外部编译好的库,需要通过link_directories显示引入库的路径

打包

# 指定deb包的版本号
set(_VERSION_MAJOR 1)
set(_VERSION_MINOR 2)
set(_VERSION_PATCH 3)
set(CPACK_PACKAGE_VERSION_MAJOR "${_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${_VERSION_PATCH}")

# 指定CPack生成的是deb包(还可以是其他包如 <.7z> <.zip> 等)
set(CPACK_GENERATOR "DEB")

# 指定打包后生成的包名
set(CPACK_PACKAGE_NAME "tang-cmake-test")
# 指定安装后的包名
set(CPACK_DEBIAN_PACKAGE_NAME "tang-cmake-test")
# 指定运行的计算机架构
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
# 指定所需的依赖
# set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc")
# 设置包作者的联系方式
set(CPACK_PACKAGE_CONTACT "tang@quanshi.com")
# 设置维护人
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "tang@quanshi.cn")

#生成之后安装
install(TARGETS tang DESTINATION bin)
install(DIRECTORY conf/ DESTINATION conf)
install(PROGRAMS test.sh DESTINATION bin)

include(CPack)

执行:

root@ubuntu:/home/xxx/test/CMakeTest/build# cmake ..

root@ubuntu:/home/xxx/test/CMakeTest/build# make 

root@ubuntu:/home/xxx/test/CMakeTest/build# make package

生成包 /home/xxx/test/CMakeTest/build/tang-cmake-test-1.2.3-Linux.deb

查看包安装的内容:

root@ubuntu:/home/xxx/test/CMakeTest/build# dpkg -c /home/xxx/test/CMakeTest/build/tang-cmake-test-1.2.3-Linux.deb
drwxr-xr-x root/root 0 2023-01-13 18:48 ./usr/
drwxr-xr-x root/root 0 2023-01-13 18:48 ./usr/conf/
-rw-r--r-- root/root 15 2023-01-13 17:33 ./usr/conf/test.conf
drwxr-xr-x root/root 0 2023-01-13 18:48 ./usr/bin/
-rwxr-xr-x root/root 5 2023-01-13 17:38 ./usr/bin/test.sh
-rwxr-xr-x root/root 9091 2023-01-13 17:54 ./usr/bin/HelloTest
drwxr-xr-x root/root 0 2023-01-13 18:48 ./usr/lib/
-rw-r--r-- root/root 1844 2023-01-13 17:52 ./usr/lib/libtest1.a
drwxr-xr-x root/root 0 2023-01-13 18:48 ./usr/include/
-rw-r--r-- root/root 363 2023-01-13 10:47 ./usr/include/test1.h

CMAKE_CXX_FLAGS "-std=c++11"

在有的 ubuntu 14,使用 set(CMAKE_CXX_STANDARD 11) 编译出错

error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \

改用 set(CMAKE_CXX_FLAGS "-std=c++11") 之后编译通过

cmake常见的变量(即选项)

  • CMAKE_CXX_STANDARD变量增加c++11标准:set(CMAKE_CXX_STANDARD 11)
    CMAKE_CXX_FLAGS变量增加pthread支持:set(CMAKE_CXX_FLAGS -pthread)
    CMAKE_CXX_FLAGS为多个选项:set(CMAKE_CXX_FLAGS "-pthread -g -Wall")
    CMAKE_CXX_FLAGS变量让程序先找当前目录:set(CMAKE_CXX_FLAGS "-Wl,-rpath=.")

VERSION 指代动态库版本,SOVERSION 指代 API 版本
SET_TARGET_PROPERTIES(test2 PROPERTIES VERSION 1.2 SOVERSION 1)

root@ubuntu:/home/xxx/test/static2/build# ll
total 52
drwxr-xr-x 3 root root 4096 Jan 16 10:00 ./
drwxr-xr-x 3 root root 4096 Jan 16 09:59 ../
-rw-r--r-- 1 root root 11994 Jan 13 17:02 CMakeCache.txt
drwxr-xr-x 5 root root 4096 Jan 16 10:00 CMakeFiles/
-rw-r--r-- 1 root root 3110 Jan 16 10:00 cmake_install.cmake
-rw-r--r-- 1 root root 52 Jan 13 17:04 install_manifest.txt
lrwxrwxrwx 1 root root 13 Jan 16 10:00 libtest2.so -> libtest2.so.1*
lrwxrwxrwx 1 root root 15 Jan 16 10:00 libtest2.so.1 -> libtest2.so.1.2*
-rwxr-xr-x 1 root root 8207 Jan 16 10:00 libtest2.so.1.2*

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tangcpp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值