• cmake学习



    本工程需要,查阅海量资料,大同小异。此文参考甚多,略显杂乱,亦有本人心得。
    是为记录,他日细阅...

     cmake学习
    ~cmake跨平台,工具只需cmake和make
    ~如果工程比较小,直接用makefile就可以了
    ~c/c++/java之外的文件就不需要用了
    ~qt编程有qmake
    ~如果是比较完整的IDE,也不需要

    示例:
    1. 首先建立一个文件夹cmake,在mkdir t1,在t1下建立main.c和CMakeLists.txt
    2. main.c就是一个简单的helloworld程序。CMakeLists.txt内容:
    project(hello)
    set(SRC_LIST main.c)
    message(STATUS "this is binary dir" ${hello_BINARY_DIR}")
    message(STATUS "this is source dir" ${hello_SOURCE_DIR}")
    add_executable(hello SRC_LIST)
    3. 执行cmake .会生成makefile, 再执行make就行了。如果要看到make的构建过程,make VERBOSE=1或者VERBOSE=1

    语法:
    1. project(name [CXX] [C] [Java])
    可以指定工程支持的语言,默认支持所有语言,此时隐式定义了两个路径:name_BINARY_DIR和name_SOURCE_DIR
    同时预定义了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR两者(编译发生的当前目录)意思一样

    2.set(var value)
    定义变量,如果有多个,可以set(SRC_LIST main.c ti.c t2.c)

    3.message([...] "str")
    输出用户定义的信息,str中如果有空格就必须用"",也可以输出变量名。[...]中有三个选项可选:
    SEND_ERROR,产生错误,生成过程被跳过
    SARUS, 输出前缀为-的信息
    FATAL_ERROR,立即终止所有cmake过程

    4. add_executable()

    5. 变量定义${}后引用,如果在if语句中,就不需要这个结构了

    6. 指令大小写无关,参数和变量大小写有关

    7.特别解释:作为工程名的hello和生成的可执行文件hello是没有任何关系的

    8.可以忽略source列表中的源文件后缀,如:
    add_executable(hello main t1)
    add_executalbe(hello main.c; t1.c)都可以
    如果不得,在cmake的时候会提示错误

    9. 清理工程
    make clean

    10. in-source build和out-of-source build

    11. add_subdirectory(source_dir [binary_dir] [execlude_from_all])
    向当前工程中添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置, 后一个是排除的目录。

    改进:
    1. 添加如下文件夹:src(存放源代码), doc(hello.txt), COPYRIGHT, README, runhello.sh(调用脚本), bin(构建后的目标文件). 另外安装文件hello和runhello.sh安装到/usr/bin, doc目录及内容及安装到/usr/shar/doc/cmake/t2(自己建立的文件夹)

    2. 在src中建立CMakeLists.txt: add_executable(hello main.c), 根目录中的CMakeLists.txt中内容:project(hello)
                                      add_subdirectory(src bin) #指定在哪,就生成在哪,否则在本目录下
    然后建立build目录,进入,cmake .. ; make
    如果不进行bin目录指定,那么生成的就在build/src目录中

    3. 换个地方保存二进制文件
    可以通过EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量来指定最终的目标二进制的位置,如:
    SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
    SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)




    A.源代码在哪里?
    B.头文件在哪里?
    C.怎么生成静态或者动态库?
    D.程序链接的静态库在哪里?
    E.如果工程的代码存放在很多地方,那又该怎么找到它们呢?
     
    1. 对于一个工程,应该有的文件夹:src, bin, include, lib, build, CMakeLists.txt. cd到build下,执行cmake .. 将生成CMakeCache.txt Makefile cmake_install.cmake hello(目标文件). 此处的makefile可以直接make生成hello

    2. CMakeLists.txt
    #注释行
    projetc(hello)
    set(TEST "test hello")
    set(SRC_LST hello.c) 或者FILE(GLOB SOURCE *.c)这个是告诉源文件夹在哪
    message(${TEST})
    add_executable(hello ${SRC_LST})
    这是这个hello的cmakelists.txt
    ~其中,变量可以用小写,没有问题
    ~message(test,hello)也可,如果有空格,用""
    ~变量引用${},有空格的话用""
    ~add_executable(), 生成可执行程序
    ~如果引用内部库,就添加target_link_libraries(hello SDL) target_link_libraries(hello GLU)对应的命令是-lSDL -lGLU
    ~FILE(GLOB_RECURSE SRC_LIST "*.cpp") 将当前目录所有文件.cpp包括子目录赋值给.
    ~

    3. 可以加个if...else...endif
    例:if(WIN32)
          message(*********)
         else(WIN32)
         message(#########)
         endif(WIN32)
    三者后面都要有条件

    4.
    set()
    subdirs() 
    add_library()
    添加静态链接文件到目标中
    会查找当前目录文件和subdirs指定的文件夹

    add_executable()  添加一个可执行程序到目标文件中
    aux_source_directory()
    progect()

    5.
    include_directories(dir1 dir2...) 相当于-ldir1 -ldir2
    link_directories()
    link_libraries()
    target_link_libraries()

    6.
    project(main)工程名称
    cmake_min_requiered(version 2.6)

    aux_source_directory(<dir> <variable>) 将dir下所有的文件名赋值给var
    常用:aux_source_directory(. dir_srcs)

    7. add_subdirectory(src)指明本项目包含一个子目录src
       target_link_libraries(main test)指明main需要链接一个test链接库

    8. 常用变量
    cmake_source_dir
    project_source_dir 
    <projectname>_source_dir
    三者皆指工程顶层目录

    cmake_binary_dir
    project_binary_dir
    <projectname>_binary_dir
    如果是in-source编译,指的是工程顶层目录,如果是out-of-source指的是工程程编译发生的目录

     CMAKE_CURRENT_SOURCE_DIR
    指的是当前处理的CMakeLists.txt所在的路径。
    CMAKE_CURRRENT_BINARY_DIR
    如果是in-source编译,它跟CMAKE_CURRENT_SOURCE_DIR一致,如果是out-ofsource 编译,他指的是target编译目录。
    CMAKE_CURRENT_LIST_FILE
    输出调用这个变量的CMakeLists.txt的完整路径

    9.
    UNIX 与 WIN32
    UNIX,在所有的类UNIX平台为TRUE,包括OS X和cygwin
    WIN32,在所有的win32平台为TRUE,包括cygwin

    10. 工程示例:

    test                                     //工程根目录
    ├── cmake                     //CMake目录:代码和CMake编译目录分离
    │   ├── bin
    │   │   └── main               //生成后的可执行文件放在这里
    │   ├── CMakeLists.txt
    │   ├── lib
    │   │   └── libhello.a                          //生成后的静态库放在这里
    │   └── src
    │       ├── CMakeLists.txt
    │       ├── hello
    │       │   └── CMakeLists.txt
    │       └── main
    │           └── CMakeLists.txt
    ├── hello                                      //hello静态库的源代码
    │   └── hello.cpp
    ├── include                                   //头文件
    │   └── hello.h
    └── main                                     //可执行文件的源代码目录
        └── main.cpp

    首先,需要给CMake的一个总入口,这个CMake设置一些全局的变量(cmake/CMakeLists.txt):
    PROJECT(hello_3)
    SET(PROJECT_ROOT_PATH "${CMAKE_SOURCE_DIR}/../")                 #工程的根目录,即test
    SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin/")    #可执行生成后存放的目录(CMAKE_SOURCE_DIR是cmake目录)
    SET(LIBRARY_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/lib/")             #静态库生成后存放的目录

    INCLUDE_DIRECTORIES("${PROJECT_ROOT_PATH}/include/")            #告诉CMake头文件在哪里?

    LINK_DIRECTORIES("${CMAKE_SOURCE_DIR}/lib/")                             #告诉CMake静态库在哪里?

    ADD_SUBDIRECTORY(src)                                                                     #多目录,把src目录加进来,src里面才是真正编译main和hello的
    (b).src目录下的CMakeList.txt,这个CMake只是简单地把main目录和hello目录链接起来:
    ADD_SUBDIRECTORY(main)
    ADD_SUBDIRECTORY(hello)
    (c).hello静态库:
    FILE(GLOB SOURCE_1 "${PROJECT_ROOT_PATH}/hello/*.cpp")      #告诉CMake源文件在哪里?
    ADD_LIBRARY(hello STATIC ${SOURCE_1})                                       #告诉CMake生成的是一个静态库
     
    (d).main可执行文件:
    FILE(GLOB SOURCE_1 "${PROJECT_ROOT_PATH}/main/*.cpp")     #告诉CMake源文件在哪里?

    ADD_EXECUTABLE(main ${SOURCE_1})                                          #告诉CMake生成一个main可执行文件
    TARGET_LINK_LIBRARIES(main hello)                                              #告诉CMake静态库在哪里?



    每天早上叫醒你的不是闹钟,而是心中的梦~
  • 相关阅读:
    C#里的async和await的使用
    解决 .NET CORE3.0 MVC视图层不即时编译
    【转】CSS实现自适应分隔线的N种方法
    iscrolljs 看API 回顾以前开发中失误
    自由了-和过去说再见
    js 性能基准测试工具-告别可能、也许、大概这样更快更省
    dom事件不求甚解,色解事件捕获和冒泡
    百度mobile UI组件GMU demo学习1-结构和初始化
    自己收集原生js-2014-2-23
    如何在电脑上测试手机网站(补充)和phonegap
  • 原文地址:https://www.cnblogs.com/vintion/p/4117073.html
Copyright © 2020-2023  润新知