CMake是一个跨平台、开源的编译管理软件,英文就是cross-platform, open-source build system。它是在其它众多编译工具之上(如Make、Visual Studio、Xcode等)创建了一层封装。用户须要编写和维护一个名为CMakeLists.txt
的文件,而后运行cmake
命令生成相应的项目文件(如针对Make就是生成Makefile
)。我本身之前也写过一个相似的软件,可是没有支持,另外看到CMake后就放弃了。你们在用的时候通常会遇到以下问题:git
针对多编程语言,CMake已经作得很好了,只要在声明项目的时候加上相应的语言就好了,如:github
project (项目名称 C CXX Fortran)
而后列出须要编译的程序文件,CMake会用相应的编译器去编译它们。这大大简化了维护编译文件的负担,这一点也是我最为欣赏的。编程
第二点其实更为重要,也更为头痛。CMake提供了不少Find<XXX>.cmake
模块,号称是方便用户查找相应的依赖库。好比我要用到C++中的Boost
库,只要写以下语句:编程语言
find_package (Boost 1.55.0 REQUIRED COMPONENTS regex filesystem system timer date_time )
它代表须要版本不能低于1.55.0
的Boost
库,使用了其中的regex
,filesystem
,system
,timer
,date_timer
子库,相应的头文件和库文件的编译选项会设置在以下两个CMake变量:工具
Boost_INCLUDE_DIRS Boost_LIBRARIES
用它们作相应设置,就可让编译器正确编译:ui
include_directories (${Boost_INCLUDE_DIRS}) ... target_link_libraries (目标名 ... ${Boost_LIBRARIES} )
对于搜索我要多说一句,FindBoost.cmake
会参考环境变量BOOST_ROOT
,若是有该变量,那么就使用它所指向的Boost
。我我的以为这个实际上是CMake的亮点,可是并非全部的Find<XXX>.cmake
模块都写得很好,好比FindArmadillo.cmake
,它就不参考ARMADILLO_ROOT
环境变量,所以若是咱们安装的Armadillo
库到一个非标准的路径下,即便咱们设置了ARMADILLO_ROOT
,CMake也是找不到它的。你会碰见恼人的错误:code
CMake Error at /opt/packman/cmake/3.2.1/share/cmake-3.2/Modules/FindPackageHandleStandardArgs.cmake:138 (message): Could NOT find Armadillo (missing: ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR) Call Stack (most recent call first): /opt/packman/cmake/3.2.1/share/cmake-3.2/Modules/FindPackageHandleStandardArgs.cmake:374 (_FPHSA_FAILURE_MESSAGE) /opt/packman/cmake/3.2.1/share/cmake-3.2/Modules/FindArmadillo.cmake:107 (find_package_handle_standard_args) external/geomtk/CMakeLists.txt:46 (find_package)
我就查看了CMake中的FindArmadillo.cmake
文件,作了以下修改:orm
# UNIX paths are standard, no need to write. find_library(ARMADILLO_LIBRARY NAMES armadillo HINTS # <-- ENV ARMADILLO_DIR # <-- ENV ARMADILLO_ROOT # <-- PATH_SUFFIXES # <-- lib # <-- lib64 # <-- PATHS "$ENV{ProgramFiles}/Armadillo/lib" "$ENV{ProgramFiles}/Armadillo/lib64" "$ENV{ProgramFiles}/Armadillo" ) find_path(ARMADILLO_INCLUDE_DIR NAMES armadillo HINTS # <-- ENV ARMADILLO_DIR # <-- ENV ARMADILLO_ROOT # <-- PATH_SUFFIXES # <-- include # <-- PATHS "$ENV{ProgramFiles}/Armadillo/include" )
就能够搜索到了。另外还有就是一个库可能依赖许多其它库,此时不能仅仅添加该库,还要将它的全部依赖库都添加进来才能正常编译链接!例如GDAL
库,它依赖不少库(不列举了),若是这些库不是放置在标准路径下,那么连接时就会出现著名的“找不到符号”的错误,所以我又对FindGDAL.cmake
作了以下修改:get
exec_program(${GDAL_CONFIG} ARGS --dep-libs OUTPUT_VARIABLE GDAL_CONFIG_DEP_LIBS) set(GDAL_LIBRARIES ${GDAL_LIBRARY} ${GDAL_CONFIG_DEP_LIBS})
即把GDAL
依赖的库(由gdal-config
命令获取)也添加到GDAL_LIBRARIES
里,就能够了。编译器
以上两处修改我都放到了我所作的跨平台、开源包管理器PACKMAN中了,所以凡是经过PACKMAN安装的CMake都包含了这两处修改~
$ packman install cmake
此处是对PACKMAN的广告~ 如不喜欢请忽视!
先写到这里了,有其它想法再添加。