利用cmake构建C++应用程序

利用cmake构建C++应用程序

参考资料:

  1. cmake语法讲解和入门示例
  2. 使用cmkae构建简单qt工程
  3. 浅谈 qmake 之 shadow build
  4. 如何编写cmakelists.txt文件
  5. cmake参考手册
  6. makefile经典教程

使用qt构建cmake程序的问题?出现“Parse error. Expected a command name, got unquoted argument with text”错误,这个是由于CMakeLists.txt文件的编码被无意之中改变导致的。在qtcreator中选择CMakeLists.txt文件,右键用binary格式打开:

利用cmake构建C++应用程序_第1张图片

正常的文件格式应该为:

利用cmake构建C++应用程序_第2张图片

如果发现在cmake前面有其他的字符,比如ef,bf之类的,说明文件格式已经被修改为其他格式了,此时需要修改文件的编码格式!一种方法是在qtcreator中找到选项,文本编辑,行为,文件编码,将文件编码设置为UTF-8编码格式;另一种方法是复制CMakeLists.txt中的文本内容,然后清空文本保存,会提示你空文本不能保存,此时输入任意一个字符再保存,会发现前面的编码识别字符已经不见了,此时再粘贴之前复制的文本回来,就再次找回了原来的编码!

cmake构建C++应用程序示例=>

#指定cmake最小版本
cmake_minimum_required(VERSION 2.8)

#指定项目名称
project(linux_rdma_server)

#设置C++编译器和添加编译器选项
set(CMAKE_CXX_COMPILER g++)
add_compile_options(-std=c++11)

#设置编译模式
#set(CMAKE_BUILD_TYPE "Release")
#cmake -DCMAKE_BUILD_TYPE=Debug

#根据不同的编译模式设置不同的生成路径
IF (CMAKE_BUILD_TYPE MATCHES "Release")
    message("set CMAKE_BUILD_TYPE = Release")
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/release)
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/release)
ELSEIF (CMAKE_BUILD_TYPE MATCHES "MinSizeRel")
    message("set CMAKE_BUILD_TYPE = MinSizeRel")
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/minSizeRel)
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/minSizeRel)
ELSEIF(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
    message("set CMAKE_BUILD_TYPE = RelWithDebInfo")
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/relWithDebInfo)
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/relWithDebInfo)
ELSEIF(CMAKE_BUILD_TYPE MATCHES "Debug")
    message("set CMAKE_BUILD_TYPE = Debug")
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug)
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/debug)
ELSE()
    message("set CMAKE_BUILD_TYPE = Default")
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/default)
    set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/default)
ENDIF()

#重置动态库查找目录
#如果使用了其他第三方库,不必在linux系统安装第三方库
#拷贝动态库文件到本地目录,加上下面几句即可解决!!!
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "$ORIGIN")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TURE)

#设置自定义变量并根据变量参数设置不同的编译选项
set(USE_CAMERA_TEST "YES")
IF (USE_CAMERA_TEST MATCHES "YES")
    message("Set USE_CAMERA_TEST = YES")
ELSE()
    message("set USE_CAMERA_TEST = NO")
ENDIF()

#添加预定义指令,每条指令前都需要加上-D,之后才是预定义名称
#预定义指令可以在程序中识别,使用#ifdef RDMA_DEBUG 即可!!!
add_definitions(-DRDMA_DEBUG)

#添加源文件路径,使用cpplib替换./cpplib名称
aux_source_directory(./cpplib cpplib)

#包含子项目路径,子项目中的cmakelist.txt文件会被自动识别
add_subdirectory(cpplib)

#添加头文件路径
include_directories(./rdma_server)
include_directories(./cpplib)

#生成动态库,包含所有需要编译的文件,注意,这里只需要包含.cpp文件,.h和.hpp文件可以选择不包含
ADD_LIBRARY(rdma_server SHARED
    cpplib/cpplogger.cpp
    cpplib/cppfilesystem.cpp
    rdma_server/rdma_server.cpp)

#生成执行文件,同样包含所有需要编译的文件
ADD_EXECUTABLE(rdma_server_test
    rdma_server_test/main.cpp)

#将动态库连接到指定的应用程序上,最紧密的依赖库在前,间接依赖库在后
target_link_libraries(rdma_server ibverbs rdmacm pthread)
target_link_libraries(rdma_server_test rdma_server ibverbs rdmacm pthread)

#拷贝文件或文件夹到目标程序生成目录,执行cmake的时候就会执行拷贝
file(COPY "rdma_camera_test/copy_files" DESTINATION ${EXECUTABLE_OUTPUT_PATH})
file(COPY "rdma_camera_test/settings.cfg" DESTINATION ${EXECUTABLE_OUTPUT_PATH})

#注意链接动态库设置:
#1) target_link_libraries(rdma_server ibverbs rdmacm pthread)
#2) target_link_libraries(rdma_server_test rdma_server ibverbs rdmacm pthread)
#这里曾经踩过一个坑:只设置了2,未设置1,导致在运行时出现segment faul错误,
#排查原因是因为rdma_server_test被设置了link库,但rdma_server这个库并没有。
#因此我们需要给每个library和execute都设置like库,否则运行时就会报告segment fault错误!!!

针对上面的cmake编写的自动编译生成bash文件=>

#!/bin/sh

if [ ! -d "build" ]; then
  echo "creat build directory"
  mkdir build
fi


echo "================= debug build ================="
if [ ! -d "build/debug" ]; then
  echo "creat debug directory"
  mkdir build/debug
fi
cd build/debug
cmake -D CMAKE_BUILD_TYPE=Debug ../..
make


cd ../..
echo "================= release build ================="
if [ ! -d "build/release" ]; then
  echo "creat release directory"
  mkdir build/release
fi
cd build/release
cmake -D CMAKE_BUILD_TYPE=Release ../..
make


echo "================= build complete ================="

你可能感兴趣的:(C)