cmake手册

 

目录

 

1.cmake与CMakeLists.txt

1.1 cmake 

1.2 CMakeLists.txt

2.CMakeLists.txt中常用指令(阿飞的链接)

2.1 指定最小版本

2.2 设置项目名称

2.3 设置编译类型

2.4 指定编译包含的源文件

2.4.1 明确指定包含哪些源文件

2.4.2 搜索所有的 cpp 文件

2.4.3 自定义搜索规则

2.5 查找指定的库文件

2.6  设置包含的目录

2.7 设置链接库搜索目录

2.8 设置 target 需要链接的库

2.8.1 指定链接动态库或静态库

2.8.2 指定全路径

2.8.3 指定链接多个库 

2.9 设置变量

2.9.1 set 直接设置变量的值

2.9.2 set 追加设置变量的值

2.9.3 list 追加或者删除变量的值

2.10 条件控制

2.10.1 if…elseif…else…endif

2.10.2 while…endwhile

2.10.3  foreach…endforeach

2.11 打印信息

2.12  包含其它 cmake 文件

3.CMakeLists.txt中的常用变量

3.1 预定义变量

3.2 环境变量

3.3 系统信息

3.4 主要开关选项

4.项目示例

4.1 最简单的hello world

4.2 一个稍微复杂一点的项目(多个目录,多个源文件,多个项目)

4.3 自定义编译选项

4.4 开源项目实践


0.makefile

Makefile文件教程(一)--阅读链接

"undefined reference to" 问题解决方法

1.cmake与CMakeLists.txt

1.1 cmake 

cmake官方教程的链接

CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程),它能够输
出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 
CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 
Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使
用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台
的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。


“CMake”这个名字是“cross platform make”的缩写。虽然名字中含有“make”,但是CMake和Unix上常见的
“make”系统是分开的,而且更为高阶。

本质: 跨平台的安装(编译)工具
功能: 编译源代码、制作程式库
中文名:描述所有平台的安装(编译过程)
外文名:cross platform make

1.2 CMakeLists.txt

cmake工具会根据CMakeLists.txt中写的一些编译规则生成Makefile等文件.

2.CMakeLists.txt中常用指令(阿飞的链接)

2.1 指定最小版本

cmake_minimum_required(VERSION 3.4.1)

这行命令是可选的,我们可以不写这句话,在一些情况下,如果CMakeLists.txt
文件中使用了一些高版本cmake特有的一些命令的时候,就需要加上这样一行,
提醒用户升级到该版本之后再执行cmake.

2.2 设置项目名称

project(demo)

这个命令不是强制性的,建议加上,它会引入两个变量 demo_BINARY_DIR 和 demo_SOURCE_DIR,
同时,cmake 自动定义了两个等价的变量PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR.

2.3 设置编译类型

add_executable(demo demo.cpp)       #生成可执行文件
add_library(common STATIC util.cpp) #生成静态库
add_library(common SHARED util.cpp) #生成动态库或共享库

add_library 默认生成是静态库,通过以上命令生成文件名字.

在Linux下是:
demo
libcommon.a
libcommon.so

在Windows下是:
demo.exe
common.lib
common.dll

2.4 指定编译包含的源文件

2.4.1 明确指定包含哪些源文件

add_library(demo demo.cpp test.cpp util.cpp)

2.4.2 搜索所有的 cpp 文件

aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。

用法:
aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})

2.4.3 自定义搜索规则

file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

2.5 查找指定的库文件

find_library(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。
默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的 name 即可。


用例:
find_library( # Sets the name of the path variable.
              log-lib
 
              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

类似的命令还有 find_file()、find_path()、find_program()、find_package()

2.6  设置包含的目录

include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)


Linux 下还可以通过如下方式设置包含的目录:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")

2.7 设置链接库搜索目录

link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)


Linux 下还可以通过如下方式设置包含的目录:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")

2.8 设置 target 需要链接的库

target_link_libraries( # 目标库
                       demo
 
                       # 目标库需要链接的库
                       # log-lib 是上面 find_library 指定的变量名
                       ${log-lib} )


在 Windows 下,系统会根据链接库目录,搜索xxx.lib 文件,Linux 下会搜索 xxx.so 或者 xxx.a 文
件,如果都存在会优先链接动态库(so 后缀)。

2.8.1 指定链接动态库或静态库

target_link_libraries(demo libface.a) # 链接libface.a
target_link_libraries(demo libface.so) # 链接libface.so

2.8.2 指定全路径

target_link_libraries(demo libface.a) # 链接libface.a
target_link_libraries(demo libface.so) # 链接libface.so

2.8.3 指定链接多个库 

target_link_libraries(demo
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a
    boost_system.a
    boost_thread
    pthread)

2.9 设置变量

2.9.1 set 直接设置变量的值

set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})

2.9.2 set 追加设置变量的值

set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})

2.9.3 list 追加或者删除变量的值

set(SRC_LIST main.cpp)
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
add_executable(demo ${SRC_LIST})

2.10 条件控制

2.10.1 if…elseif…else…endif

逻辑判断和比较:
if (expression):expression 不为空(0,N,NO,OFF,FALSE,NOTFOUND)时为真
if (not exp):与上面相反
if (var1 AND var2)
if (var1 OR var2)
if (COMMAND cmd):如果 cmd 确实是命令并可调用为真
if (EXISTS dir) if (EXISTS file):如果目录或文件存在为真
if (file1 IS_NEWER_THAN file2):当 file1 比 file2 新,或 file1/file2 中有一个不存在时为真,文件名需使用全路径
if (IS_DIRECTORY dir):当 dir 是目录时为真
if (DEFINED var):如果变量被定义为真
if (var MATCHES regex):给定的变量或者字符串能够匹配正则表达式 regex 时为真,此处 var 可以用 var 名,也可以用 ${var}
if (string MATCHES regex)

数字比较:
if (variable LESS number):LESS 小于
if (string LESS number)
if (variable GREATER number):GREATER 大于
if (string GREATER number)
if (variable EQUAL number):EQUAL 等于
if (string EQUAL number)

字母表顺序比较:
if (variable STRLESS string)
if (string STRLESS string)
if (variable STRGREATER string)
if (string STRGREATER string)
if (variable STREQUAL string)
if (string STREQUAL string)



示例:
if(MSVC)
    set(LINK_LIBS common)
else()
    set(boost_thread boost_log.a boost_system.a)
endif()
target_link_libraries(demo ${LINK_LIBS})
# 或者
if(UNIX)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -g")
else()
    add_definitions(-D_SCL_SECURE_NO_WARNINGS
    D_CRT_SECURE_NO_WARNINGS
    -D_WIN32_WINNT=0x601
    -D_WINSOCK_DEPRECATED_NO_WARNINGS)
endif()
 
if(${CMAKE_BUILD_TYPE} MATCHES "debug")
    ...
else()
    ...
endif()

2.10.2 while…endwhile

while(condition)
    ...
endwhile()

2.10.3  foreach…endforeach

语法:
foreach(loop_var RANGE start stop [step])
    ...
endforeach(loop_var)


参数含义:start 表示起始数,stop 表示终止数,step 表示步长,

示例:
foreach(i RANGE 1 9 2)
    message(${i})
endforeach(i)
# 输出:13579

2.11 打印信息

message(${PROJECT_SOURCE_DIR})
message("build with debug mode")
message(WARNING "this is warnning message")
message(FATAL_ERROR "this build has many error") # FATAL_ERROR 会导致编译失败

2.12  包含其它 cmake 文件

include(./common.cmake) # 指定包含文件的全路径
include(def) # 在搜索路径中搜索def.cmake文件
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # 设置include的搜索路径

 

3.CMakeLists.txt中的常用变量

3.1 预定义变量

PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置

3.2 环境变量

使用环境变量:
 $ENV{Name}

写入环境变量:
 set(ENV{Name} value) # 这里没有“$”符号

3.3 系统信息

CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3
­CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4
­CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1
­CMAKE_SYSTEM:系统名称,比如 Linux-­2.6.22
­CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux
­CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22
­CMAKE_SYSTEM_PROCESSOR:处理器名称,比如 i686
­UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin
­WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin

3.4 主要开关选项

BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有
指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的
为动态库
CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加
CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加


add_definitions(-DENABLE_DEBUG -DABC) # 参数之间用空格分隔

4.项目示例

4.1 最简单的hello world

1.新建main.c;
2.源码同级目录下写CMakeLists.txt文件,设置编译的一些内容;
3.源码同级目录下创建目录build(mkdir build);
4.进入build目录(cd build);
5.执行cmake ..;(cmake ..表示到上级目录中寻找CMakeLists.txt并按照其指示的规则进行编译,
  此处此时生成Makefile等文件)
6.执行make -j8(表示用8个核心来编译,可根据自己的机器的情况制定参数,这个简单的小例子无所谓 啦);
7.发现在build目录下已经正常生成了可执行文件.


代码片段,main.c
#include <stdio.h>
int main() {
    printf("Hello World!\n");
    return 0;
}

CMakeLists.txt文件内容:
project(HELLO)
add_executable(hello main.c)


为什么要新建一个 build 文件夹?
一般我们采用cmake的out-of-source方式来构建(即生成的中间产物和源代码分离),这
样做可以让生成的文件和源文件不会弄混,且目录结构看起来也会清晰明了.所以推荐使
用这种方式,至于这个文件夹的命名并无限制,我们习惯命名为build.

4.2 一个稍微复杂一点的项目(多个目录,多个源文件,多个项目)

demo目录下有:
            CMakeLists.txt
            main.c
            math(文件夹)
 
            math目录下有:
                        CMakeLists.txt
                        MathFunctions.h
                        MathFunctions.cc

则demo根目录下面的CMakeLists.txt应该写成:
cmake_minimum_required (VERSION 2.8)
project(demo)
aux_source_directory(. DIR_SRCS)
# 添加math子目录
add_subdirectory(math)
# 指定生成目标
add_executable(demo ${DIR_SRCS})
# 添加链接库
target_link_libraries(demo MathFunctions)


math目录下的CMakeLists.txt应该写成:
aux_source_directory(. DIR_LIB_SRCS)
# 生成链接库
add_library(MathFunctions ${DIR_LIB_SRCS})

4.3 自定义编译选项

cmake 允许为项目增加编译选项,从而可以根据用户的环境和需求选择最合适的编译方案。
例如,可以将 MathFunctions 库设为一个可选的库,如果该选项为 ON ,就使用该库定义的数学函数来进行运算,否则就调用标准库中的数学函数库。
修改根目录下的 CMakeLists.txt 文件如下:


# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (Demo)
# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
    "${PROJECT_SOURCE_DIR}/config.h.in"
    "${PROJECT_BINARY_DIR}/config.h"
    )
# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
        "Use provided math implementation" ON)
# 是否加入 MathFunctions 库
if (USE_MYMATH)
    include_directories ("${PROJECT_SOURCE_DIR}/math")
    add_subdirectory (math)
    set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo ${EXTRA_LIBS})




configure_file 命令用于加入一个配置头文件 config.h ,这个文件由 cmake 从 config.h.in 生
成,通过这样的机制,将可以通过预定义一些参数和变量来控制代码的生成。
option 命令添加了一个 USE_MYMATH 选项,并且默认值为 ON 。根据 USE_MYMATH 变量的值来决定是
否使用我们自己编写的 MathFunctions 库。




修改 main.cc 文件,让其根据 USE_MYMATH 的预定义值来决定是否调用标准库还是MathFunctions 库:

#include "config.h"
#ifdef USE_MYMATH
    #include "math/MathFunctions.h"
#else
    #include <math.h>
#endif
 
int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
 
#ifdef USE_MYMATH
    printf("Now we use our own Math library. \n");
    double result = power(base, exponent);
#else
    printf("Now we use the standard library. \n");
    double result = pow(base, exponent);
#endif
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}




编写 config.h.in 文件
注意 main.cc 的第一行,这里引用了一个 config.h 文件,这个文件预定义了 USE_MYMATH 的值。但
我们并不直接编写这个文件,为了方便从 CMakeLists.txt 中导入配置,我们编写一个 config.h.in 
文件,内容如下:

#cmakedefine USE_MYMATH

这样 cmake 会自动根据 CMakeLists.txt 配置文件中的设置自动生成 config.h 文件.

4.4 开源项目实践

4.4.1 

腾讯的TARS

我的电脑上的TARS主框架的CMakeLists.txt路径是:/home/muten/module/TARS/TarsFramework/CMakeLists.txt

add_custom_comand和add_custom_target的链接

        set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${PROJECT_BINARY_DIR}/${BUILD_SERVER}/${MODULE}/bin)
    endforeach()

    include_directories(${PROJECT_SOURCE_DIR}/tarscpp/servant/protocol/framework)
    include_directories(${PROJECT_SOURCE_DIR}/tarscpp/util/include)
    if(WIN32)
        include_directories(${PROJECT_SOURCE_DIR}/tarscpp/util/src/epoll_windows)
    endif()

    include_directories(${servant_SOURCE_DIR}/servant)

    aux_source_directory(. DIR_SRCS)

    add_executable(${MODULE} ${DIR_SRCS})
    add_dependencies(${MODULE} FRAMEWORK-PROTOCOL)
    add_dependencies(${MODULE} tars2cpp)

    target_link_libraries(${MODULE} tarsservant tarsutil ${LIB_MYSQL})

    if(TARS_SSL)
        target_link_libraries(${MODULE} ${LIB_SSL} ${LIB_CRYPTO})
    endif()

    if(TARS_HTTP2)
        target_link_libraries(${MODULE} ${LIB_HTTP2})
    endif()

    if(NOT WIN32)
        link_libraries(pthread z dl)
    endif()
endmacro()

add_subdirectory(mysql-tool)
#add_subdirectory(tars-client)

add_subdirectory(ConfigServer)
add_subdirectory(NodeServer)
add_subdirectory(NotifyServer)
add_subdirectory(PatchServer)
add_subdirectory(AdminRegistryServer)
add_subdirectory(RegistryServer)
add_subdirectory(PropertyServer)
add_subdirectory(LogServer)
add_subdirectory(patchclient)
add_subdirectory(StatServer)
add_subdirectory(QueryStatServer)
add_subdirectory(QueryPropertyServer)
#add_subdirectory(AuthServer)
############################################################################################
# 打包deploy, 用于部署

set(DEPENDS_LIST)
list(APPEND DEPENDS_LIST tarsnode)
list(APPEND DEPENDS_LIST tarsregistry)
list(APPEND DEPENDS_LIST tarsAdminRegistry)
list(APPEND DEPENDS_LIST tarspatch)
list(APPEND DEPENDS_LIST tarsconfig)

set(FRAMEWORK-TGZ "${CMAKE_BINARY_DIR}/framework.tgz")

#执行命令
add_custom_command(OUTPUT ${FRAMEWORK-TGZ}
        WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${BUILD_SERVER}
        COMMAND ${CMAKE_COMMAND} -E make_directory test 
        COMMAND ${CMAKE_COMMAND} -E tar czf ${FRAMEWORK-TGZ} ${DEPENDS_LIST}
        COMMAND ${CMAKE_COMMAND} -E copy ${FRAMEWORK-TGZ} ${PROJECT_BINARY_DIR}
        COMMENT "make framework-tar")

add_custom_target(framework-tar
        DEPENDS ${FRAMEWORK-TGZ} ${DEPENDS_LIST})

############################################################################################
# 打包tarsnotify tarsstat tarsproperty tarslog tarsauth tarsquerystat tarsqueryproperty

set(DEPENDS_LIST)
list(APPEND DEPENDS_LIST tarsnotify)
list(APPEND DEPENDS_LIST tarsstat)
list(APPEND DEPENDS_LIST tarsproperty)
list(APPEND DEPENDS_LIST tarslog)
list(APPEND DEPENDS_LIST tarsquerystat)
list(APPEND DEPENDS_LIST tarsqueryproperty)

foreach (MODULE ${DEPENDS_LIST})

    set(MODULE-TGZ "${CMAKE_BINARY_DIR}/${MODULE}.tgz")

    add_custom_command(OUTPUT ${MODULE-TGZ}
            WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
            COMMAND ${CMAKE_COMMAND} -E make_directory ${MODULE}
            COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_SERVER}/${MODULE}/bin/${MODULE} ${MODULE}/
            COMMAND ${CMAKE_COMMAND} -E tar czf ${MODULE-TGZ} ${MODULE}
            COMMAND ${CMAKE_COMMAND} -E remove_directory ${MODULE}
            COMMENT "create ${MODULE-TGZ}")

    add_custom_target(${MODULE}-tar DEPENDS ${MODULE-TGZ} ${MODULE})
endforeach ()

############################################################################################

install(DIRECTORY ${PROJECT_BINARY_DIR}/${BUILD_SERVER}/ DESTINATION deploy/framework/${BUILD_SERVER}
        PATTERN "tars*"
        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE)

IF(WIN32)
install(DIRECTORY deploy DESTINATION ./ 
        PATTERN "*.bat"
        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE)

install(FILES ${PROJECT_BINARY_DIR}/src/mysql/lib/libmysql.dll DESTINATION deploy)

else(WIN32)
install(DIRECTORY deploy DESTINATION ./ 
        PATTERN "*.sh"
        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE)
install(FILES ${PROJECT_BINARY_DIR}/bin/tars2case DESTINATION deploy)

ENDIF(WIN32)

############################################################################################
#for debug

macro(copy_server server)
if(WIN32)
        add_custom_target(cp-${server}
                WORKING_DIRECTORY ${WORKING_DIRECTORY}
                DEPENDS ${server}
                # COMMAND ${TARS_INSTALL_PATH}/${server}/util/stop.bat
                COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_SERVER}/${server}/bin/${server}.exe ${TARS_INSTALL_PATH}/tars/${server}/bin/
                # COMMAND start /b ${TARS_INSTALL_PATH}/${server}/util/start.bat
                COMMENT "cp ${server} & restart: copy ${BUILD_SERVER}/${server}/bin/${server}.exe ${TARS_INSTALL_PATH}/tars/${server}/bin/")
else(WIN32)
        add_custom_target(cp-${server}
                WORKING_DIRECTORY ${WORKING_DIRECTORY}
                DEPENDS ${server}
                COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_SERVER}/${server}/bin/${server} ${TARS_INSTALL_PATH}/tars/${server}/bin/
                COMMAND ${TARS_INSTALL_PATH}/tars/${server}/util/start.sh
                COMMENT "cp ${server} & restart")
endif(WIN32)
endmacro()

copy_server(tarsAdminRegistry)
copy_server(tarsnotify)
copy_server(tarsnode)
copy_server(tarsstat)
copy_server(tarsquerystat)
copy_server(tarsqueryproperty)
copy_server(tarsregistry)
copy_server(tarslog)
copy_server(tarspatch)
copy_server(tarsproperty)

4.4.2 hello

usr/local/app/tars/HelloServer/src/CMakeLists.txt


cmake_minimum_required(VERSION 2.8)

project(TestApp-HelloServer)

gen_server(TestApp HelloServer)

#target_link_libraries(mysqlclient ssl crypto nghttp2-static)

4.4.3 协程的例子

build_tars_server("CoroutineDemoClient" "CoroutineDemoAServer CoroutineDemoBServer")

/home/muten/module/TARS/TarsFramework/tarscpp/examples/CoroutineDemo/client/CMakeLists.txt

 

  • 11
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
CMake是一款跨平台的开源构建工具,用于管理和构建软件项目。CMake手册详解是CMake官方提供的教程文档,旨在帮助开发者深入了解和学习CMake的使用方法和功能。 CMake手册详解下载可以通过多种方式实现。首先,可以访问CMake官方网站,从中文或英文文档页面下载最新的CMake手册详解。同时,CMake还提供了在线文档,可以直接在网页上查看和学习。 此外,CMake的源代码仓库中也包含了完整的CMake手册详解,可以通过克隆或下载源代码仓库的方式获取。在源代码仓库中,手册详解通常在docs目录下,按照不同版本和语言进行组织和分类。 另一种常见的获取CMake手册详解的方式是通过社区和论坛。CMake拥有广泛的用户社区,许多开发者在论坛中分享他们编写的教程和手册详解。可以通过搜索引擎或加入相关社区来获取这些用户贡献的手册详解,并进行下载和学习。 无论通过哪种方式获取CMake手册详解,建议选择最新版本的手册以获取最新的特性和功能说明。通过仔细阅读手册详解,开发者可以系统性地学习CMake的用法,并运用CMake来管理和构建自己的软件项目。手册中还包含了各种示例和案例,帮助开发者更好地理解和应用CMake的各个方面。 总之,CMake手册详解是学习和使用CMake的重要参考资料,通过下载和阅读手册详解,开发者可以更好地掌握CMake的功能和用法,加快软件项目的构建和管理速度。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值