zoukankan      html  css  js  c++  java
  • cmake

    cmake在编译期间会使用到的命令总结:
    1、指定编译器并同时设置编译选项

    set(CMAKE_CXX_COMPILER      "clang++" )         # 显示指定使用的C++编译器
    set(CMAKE_CXX_FLAGS   "-std=c++11")             # c++11
    set(CMAKE_CXX_FLAGS   "-g")                     # 调试信息
    set(CMAKE_CXX_FLAGS   "-Wall")                  # 开启所有警告
    set(CMAKE_CXX_FLAGS_DEBUG   "-O0" )             # 调试包不优化
    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " )   # release包优化
    CMAKE_CXX_FLAGS设置的编译选项只会对g++有效,其他编译器不生效   
    

    当然我们也可以通过add_compile_options()设置,但是通过add_compile_options会对所有编译器生效,如:

    add_compile_options(-std=c++11)
    

    在编译C代码时就会产生告警信息
    2、编译库文件
    1、cmake可以通过add_library利用源文件生成动态和静态库文件,指令如下:

    add_library(libxxx1 SHARED xxx.cpp xxxx.cpp) ##命令根据xxx.cpp和xxxx.cpp生成动态库文件libxxx1.so
    add_library(libxxx2 STATIC xxx.cpp xxxx.cpp) ##命令根据xxx.cpp和xxxx.cpp生成静态库文件libxxx1.a
    add_library(libxxx3 MODULE xxx.cpp xxxx.cpp) ##命令根据xxx.cpp和xxxx.cpp生成中间文件libxxx3,该文件不会被加载到其他地方使用
    

    库文件生成后,我们需要对其属性进行设置,如重置库文件的名称,设置库文件的版本号等,这些需要通过set_target_properties命令实现:

    1、将静态库hello_static更名为hello
      set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello") 
    2、cmake在构建一个新的target时,会尝试清理掉其它使用这个名字的库,所以在构建libxxx.a时,就会清理掉libxxx.so,所以为了避免这种情况,我们需要如下指令
      set_target_properties(xxx PROPERTIES CLEAN_DIRECT_OUTPUT 1)
      set_target_properties(xxx_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    3、有时候我们需要增加动态库的版本号
      set_target_properties(hello PROPERTIES VERSION 1.2 SOVERSION 1) ## VERSION指代动态库版本,SOVERSION指代API版本
    

    2、当然我们也可以使用外部现成的库文件,指令如下

    add_library(libxxx4 <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED) 
    IMPORTED 表明此库在工程之外,是target_link_libraries的方便形式。外部库的详细信息通过set_target_properties
    设置以IMPORTED_开头的属性来完成,其中最重要的就是 IMPORTED_LOCATION 属性,它指定外部库的位置。
    add_library(libxxx4 STATIC IMPORTED)
    set_target_properties(libxxx4 PROPERTIES IMPORTED_LOCATION /path/to/libboost_system.a) ##libxxx4其实就是libboost_system.a
    target_link_libraries(wang libxxx4)
    其实上述3条命令等价于
    target_link_libraries(wang /path/to/libboost_system.a)
    

    注意:add_library除了可以生产库文件之外,还可以生成目标文件,但不打包成lib命令如下:

    add_library(objlib OBJECT <src>...)
    这种库只编译源文件生成目标文件,但是不把这些目标文件打包进一个lib。当其他的库或者目标文件要使用这些目标文件的时候,会以这样的形式来添加,objlib是这个库的名字
    add_library(... $<TARGET_OBJECTS:objlib> ...)
    add_executable(... $<TARGET_OBJECTS:objlib> ...)
    

    寻找外部依赖库find_package()
    在一个大型项目中,免不了需要导入很多外部依赖库,比如一个项目需要使用到伯克利数据库项目,我们需要知道头文件的位置,库文件的位置以及库文件的名称,此时我们就需要find_package命令
    find_package命令就是寻找该库的头文件位置、库文件位置以及库文件名称,并将其设置为变量提供给CMakelists使用。以上述伯克利数据库项目为例,

    find_package(DBMS)
    include_directories(${DBMS_INCLUDE_DIR})
    target_link_libraries(main ${DBMS_LIBRARY})
    

    find_package(DBMS)会去 ${CMAKE_MODULE_PATH}指定的所有路径下寻找名字为FindDBMS.cmake的文件,并执行相应的代码,通常FindDBMS.cmake会输出如下几个变量
    通常FindCURL.cmake文件会提供以下几个变量:

    <name>_FOUND => 表明是否查找到
    <name>_INCLUDE_DIR 或 <name>_INCLUDES => 表示头文件位置
    <name>_LIBRARY 或 <name>_LIBRARIES 或 <name>_LIBS => 表示库文件路径+名称
    <name>_DEFINITIONS
    

    编写FindDBMS.cmake
    FindDBMS.cmake主要使用如下两个函数find_path/find_library,其中find_path输出头文件的位置信息,find_library输出库文件的位置信息
    find_path原型如下:
    查找路径HINTS/PATH/PATH_SUFFIXES下,是否有文件名为name1的文件,如果有则将HINTS/PATH/PATH_SUFFIXES的内容存储在中,否则中存储_NOTFOUND

     find_path(<VAR>
                 name | NAMES name1 [name2 ...]
                 [HINTS path1 [path2 ... ENV var]]
                 [PATHS path1 [path2 ... ENV var]]
                 [PATH_SUFFIXES suffix1 [suffix2 ...]]
                 [DOC "cache documentation string"]
                 [NO_DEFAULT_PATH]
                 [NO_CMAKE_ENVIRONMENT_PATH]
                 [NO_CMAKE_PATH]
                 [NO_SYSTEM_ENVIRONMENT_PATH]
                 [NO_CMAKE_SYSTEM_PATH]
                 [CMAKE_FIND_ROOT_PATH_BOTH |
                  ONLY_CMAKE_FIND_ROOT_PATH |
                  NO_CMAKE_FIND_ROOT_PATH]
    )
    举例如下:
    find_path(dbms_path
              NAMES db_xxx.h 
              PATHS /home/dongfang/cmake_example/find_path
              DOC "this is a test for find_path"
    )
    查找路径PATH(/home/dongfang/cmake_example/find_path)下是否有db_xxx.h文件,如果有则将"/home/dongfang/cmake_example/find_path"存储在变量dbms_path中
    

    find_library原型如下:
    查找路径HINTS/PATH/PATH_SUFFIXES下,是否有文件名为name1的文件,如果有则将HINTS/PATH/PATH_SUFFIXES的内容存储在中,否则中存储_NOTFOUND

       find_library(
                 <VAR>
                 name | NAMES name1 [name2 ...]
                 [HINTS path1 [path2 ... ENV var]]
                 [PATHS path1 [path2 ... ENV var]]
                 [PATH_SUFFIXES suffix1 [suffix2 ...]]
                 [DOC "cache documentation string"]
                 [NO_DEFAULT_PATH]
                 [NO_CMAKE_ENVIRONMENT_PATH]
                 [NO_CMAKE_PATH]
                 [NO_SYSTEM_ENVIRONMENT_PATH]
                 [NO_CMAKE_SYSTEM_PATH]
                 [CMAKE_FIND_ROOT_PATH_BOTH |
                  ONLY_CMAKE_FIND_ROOT_PATH |
                  NO_CMAKE_FIND_ROOT_PATH]
    )
    举例如下:
    find_library(dbms_library
                 NAMES libDBMS.so
                 PATHS /home/dongfang/cmake_example/find_path
                 DOC "this is a test for find_path"
    )
    查找路径PATH(/home/dongfang/cmake_example/find_path)下是否有libDBMS.so文件,如果有则将"/home/dongfang/cmake_example/find_path"存储在变量dbms_library中
    

    在经过查找头文件和库文件路径之后,我们需要对下游负责,明确告知下游头文件路径和库文件路径是否准确找到,可使用如下命令:

    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(DBMS dbms_path dbms_library) //如果dbms_path或者dbms_library无值,直接对下游报错
    

    安装
    不管是库文件还是目标文件,编出来之后,都需要将其放到一定的位置,方便其他目标文件使用,此时就需要install命令

    install(TARGETS xylib
        CONFIGURATIONS DEBUG
        RUNTIME DESTINATION bin  ##可执行文件安装路径
        LIBRARY DESTINATION lib  ##动态库安装路径
        ARCHIVE DESTINATION libstatic  ##静态库安装路径
        )
    
  • 相关阅读:
    利用border-radius画椭圆
    关于使用svg构建六边形蜂巢列表的方式
    JavaScript拖拽效果的原理及实现
    逆战班-JS的形参与实参
    前端面试&笔试汇总
    less学习---less的混合(mixin)
    less学习---less的嵌套规则
    less学习----less变量
    vue-cli3实现将数据导出为Excel表
    js中apply和call方法浅析
  • 原文地址:https://www.cnblogs.com/wangdongfang/p/13382882.html
Copyright © 2011-2022 走看看