我是靠谱客的博主 含糊糖豆,最近开发中收集的这篇文章主要介绍CMake笔记相关命令CMake教程编译错误记录,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

相关命令

#运行当前目录下的cmake文件
cmake . 
#运行父目录下的cmake文件,并在当前目录生成相关文件,通常位于build文件夹
cmake ..
#执行makefile
make
#删除make出的elf文件
make clean

CMake教程

简例

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目名称
project (echo)

# 指定生成目标,包含所有源文件
add_executable(echo main.cc echo.cc)

#链接库文件(静态或动态,被库文件依赖的库文件放后面),
target_link_libraries (${PROJECT_NAME} muduo_net muduo_base pthread )

target_link_libraries默认寻找默认路径中的库,需要放在add_executable后面。

链接库

在CMakeLists.txt如果需要使用第三方库,那么需要知道三个东西

去哪里找头文件(.h等)对应于GCC的参数 -I
去哪里找库文件(.so/.lib/.ddl等)对应于GCC的参数 -L
需要链接的库文件名称对应于GCC的参数 -l

比如我需要链接第三方库curl,那么在CMakeLists.txt中可以书写如下:

include_directories(include路径) # 对应于-I
link_directories(lib路径) # 对应于-L
target_link_libraries(target curl) # 对应于-l

或者使用find_package

find_package

find_package的作用就是去寻找该库的头文件位置、库文件位置以及库文件名称,并将其设为变量,返回提供给CMakeLists.txt其他部分使用。

例如:

find_package(curl REQUIRED)
include_directories(${CURL_INCLUDE_DIR})
target_link_libraries(curltest ${CURL_LIBRARY})

REQUIRED选项可选,当找不到模块时报错。

find_package会去 ${CMAKE_MODULE_PATH}的所有路径中去寻找FindCURL.cmake(一般会去查找Find<name>.cmake这种格式),并执行FindCURL.cmake里的代码。

实际上,find_package寻找.cmake文件的搜索规则为

  1. ${CMAKE_MODULE_PATH},该变量是CMake默认自带的一个路径,也可以通过语句添加自己的CMake的模块搜索路径,如:

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") 
    # CMAKE_SOURCE_DIR是项目根目录
    
  2. /usr/share/cmake-x.y/Modules/

  3. 如果Find<name>.cmake文件未找到,它将会尝试在系统路径中查找 <Name>Config.cmake<lower-case-name>-config.cmake 文件。这两个文件是库文件安装时自己安装的,将自己的路径硬编码到其中。前者称为 module 模式,后者称为 config 模式。

通常FindCURL.cmake文件会提供以下几个变量:

  • <name>_FOUND => 表明是否查找到
  • <name>_INCLUDE_DIR<name>_INCLUDES => 表示头文件位置
  • <name>_LIBRARY<name>_LIBRARIES<name>_LIBS => 表示库文件路径+名称
  • <name>_DEFINITIONS

转自:http://ruiy.leanote.com/post/find_package%E7%9A%84%E4%BD%9C%E7%94%A8

注:find_package想要找到spdlog静态库,需要在spdlog项目cmake.make后使用sudo make install(卸载使用sudo make uninstall),自动在指定系统目录生成cmake文件,供find_package使用。其他库文件同理。

<Packagename>_FOUND可以用来判断该库文件是否被找到:

find_package(spdlog)

if(spdlog_FOUND)
    target_link_libraries(lib_utility spdlog::spdlog pthread)
    message("spdlog lib was found.")
else()
    target_link_libraries(lib_utility pthread)
    message("spdlog lib not found.")
endif()

其他

添加编译选项

add_compile_options(-std=c++11 -Wall) 

设置输出路径

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

不同目录下多个源文件

当程序文件比较多时,我们会进行分类管理,把代码根据功能放在不同的目录下,这样方便查找。

整体文件结构如下:
这里写图片描述

cmake_minimum_required (VERSION 2.8)

project (demo)

include_directories (test_func test_func1)

aux_source_directory (test_func SRC_LIST)
aux_source_directory (test_func1 SRC_LIST1)

add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})

SET_TARGET_PROPERTIES

语法:

set_target_properties(target1 target2 ...
                      PROPERTIES prop1 value1
                      prop2 value2 ...)

用来设置目标的属性。

示例:

SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

编译错误记录

recompile with -fPIC

[ 86%] Linking CXX shared library librocksdb.so
/usr/bin/ld: /usr/local/lib/libgflags.a(gflags.cc.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: 最后的链结失败: 错误的值
collect2: error: ld returned 1 exit status
CMakeFiles/rocksdb-shared.dir/build.make:4484: recipe for target 'librocksdb.so.6.20.3' failed

原因:gflags库编译时未使用-fPIC参数。
解决办法:

  • 对于./configure可以在编译时直接输入命令"CFLAGS=-fPIC" ./configure
  • 对于cmake生成的makefile则可以在CMakeList.txt中加上add_compile_options(-fPIC)

参考资料:

https://blog.csdn.net/whahu1989/article/details/82078563
http://ruiy.leanote.com/post/find_package%E7%9A%84%E4%BD%9C%E7%94%A8

最后

以上就是含糊糖豆为你收集整理的CMake笔记相关命令CMake教程编译错误记录的全部内容,希望文章能够帮你解决CMake笔记相关命令CMake教程编译错误记录所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部