cmake多目录,生成so的模板

什么是CMake

  你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。

  CMake就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的CMakeLists.txt文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化Makefile和工程文件,如Unix的Makefile或Windows的Visual Studio工程。从而做到"Write once, run everywhere"。显然,CMake是一个比上述几种make更高级的编译配置工具。

  在linux平台下使用CMake生成Makefile并编译的流程如下:

  1、编写CMake配置文件CMakeLists.txt

  2、执行命令cmake PATH,其中PATH是CMakeLists.txt所在的目录。

  3、使用make命令进行编译。

  一个通用的模板如下。

源码目录结构

├── CMakeLists.txt     根目录cmakelists.t
├── math
│   ├── inc
│    │    ├── MathFunctions.h
│   ├── src
│    │    ├── MathFunctions.cc
│   └── CMakeLists.txt 子目录cmakelists.txt
├── main.c  main函数
└── README.md

源码

根目录CMakeLists.txt

#-------------------------------------------------------------------------------
# File: CMakeLists.txt
# Description: CMake Configuration File
#-------------------------------------------------------------------------------
# CMake最低版本要求
cmake_minimum_required(VERSION 2.8)
# 项目名称
project(Template)

#-------------------------------------------------------------------------------
# project setting
#-------------------------------------------------------------------------------
# setting for compiling in debug or release mode
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
  message(STATUS "Release版本")
  set(BuildType "Release")
else()
  message(STATUS "Debug版本")
  set(BuildType "Debug")
endif()

# 设置bin和lib库目录
# PROJECT_SOURCE_DIR为cmake内置变量,表示工程的根目录
set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
# debug和release版本目录不一样
# LIBRARY_OUTPUT_PATH为cmake内置变量,表示目标链接库文件的存放位置
set(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType})
set(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType})

#-----------------------------------------------------------------------------
# compile setting
#-----------------------------------------------------------------------------
# 设置编译选项
# -fPIC:标识编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的
# add_compile_options是针对所有类型编译器的
add_compile_options(-fPIC)
# 设置c++编译器编译选项        
set(CXX_FLAGS
  -std=c++11
  -Wno-overflow
  -Wno-conversion-null
  -Wno-maybe-uninitialized
  -Wno-uninitialized
  -Wno-sequence-point
  -Wno-write-strings
  -Wno-unused-label
  -Wno-unused-variable
  -Wno-unused-variable
  -Wno-cpp
  -Wno-deprecated
  -Wno-unused-but-set-variable -pthread)

# string(REPLACE <match-string> <replace-string> <out-var> <input>...)
# 替换CXX_FLAGS变量中的;字符为空格,然后写入CMAKE_CXX_FLAGS,CMAKE_CXX_FLAGS为cmake内置变量,用于设置C++编译选项
string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CXX_FLAGS}")
# CMAKE_CXX_COMPILER为cmake内置变量,用于指定gcc,g++版本编译
set(CMAKE_CXX_COMPILER "g++")
# 指定Debug模式下编译选项,CMAKE_CXX_FLAGS_DEBUG为cmake内置变量
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
# 指定Release模式下编译选项,CMAKE_CXX_FLAGS_RELEASE为cmake内置变量
# -g表示添加gdb调试选项
set(CMAKE_CXX_FLAGS_RELEASE "-g -O2 -finline-limit=1000")


MESSAGE(STATUS "CMAKE_BUILD_TYPE : ${CMAKE_BUILD_TYPE}")
IF( "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    MESSAGE(STATUS "CMAKE_CXX_FLAGS : ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS}")
ELSE()
    MESSAGE(STATUS "CMAKE_CXX_FLAGS : ${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS}")
ENDIF()

#-------------------------------------------------------------------------------
# thirdparty dependencies
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# project generation
#-------------------------------------------------------------------------------

# 查找当前目录下的所有源文件
# 并将名称保存到DIR_SRCS 变量中
aux_source_directory(. DIR_SRCS)
# 向当前工程添加存放源文件的子目录
# 注意,该子目录中须包含CMakeList.txt文件
add_subdirectory(math)
# 添加当前编译目标使用到的头文件搜索路径,多个路径之间用空格分隔
# 如果路径包含空格,可以使用双引号将它括起来
include_directories("${PROJECT_SOURCE_DIR}/math/inc")
# 指定生成目标
add_executable(dynamic main.cc)
# 添加链接库
target_link_libraries(dynamic mathLib)

子目录CMakeLists.txt

# 设置release版本还是debug版本
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
    message(STATUS "Release版本")
    set(BuildType "Release")
else()
    set(BuildType "Debug")
    message(STATUS "Debug版本")
endif()

#设置lib库目录
set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
# debug和release版本目录不一样
#设置生成的so动态库最后输出的路径
set(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/linux/${BuildType})
add_compile_options(-fPIC)

# 查找src目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(src DIR_LIB_SRCS)
# 添加当前编译目标使用到的头文件搜索路径,多个路径之间用空格分隔
# 如果路径包含空格,可以使用双引号将它括起来
include_directories("${PROJECT_SOURCE_DIR}/math/inc")
# 生成动态库
add_library (mathLib SHARED  ${DIR_LIB_SRCS})

 

posted @ 2021-01-20 20:31  阿玛尼迪迪  阅读(1242)  评论(0编辑  收藏  举报