首页 > 代码库 > 【转载】cmake编写

【转载】cmake编写

  Cmake的输入是在源码目录下的CMakeLists.txt文件。这个文件可以用include或者 add_subdirectory 命令增加入其它的输入文件。

语法

  CMakeList.txt文件是由注释、命令和空白字符组成。

  注释是由 # 开始,到行结尾。

  命令是由:命令名、(、空格分隔的参数、)组成。

  例如:command (args….)

  上面的command可以是一个命令名;或者是一个宏;也可以是一个函数名。

  args是以空格分隔的参数例表(如果参数中包含空格,则要加双引号)

  除了用于分隔参数的空白字符(空格、换行号、tabs)都是被忽略不计的。任何包含在双引号中的字符都做为一个参数。一个反斜杠用于转换码。

  命令名是大小写不敏感的。

字符串(string)和字符串列表(lists)

  CMake的基本数据类型是字符串(string)。CMake也支持由字符串组成的字符串列表。字符串列表可以由;或空格分隔的组成。例如:下面设置变量var是等效的。

  set(var a;b;c)

  set(var a b c)

  字符串列表可以用 foreach命令叠代(iterated)或list命令操作。

变量

  CMake支持简单的变量:字符串或字符串列表。用${VAR} 语法得到变量的引用。

  可以用一个set命令把一个字符串列表设置为一个变量,然后把这个变量传递给需要传递多参数的函数。例如:

  set(Foo a b c)

  command(${Foo})

  上面两行等效 command(a b c)

  如果你想传把一个字符串列表做为一个单独的参数传递给函数,用双引号包含它。例如:

  Command(“${Foo}”)

  等效于:command(“a b c”)

环境变量:

  用$ENV{VAR}得到环境变量的引用

  设置环境变量:

  Set(ENV{VAR} /home) 

程序流控制

  CMake提供三种程序流控制结构:

1.条件声明:if

  # some_command will be called if the variable‘s value is not:
  # empty, 0, N, NO, OFF, FALSE, NOTFOUND, or -NOTFOUND. 
  if(var) 
      some_command(...) 
  endif(var)

2. 循环控制:foreach 和 while

  set(VAR a b c) 
  # loop over a, b,c with the variable f 
  foreach(f ${VAR}) 
    message(${f}) 
  endforeach(f)

3.程序定义:宏或函数(函数在CMake2.6以后的版本才支持)。函数建立本地范围内的变量,宏用于全局范围内。

# define a macro hello macro(hello MESSAGE)  message(${MESSAGE})endmacro(hello) # call the macro with the string "hello world" hello("hello world") # define a function hello function(hello MESSAGE)  message(${MESSAGE}) endfunction(hello)

  函数可以返回,可以用 return()命令返回。如果要从函数中返回值,只能通过参数返回:

  #定义函数 get_lib从给定的目录查找指定的库,并把它传回到参数 lib_FILE中

function(get_lib lib_FILE lib_NAME lib_PATH)#message("lib_name:""${lib_NAME}")    set(__LIB "__LIB-NOTFOUND")    #message("__LIB:""${__LIB}")    find_library(__LIB ${lib_NAME} ${lib_PATH})    if(__LIB STREQUAL "__LIB-NOTFOUND")        message("don‘t find ${lib_NAME} librarys in ${lib_PATH}")        return()    endif()    #message("__LIB:""${__LIB}")    set(${lib_FILE} ${__LIB}PARENT_SCOPE)endfunction(get_lib)

set命令中 PARENT_SCOPE表示传递给函数调用者所拥有的变量

模板

├── bin│   └── main├── build├── CMakeLists.txt├── doc├── README└── src    ├── CMakeLists.txt    ├── libs    │   ├── hello.cpp    │   └── hello.h    ├── main.cpp    └── modules

根目录下的CMakeLists.txt:

#项目名称PROJECT(hello)#声明要求的最小版本cmake_minimum_required(VERSION 2.6)SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2")SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2")#添加参与编译的子目录 我理解为:添加下一个CMakeLists.txtadd_subdirectory(src)

src下的:

#添加头文件的查找目录 && 在编译参数"-l" ,指定搜索头文件的路径INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/libs)SET(SEC_LIST     main.cpp    libs/hello.cpp)ADD_EXECUTABLE(main ${SEC_LIST})#TARGET_LINK_LIBRARIES 用来链接 -l后的文件依赖#TARGET_LINK_LIBRARIES(CRNode thread)#EXECUTABLE_OUTPUT_PATH && LIBRARY_OUTPUT_PATH用来指定二进制文件位置和库文件路径,这里不包括中间文件SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)#关于install 请看http://now-code.com/archives/208

包含库的目录:

├── bin├── build├── CMakeLists.txt├── doc├── README└── src    ├── apps    │   ├── CMakeLists.txt    │   └── main.cpp    ├── CMakeLists.txt    ├── includes    │   └── hello.h    ├── libs    │   ├── CMakeLists.txt    │   └── hello.cpp    └── modules

根目录下:

PROJECT(hello)cmake_minimum_required(VERSION 2.6)SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2")SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2")add_subdirectory(src)

src->apps 下:

 set(myexe_EXEC_SRCS    main.cpp    # 其它cpp文件    )#一定要包含main.cpp 包含的"*.h"文件include_directories(    ${PROJECT_SOURCE_DIR}/src/includes/    #${PROJECT_BINARY_DIR}/src/libs/    #${PROJECT_SOURCE_DIR}/src/libs/markup     #${PROJECT_SOURCE_DIR}/src/modules/    #/opt/Ice/include)#库文件路径link_directories(/usr/local/lib#$ENV{ORACLE_HOME}/lib)#添加自己生成的动态库/静态库 设置目标所需要的链接库#link_libraries(myexe markup)link_libraries(main hellolib)add_executable(main ${myexe_EXEC_SRCS})set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin/)#install(TARGETS main RUNTIME DESTINATION bin)

src->libs 的:

set(utils_LIB_SRCS    hello.cpp    #其它cpp文件    )include_directories(    ${PROJECT_SOURCE_DIR}/src/includes    #${PROJECT_SOURCE_DIR}/src/libs/markup     #${PROJECT_SOURCE_DIR}/src/libs)link_directories(    /usr/local/lib     #其它库路径    )#link_libraries(utils markup)#link_libraries(utils uuid)#生成动态库  静态库则 STATICadd_library (hellolib SHARED ${utils_LIB_SRCS})set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/src/libs/)

转载自

cmake使用——cmake语法 http://blog.csdn.net/kl222/article/details/7519340

Cmake 模板和语法 http://blog.csdn.net/feibuhui123/article/details/8552719

推荐阅读

cmake 学习笔记(一) http://blog.csdn.net/dbzhang800/article/details/6314073

CMake 2.8.8 Documentation http://www.cmake.org/cmake/help/v2.8.8/cmake.html