【实用工具】CMake的具体应用

130 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情

【实用工具】CMake的具体应用

  • string

    • REPLACE

           string(REPLACE 
                 <match_string> <replace_string> 
                 <output_variable> <input> [<input>...])
      

      将所有input中出现的match_String替换为replace_string,并且将结果存在output_variable

  • message

         message([<mode>] "message to display" ...)
    
    • 显示信息给用户 mode取决于信息的类型:

      • STATUS:以简洁的方式显示用户感兴趣的信息。

             message(STATUS 
                     "CXX_FLAGS = " 
                     ${CMAKE_CXX_FLAGS} 
                     " " 
                     ${CMAKE_CXX_FLAGS_${BUILD_TYPE}}
                     )
        

        可以理解为printf,把后面的几个信息以空格相间,然后打印出来。显示结果为(和上面对应分成三段):

             CXX_FLAGS = 
             
             -g -D_FILE_OFFSET_BITS=64 -Wall -Wextra 
             -Werror -Wconversion -Wno-unused-parameter 
             -Wold-style-cast -Woverloaded-virtual 
             -Wpointer-arith -Wshadow -Wwrite-strings 
             -march=native -rdynamic 
             
             -O0
        
  • find_package

         find_package(<PackageName> 
                     [version] [EXACT] [QUIET] [MODULE]
                     [REQUIRED] [[COMPONENTS] [components...]]
                     [OPTIONAL_COMPONENTS components...]
                     [NO_POLICY_SCOPE])
    

    主要是寻找和加载外部项目。如果PackageName找到了,PackageName-found会显出,当没有找到时,默认显示 PackageName-not found。通过模式的选择,可以处理在没有找到包时的解决方案。

    • QUIET:不显示有用信息,
    • REQUIRED:报错
  • find_path

         find_path (<VAR> name0|NAMES name1 [path1 path2 ...])
    

    用以寻找包含着name1文件的目录,如果找到了结果存储在VAR,没有找到结果结果是VAR-not found。成功时,变量被清除find_path再次搜索,没有成功,fin_path再次以相同的变量被调用时搜索。

  • find_library 同上find_path

         find_library (<VAR> name0|NAMES name1 [path1 path2 ...])
    
    • OPTIONS

      • NAMESlibrary指定一个或多个可能的名字。

CMake 使用

目录结构:

     Tutorial
     ├── CMakeLists.txt
     ├── selfmath
     │   ├── CMakeLists.txt
     │   ├── selfmath.cc
     │   └── selfmath.h
     ├── tutorial.cc          # 主程序文件
     └── TutorialConfig.h.in  # 配置文件
  • Tutorial/CMakeLists.txt

         cmake_minimum_required(VERSION 3.10)
         project(Tutorial VERSION 1.0)
     ​
         # 指定c++11标准
         set(CMAKE_CXX_STANDARD 11)
         set(CMAKE_CXX_STANDARD_REQUIRED True)
     ​
         option(USE_MYPATH 
             "use tutorial provided math implementation"  ON)   
         configure_file(TutorialConfig.h.in  TutorialConfig.h) # 配置
     ​
         if(USE_MYPATH)
             #  这两步就可以搜索到子目录`selfmath`下的`.cc`文件生成的静态库`libselfmath.a`。
             add_subdirectory(selfmath)
             # 函数原型`list(APPEND <list> [<element>...])`:将`element`添加到`list`中。
             list(APPEND EXTRA_LIBS selfmath)    # 这是为了找到源文件
         endif(USE_MYPATH)
     ​
         add_executable(Tutorial tutorial.cc)
         # Tutorial使用到了`selfmath`中的函数,因此链接到`selfmath`这个库
         target_link_libraries(Tutorial ${EXTRA_LIBS})
         # 把build目录加入可执行文件`Tutorial`的头文件搜索目录。
         target_include_directories(Tutorial PUBLIC
                                 "${PROJECT_BINARY_DIR}" ) # 把build目录加入 
     ​
         install(TARGETS Tutorial DESTINATION bin)
         install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include)
    
  • selfmath/CMakeLists.txt

         add_library(selfmath selfmath.cc)
         target_include_directories(selfmath 
                                 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
                                 PRIVATE   ${CMAKE_BINARY_DIR})
     ​
         # 这里都是为了检测是否存在某个函数,如果存在则使用,不存在则使用库函数               
         include(CheckSymbolExists)
         set(CMAKE_REQUIRED_LIBRARIES  "m")
         check_symbol_exists(log "math.h" HAVE_LOG)
         check_symbol_exists(exp "math.h" HAVE_EXP)
     ​
         if(HAVE_LOG AND HAVE_EXP)
             target_compile_definitions(selfmath
                                     PRIVATE "HAVE_LOG" "HAVE_EXP")
         endif()
    
     install(TARGETS selfmath DESTINATION lib)
     install(FILES selfmath.h DESTINATION include)
 ```