• CMakeLists 编写规则


    实例-1

    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)  #声明Cmake版本,如果低于指定版本则会停止处理工程文件,并报告错误
    PROJECT(XXX)
    
    SET(CMAKE_BUILD_TYPE Release)
    SET(CMAKE_CXX_FLAGS "-std=c++11 -O2 -mfloat-abi=hard -mfpu=neon")
    
    #micro 
    #ADD_DEFINITIONS( -DDDDDDDDD)
    
    #include and libs path
    SET(INCLUDE_PATH . ../ /usr/include/eigen3 /srv/boost_1_63_0 )
    
    SET(LINK_PATH /srv/boost_1_63_0/stage/lib )
    
    INCLUDE_DIRECTORIES(${INCLUDE_PATH})
    LINK_DIRECTORIES(${LINK_PATH} )
    
    #source files in dir
    
    #dir CommonH
    AUX_SOURCE_DIRECTORY(filepath name)
    
    #execuable 
    ADD_EXECUTABLE(XX mainV2.cpp ${name} )
    
    TARGET_LINK_LIBRARIES(XX libnames)

    指令说明

    CMAKE_MINIMUM_REQUIRED(VERSION major[.minor[.patch[.tweak]]] [FATAL_ERROR])
    

    声明Cmake版本,如果低于指定版本则会停止处理工程文件,并报告错误

    PROJECT(PROJECTNAME [CXX] [C])

    [指定工程支持的语言,如果忽略,表示支持所有语言]

    ADD_EXECUTABLE([WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 ...)

    引入一个名为的可执行目标,该目标会由调用该命令时在源文件列表中指定的源文件来构建。对应于逻辑目标名字,并且在工程范围内必须是全局唯一的,如果构成可执行文件的源文件很多,

    AUX_SOURCE_DIRECTORY(. DIRSRCS)

    则可以指定一个源文件列表或者添加文件夹内所有文件 

    CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
    PROJECT(Hello)
    
    SET (SRC_LIST main.cpp v4l2_util.cpp tran_data.cpp)
    MESSAGE(${SRC_LIST})
    ADD_EXECUTABLE(Hello ${SRC_LIST})

    ADD_EXECUTABLE:可执行程序由哪些.o文件生成

    实例-2 编译静态库,并让主程序调用静态库最终生成一个可执行程序

    即先生成一个hello.a,再让主程序main.cpp使用libhello.a,最终生成Hello

    CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
    PROJECT(Hello)
    SET(LIB_SRC_LIST source1.cpp  source2.cpp)
    SET(EXEC_SRC_LIST main.cpp)
    ADD_LIBRARY(LIB STATIC ${LIB_SRC_LIST})
    ADD_EXECUTABLE(Test_Hello ${EXEC_SRC_LIST})
    TARGET_LINK_LIBRARIES(Test_Hello LIB)

    创建一个名字name的库文件,SHARED STATIC 制定生成库的类型

    ADD_LIBRARY(NAME [STATIC| SHARED|MODULE] [EXCLUDE_FROM_ALL] source1, source2,...) 

    将给定的库链接到target上,默认优先链接动态库,类似于静态链接,必须放置在ADD_EXECUTABLE后面,否则都会出现undefied reference函数

    TARGET_LINK_LIBRARIES(target [item1 [item2] [ ...] ]),LINK_DIRECTORIES

    • 指定include路径

    一般情况下,src和include为同级目录,需要指定include路径src才可以正确定位头文件

    SET(INCLUDE_DIRECTORIES " ../include")
    INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})

    它相当于g++选项中的-I参数的作用,也相当于环境变量中增加路径到CPLUS_INCLUDE_PATH变量的作用。

    • 添加第三方库,不需要编译,将他放在resource目录下,需要指定搜索库路径
    SET(LINK_DIR "../../resource")
    LINK_DIRECTORIES(${LINK_DIR })

    相当于g++命令的-L选项的作用,也相当于环境变量中增加LD_LIBRARY_PATH的路径的作用。

    如果想设置更多的关于动态库的参数例如: -Wl,-rpath=usr/local/lib

    LINK_LIBRARY("/usr/local/lib")
    ADD_EXECUTABLE(main main.c)
    • 创建Release和Debug版本
    SET(CMAKE_BUILD_TYPE Release)
    SET(CMAKE_BUILD_TYPE Debug)

    二者模式区别在于

    Release: -O3 -DNDEBUG
    Debug: -g

    也可不加在MakeFiles.txt里面,在产生Makefiles时候才加入

    cmake -DCMAKE_BUILD_TYPE=Release

    #增加编译和链接选项

    CMAKE_C_FLAGS
    CMAKE_CXX_FLAGS
    CMAKE_EXE_LINKER_FLAGS

    分别相当于:CFLAGS, CXXFLAGS, LDFLAGS

    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEMBED")

    这种写法的好处是,不会覆盖CMAKE_CXX_FLAGS本来的信息。只是把需要添加的内容添加进去

    Debug和Release版本:

    关键在于三个CMake设置:

    CMAKE_BUILD_TYPE

    CMAKE_CXX_FLAGS_DEBUG, CMAKE_CXX_FLAGS_RELEASE

    当CMAKE_BUILD_TYPE设置为Debug。 则编译时采用CMAKE_CXX_FLAGS_DEBUG。

    当CMAKE_BUILD_TYPE设置为Release。 则编译时采用CMAKE_CXX_FLAGS_RELEASE

    例如

    cmake_minimum_required (VERSION 2.6)
    project (CMAKE_Test)
    add_executable(CMAKE_Test src/banchmark.cpp)
    #set(CMAKE_BUILD_TYPE Debug)
    set(CMAKE_BUILD_TYPE Release)
    set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb -Wno-unused-but-set-variable")
    set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -Wno-unused-but-set-variable")
    • 多目录结构的cmake使用

    Hello 实际的目录结构其实并不是所有源码都存放在src目录内。它的目录结构是:

    src: 存放生成库的源码。source1.cpp, source2.cpp
    test:存放使用库的测 试程序: main.cpp
    include: 存放头文件: source1.h
    resource: 存放第三方库
    build:存放编译过程的文件
    build/lib: 存放生成的libv4l2_utils.so
    build/bin:存放main.cpp所产生的测试程序可执行文件。

    此时,可以采用顶层目录和每个有源码的目录中均创建CMakeLists.txt的方式来处理(和Makefile处理方式类似),顶层目录的CMakeLists.txt 内容如下:

    CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
    PROJECT(Hello)
    ADD_SUBDIRECTORIES(src lib)
    ADD_SUBDIRECTORIES(test bin)

    构建添加一个子路径

    ADD_SUBDIRECTORIES([source dir] [bin dir] [exclude_from_all])

    source_dir选项指定了CMakeLists.txt源文件和代码文件的位置。如果source_dir是一个相对路径,那么source_dir选项会被解释为相对于当前的目录,但是它也可以是一个绝对路径。binary_dir选项指定了输出文件的路径。如果binary_dir是相对路径,它将会被解释为相对于当前输出路径。

    SOURCE_DIR算相对路径时,是从CMakeLists.txt算起。所以src指的是当前 CMakeLists.txt所在路径下的src. 而bin, lib 指的是当前输出路径下的bin,lib. 也就是build/bin build/lib

    src CMakeLists.txt :

    SET(LIB_SRC_LIST source1.cpp)
    SET(CMAKE_BUILD_TYPE Release)
    INCLUDE_DIRECTORIES(../include)
    ADD_LIBRARY(SOURCE1 SHARED ${LIB_SRC_LIST})

    test CMakeLists.txt :

    SET(EXEC_SRC_LIST main.cpp)
    SET(INCLUDE_DIRECTORIES ../include)
    SET(LINK_DIR ../../resource)
    SET(LINK_DIR "${LINK_DIR} ../../libs/")
    SET(CMAKE_BUILD_TYPE Release)
    INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES})
    LINK_DIRECTORIES(${LINK_DIR})
    ADD_EXECUTABLE(Test_Hello ${EXEC_SRC_LIST})
    TARGET_LINK_LIBRARIES(Test_Hello SOURCE1 )
    文件移动

    将某一个工程放置于某一个文件夹下(指的是工程位于某目录下)

    SET_PROPERTY(TARGET NetLib PROPERTY FOLDER "Common")

     NetLib移动到Common文件夹下

    INSTLLL(FILES ${CMAKE_LINK_PATH}/odbc/libodbc.so DESTINATION bin)

     将动态库移动到bin目录下

    显示编译细节

    SET(CMAKE_VERBOSE_MAKEFILE ON)

    如果不希望改变CMakeLists.txt,可以在创建Makefile时候加入

    cmake -DCMAKE_VERBOSE_MAKEFILE=ON

    如果连Makefile都不希望修改可以:make VERBOSE=1

    相对路径问题:

    set (LIBRARY_DIRECTORIES ../resource)
    link_directories(${LIBRARY_DIRECTORIES})

    这里会出警告:

    This command specifies the relative path:../resource

    可以做如下处理:

    SET(LIBRARY_DIRECTORIES ../resource)
    LINK_DIRECTORIES($PROJECT_SOURCE_DIR}/${LIBRARY_DIRECTORIES})

    但是如果LIBRARY_DIRECTORIES 是个列表的话,此种方式仍然会引起警告。

    CMAKE_CURRENT_SOURCE_DIR
    CMAKE_CURRENT_BINARY_DIR 
    PROJECT_SOURCE_DIR
    PROJECT_BIANRY_DIR

    内部编译时,以上四种变量没有区别,都是CMakeLists.txt所在位置

    外部编译时

    CMAKE_CURRENT_BINARY_DIR
    PROJECT_BIANRY_DIR

    在build文件夹

    FIND_PACKAGE()

    可以被用来在系统中自动查找配置构建工程所需的程序库。在linux和unix类系统下这个命令尤其有用。CMake自带的模块文件里有大半是对各种常见开源库的find_package支持,支持库的种类非常多,例如

    FIND_PACKAGE(Qt5Widgets)

    FIND_PACKAGE( [version] [EXACT] [QUIET] [[REQUIRED|COMPONENTS] [components...]] [NO_POLICY_SCOPE])

    查找并加载外来工程的设置。该命令会设置_FOUND变量,用来指示要找的包是否被找到了。如果这个包被找到了,与它相关的信息可以通过包自身记载的变量中得到。REQUIRED选项表示如果报没有找到的话,cmake的过程会终止,并输出警告信息。

    1. 在REQUIRED选项之后,或者如果没有指定REQUIRED选项但是指定了COMPONENTS选项,在它们的后面可以列出一些与包相关的部件清单(components list)。
    2. 每一个模块都会产生如下变量,_FOUND, _INCLUDE_DIR _LIBRARY和_LILBRARIES,如果_FOUND为真,_INCLUDE_DIR加入到INCLUDE_DIRECTORIES中,_LIBRARY加入到TARGET_LINK_LIBRARIES中就会有相应的变量Qt5Widgets_FOUND,Qt5Widgets_INCLUDE_DIRS等相应的变量生效。

    PKG_CHECK_MODULES

    PKG_CHECK_MODULES(<PREFIX> [REQUIRED] [QUIET] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] <MODULE> [<MODULE>]*)

    检测所有给出的modules

    PKG_CHECK_MODULES(PC_OPENNI2 libopenni2)
    if (NOT PC_OPENNI2_FOUND)
    PKG_CHECK_MODULES(PC_OPENNI2 REQUIRED openni2)
    endif()

    PC_OPENNI2_INCLUDE_DIRS, PC_OPENNI2_LIBRARY_DIRS 等被设置。

     

  • 相关阅读:
    linux下启动和关闭网卡命令及DHCP上网
    python 编码问题
    paddlepaddle
    Convolutional Neural Network Architectures for Matching Natural Language Sentences
    deep learning RNN
    Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
    Python IO密集型任务、计算密集型任务,以及多线程、多进程
    EM 算法最好的解释
    tensorflow 调参过程
    tensorflow 学习纪录(持续更新)
  • 原文地址:https://www.cnblogs.com/flyinggod/p/7805587.html
Copyright © 2020-2023  润新知