为什么使用CMake
CMake是跨平台的构建工具,公司主要使用这个工具生成,掌握了CMake用法觉得自动化构建还是很容易的
cmake使用方法
1.基本结构
1 2 3 4 5 6 7 8
| - project - includes - CMakeLists.txt - *.h - src - CMakeLists.txt - *.cc - CMakeLists.txt
|
- 依赖CMakeLists.txt文件,项目主目标一个,主目录可指定包含的子目录
- 在项目CMakeLists.txt中使用project指定项目名称,add_subdirectory添加子目录
- 子目录CMakeLists.txt从父目录CMakeLists.txt继承设置
2.语法
1 2 3 4 5 6 7
| if(var) ... elseif() ... else() ... endif()
|
1 2 3 4 5 6 7 8 9 10
| 第一种: set(var a b c) foreach(f ${var}) ... endforeach(f)
第二种: while() ... endwhile()
|
3.内部变量
1 2 3 4 5 6 7
| 1. CMAKE_C_COMPILER/CMAKE_CXX_COMPILER 指定C/C++编译器 2. CMAKE_C_FLAGS/CMAKE_CXX_FLAGS 设置C/C++编译参数 3. EXECUTABLE_OUTPUT_PATH 可执行文件的存放路径 4. LIBRARY_OUTPUT_PATH 库文件存放路径 5. CMAKE_BUILD_TYPE 编译类型(Debug,Release) 6. BUILD_SHARED_LIBS 编译动态链接库(ON,OFF)
|
4.命令(不分大小写)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| project( test )
include_directories
link_directories
add_subdirectory
add_executable
add_definitions
target_link_libraries
add_library
add_custom_target
set_target_properties
link_libraries(lib1 lib2 )
|
5.其他
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 1. MESSAGE({SEND_ERROR|STATUS|FATAL_ERROR} "this is message")
2. AUX_SOURCE_DIRECTORIES
3. FILE(GLOB SRC_FILES RELATIVE ${CMAKE_CURRENT_SOUCE_DIR} *.cpp)
4. FIND_LIBRARY(Boost COMPONENTS thread system log REQUIRED)
5. OPTION 条件编译 OPTION(DEBUG_mode "this is debug." ON) IF(DEBUG_mode) add_definitions(-DDEBUG) ENDIF() 6. ADD_DEPENDENCIES 添加编译依赖项
7. SET_TARGET_PROPERTIES 设置目标文件目录
8. CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 设置cmake最小版本
9. LESS,GREATER,EQUAL 数字比较
10.STRLESS、STRGREATER、STREQUAL 字符串比较
|
6.C++ Server组使用范例
workspace
- CMakeLists.txt #根目录cmake file
- common_inc #头文件
- common_lib #库文件
编译common库
- add_subdirectory(stt_common/branch/1.0)
- add_subdirectory(stt_msgbus/branch/1.0_cluster)
- add_subdirectory(stt_dy_common/trunk)
编译具体项目
- add_subdirectory(stt_dy_chatroom/trunk)
Win平台使用CMake
- 像大多数开源软件一样,CMake和Unix/Linux的结合比Win好多了
- 在Win下使用比较麻烦,当然这只是在链接各种第三方库的情况下
- 而我们一般都在使用各种第三方库的情况下,CMake才比VS有优势
- 下面将以CMake链接Boost的一个项目作为示例
语法规则
- CMake的内建命令大部分都是通用的,但是对于Win下使用VS的编译器来说,需要注意以下几点:
- 必须定义CMAKE_CXX_COMPILER为cl
- 最好使用/EHsc的定义来避免链接的过程失败,因为VS有自己的安全检查方法
- 可以使用WinDbg来确定可执行文件的依赖,然后针对性去除多余的LINK_LIBRARIES
- 生成MakeFile或者VS的工程需要定义好平台架构,默认是x86,还可以定义Win64和arm,可以参阅cmake帮助
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream>
#include <boost/thread.hpp> #include <boost/asio.hpp> #include <boost/timer.hpp> #include <boost/ref.hpp> #include <boost/bind.hpp>
void test_timer(const boost::system::error_code& ec,boost::asio::deadline_timer& t,int& count) { if(!ec){ if(count++==5) return; t.expires_from_now(boost::posix_time::seconds(1)); t.async_wait(boost::bind(&test_timer,boost::asio::placeholders::error, boost::ref(t),boost::ref(count))); std::cout<<"working\n"; } }
int main(int argc, char const *argv[]) { boost::asio::io_service io; int count = 0; boost::asio::deadline_timer tm(io); tm.expires_from_now(boost::posix_time::seconds(1)); tm.async_wait(boost::bind(test_timer,boost::asio::placeholders::error, boost::ref(tm),boost::ref(count))); io.run(); return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| cmake_minimum_required(VERSION 2.8) set(CMAKE_CXX_COMPILER "cl") set(CMAKE_CXX_FLAGS "/O2") add_definitions("/EHsc")
include_directories( D:\\boost_1_60_0 )
link_directories( D:\\boost_1_60_0\\lib64-msvc-14.0 )
link_libraries( boost_thread-vc140-mt-1_60 boost_system-vc140-mt-1_60 )
add_executable(test_vc 1.cc)
|
1 2 3 4 5 6 7 8
| //生成VS2015 64位的应用,默认是x86 cmake -G "Visual Studio 14 2015 Win64" . //VS编译打开目录下的解决方案,编译即可
//nmake使用,在有外部链接库的时候容易失败 cmake -G "NMake Makefiles" . //找到对应平台的nmake命令,一定要一致 nmake
|