唠叨CMake工具

CMake是一个跨平台、开源的编译管理软件,英文就是cross-platform, open-source build system。它是在其它众多编译工具之上(如Make、Visual Studio、Xcode等)建立了一层封装。用户需要编写和维护一个名为CMakeLists.txt的文件,然后运行cmake命令生成相应的项目文件(如针对Make就是生成Makefile)。我自己以前也写过一个类似的软件,但是没有支持,另外看到CMake后就放弃了。大家在用的时候一般会遇到如下问题:

  • 多编程语言如何管理
  • 依赖库的编译选项如何管理

针对多编程语言,CMake已经做得很好了,只要在声明项目的时候加上相应的语言就行了,如:

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.0Boost库,使用了其中的regexfilesystemsystemtimerdate_timer子库,相应的头文件和库文件的编译选项会设置在如下两个CMake变量:

Boost_INCLUDE_DIRS
Boost_LIBRARIES

用它们做相应设置,就可以让编译器正确编译:

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也是找不到它的。你会遇见恼人的错误:

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文件,做了如下修改:

# 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做了如下修改:

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的广告~ 如不喜欢请忽视!

先写到这里了,有其它想法再添加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值