zoukankan      html  css  js  c++  java
  • 310实验室(六)CMake学习心得

    树形结构方式布局。

    OTL 中每一个文件中的CMakeLists.txt 有不同的作用:按查看文件的先后顺便进行分层理解, 根文件即第一次 中的.txt是 启用 CMAKE_MODULE_PATH模板,加载相关文件,每一层的.txt负责创建同一层不同文件夹的子目录。如:add_subdirectory("${CMAKE_SOURCE_DIR}/Test"). 然后进入第二层,在第一层创建了相应文件夹的子目录中再进行遍历,具体与第一层类似。在遍历文件的数据结构类似树的结点,如 对Test文件进行遍历,首先设置路径: set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin/test"},然后将路径加载到list_projects中 list_projects("${CMAKE_CURRENT_SOURCE_DIR}"),最后循环遍历每一个子文件。foreach(PROJECT_ITEM ${PROJECT_LIST})

      message("Adding test: " " ${PROJECT_ITEM}")

      add_subdirectory("${PROJECT_ITEM}")

    endforeach()

    3.Cmake使用

    3.1.单个文件示例

        下面是一个简单的C程序代码(打印“helloworld!”字符串):
    #include <stdio.h>
     
    int main(void)
    {
       printf("hello world!
    ");
       return 0;
    }
       在H:CmakeTest目录下创建一个Exp1目录,在该目录下创建一个main.c文件,内容为上面的C程序代码,然后再创建一个CMakeLists.txt文件,内容如下:
    PROJECT (HELLO)
    SET (SRC_LIST main.c)
    ADD_EXECUTABLE (hello ${SRC_LIST})
       最后,在Exp1目录中创建一个build子目录,进入build目录,调用cmake命令自动生成项目文件,然后执行nmake进行编译生成可执行文件:
    H:CmakeTestExp1> mkdir build & cdbuild
    H:CmakeTestExp1uild> cmake ..-G"NMake Makefiles”
    H:CmakeTestExp1uild> nmake
       注1:为了简单起见,上面采用cmake的Out-Of-Source方式构建,即生成的中间产物和代码相分离。
       注2:必须使用“VisualStudio 2008 Command Line”快捷方式打开命令行窗口,然后执行上面的命令,否则不能创建“NMake Makefiles”的项目。
       注3:如果使用MinGW开发环境进行编译,执行下面的cmake命令:
    #> cmake .. -G”MinGW Makefiles”
    #> make
       nmake编译完成后,在当前目录下会生成一个hello.exe,运行它会在屏幕上打印“hello world!”字符串。
    H:CmakeTestExp1uild>hello.exe
    hello world!
       此时,目录结构如下:
    H:CMAKETESTEXP1
    │  CMakeLists.txt
    │  main.c
    │
    └─build
        │  CMakeCache.txt
        │  cmake_install.cmake
        │  hello.exe   
        │  ……
       CMakeLists.txt文件说明:
       第一行PROJECT不是强制性的,推荐使用,这一行会引入两个变量HELLO_BINARY_DIR和HELLO_SOURCE_DIR。同时cmake自动定义了两个等价的变量PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR。由于基于Out-Of-Source方式构建,务必注意这两个变量对应的目录,可以通过MESSAGE来输出变量的值,例如:MESSAGE(${PROJECT_SOURCE_DIR})。
       SET命令用于设置变量。
       ADD_EXECUTABLE命令用于告诉工程生成一个可执行文件。
       ADD_LIBRARY命令用于告诉工程生成一个库文件。
       注意:CMakeLists.txt文件中,命令的名称是不区分大小写的,而参数和变量名是大小写敏感的。
       Cmake命令说明:
        Cmake命令后面跟一个路径参数,它用来指定CMakeLists文件所在的位置。
        由于系统中可能有多套构建工程的开发环境,我们可以通过-G命令行参数来指定生成那种工程,你可以通过cmake --help命令获得-G参数的详细信息。
        如果要显示执行构建工程过程中详细信息,可以在CMakeLists.txt文件中加入:
    SET (CMAKE_VERBOSE_MAKEFILEon)
      或者执行make时:
    $ make VERBOSE=1
      或者
    $ exportVERBOSE=1
    $ make

    3.2.多个文件示例

        下面针对多个文件构建工程,假设有hello.h/hello.c/main.c三个源代码文件,如下所示:
    Hello.h代码:
    #ifndef __HELLO_H__
    #define __HELLO_H__
    void hello(const char *name);
    #endif
    Hello.c代码:
    #include "hello.h"
    #include <stdio.h>
     
    void hello(const char *name)
    {
        printf("hello%s!
    ", name);
    }
    Main.c代码:
    #include "hello.h"
     
    int main(void)
    {
        hello("world");
        return 0;
    }
      在CMakeTest目录下创建Exp2目录,并且在Exp2目录中创建上面的三个源代码文件,然后再创建CMakeLists.txt文件,内容如下:
    PROJECT(HELLO)
    SET(SRC_LIST main.c hello.c)
    ADD_EXECUTABLE (hello ${SRC_LIST})
       创建build目录,进入到该目录进行构建,如下所示:
    H:CmakeTestExp2>mkdirbuild & cd build
    H:CmakeTestExp2uild>cmake.. -G"NMake Makefiles"
        构建完成后使用nmake进行编译生成hello程序,然后运行程序如下所示:
    H:CmakeTestExp2uild>nmake
    H:CmakeTestExp2uild>hello
    hello world!
        Exp2的目录结构如下所示:
    H:CMAKETESTEXP2
    │  CMakeLists.txt
    │  hello.c
    │  hello.h
    │  main.c
    │
    └─build
        │  CMakeCache.txt
        │  cmake_install.cmake
        │  hello.exe

    3.3.生成库文件示例

        还是使用上面例子中多个源代码,这里我们将hello.c生成一个库,然后在main.c中调用。修改CMakeLists.txt文件如下:
    PROJECT (HELLO)
    SET(SRC_LIBhello.c)
    SET(SRC_APPmain.c)
    ADD_LIBRARY(libhello ${SRC_LIB})
    ADD_EXECUTABLE(hello ${SRC_APP})
    TARGET_LINK_LIBRARIES(hellolibhello)
        在上面的文件中,我们添加一个新的目标库libhello,并且把它链接到hello程序中。
        注:在CMakeTest目录下创建一个Exp3目录,然后把Exp2目录中除build目录以外的4个文件拷贝到该目录下,最后修改CMakeLists.txt文件内容。
        创建一个build目录进行构建工程:
    H:CmakeTestExp3>mkdirbuild & cd build
    H:CmakeTestExp3uild>cmake.. -G"NMake Makefiles"
    H:CmakeTestExp3uild>hello.exe
       由于可执行程序使用hello这个名称,此时添加类时就不能使用这个名称,而是使用libhello,此时编译生成的库名为libhello.lib,如果希望生成hello.lib库,添加下面一行:
    SET_TARGET_PROPERTIES(libhelloPROPERTIES OUTPUT_NAME “hello”)
       注意:推荐添加设置选项为cmake_minimum_required(VERSION2.8)。

    3.4.多个目录示例

        源文件位于多个目录情况下构建工程,源代码放置于不同路径下的结构如下:
    H:CMAKETESTEXP4
    │  CMakeLists.txt
    │
    ├─build
    ├─libhello
    │      CMakeLists.txt
    │      hello.c
    │      hello.h
    │
    └─src
           CMakeLists.txt
           main.c
        Exp4目录下的CMakeLists.txt文件,内容如下:
    CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
    PROJECT(HELLO)
    ADD_SUBDIRECTORY(src)
    ADD_SUBDIRECTORY(libhello)
        Src目录下的CMakeLists.txt文件,内容如下:
    CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
    INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/libhello)
    SET(SRC_APP main.c)
    ADD_EXECUTABLE(hello${SRC_APP})
    TARGET_LINK_LIBRARIES(hellolibhello)
        Libhello目录下CMakeLists.txt文件,内容如下:
    CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
    SET(SRC_LIB hello.c)
    ADD_LIBRARY(libhello ${SRC_LIB})
    SET_TARGET_PROPERTIES(libhello PROPERTIES OUTPUT_NAME"hello")
        建立build目录构建工程,在build目录中执行下面命令:
    H:CmakeTestExp4uild>cmake .. -G"NMake Makefiles"
    H:CmakeTestExp4uild>nmake
    H:CmakeTestExp4uild>srchello
        生成的执行文件位于buildsrc目录中,库文件位于buildlibhello目录中。
       在Exp4目录中的CMakeLists.txt文件中:
       ADD_SUBDIRECTORY命令用来告诉cmake去子目录中查找可用的CMakeLists.txt文件。
       在Src目录中的CMakeLists.txt文件中:
       INCLUDE_DIRECTORIES命令用来指明头文件所在的路径。

    3.5.指定输出目录示例

         要求把生成的可执行文件和库文件分别输出到bin目录和lib目录下,目录结构如下:
    H:CMAKETESTEXP5
    │  CMakeLists.txt
    │
    ├─build
    │  ├─bin
    │  └─lib
    ├─libhello
    │      CMakeLists.txt
    │      hello.c
    │      hello.h
    │
    └─src
            CMakeLists.txt
            main.c
        第一种方法,修改Exp5目录下的CMakeLists.txt文件,如下所示:
    CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
    PROJECT(HELLO)
    ADD_SUBDIRECTORY(src bin)
    ADD_SUBDIRECTORY(libhello lib)
        这种方法在build目录下生成bin和lib目录替换上例中src和libhello目录,不满足要求。
        第二种方法,不修改顶级文件,修改其它两个文件,如下:
        src/CMakeLists.txt文件:
    CMAKE_MINIMUM_REQUIRED (VERSION2.8)
    INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/libhello)
    #LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lib)
    SET(SRC_APP main.c)
    SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
    ADD_EXECUTABLE(hello ${SRC_APP})
    TARGET_LINK_LIBRARIES(hello libhello)
        libhello/CMakeLists.txt文件:
    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
    SET(SRC_LIB hello.c)
    ADD_LIBRARY(libhello ${SRC_LIB})
    SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
    SET_TARGET_PROPERTIES(libhello PROPERTIES OUTPUT_NAME"hello")
        上面主要是设置LIBRARY_OUTPUT_PATH和EXECUTABLE_OUTPUT_PATH两个环境变量。
        在build目录下使用cmake构建工程,nmake进行编译,命令如下:
    H:CmakeTestExp4uild>cmake.. -G"NMake Makefiles"
    H:CmakeTestExp4uild>nmake

    3.6.编译动态库示例

        上述示例中都是使用静态库,下面考虑下如何编译成动态库。
        如果不是Windows操作系统,Linux/Unix下生成动态库很容易,只要修改下libhello/CMakeLists.txt文件中的ADD_LIBRARY命令(添加SHARED参数)即可,如下所示:
    ADD_LIBRARY(librarySHARED ${SRC_LIB})
        如果要做到Windows和Linux下可移植性,需要修改hello.h的头文件,如下所示:
    #ifndef__HELLO_H__
    #define__HELLO_H__
    #ifdef WIN32
    #ifLIBHELLO_BUILD
    #defineLIBHELLO_API __declspec(dllexport)
    #else
    #define LIBHELLO_API__declspec(dllimport)
    #endif
    #else
    #defineLIBHELLO_API
    #endif
    LIBHELLO_APIvoid hello(const char *name);
    #endif
        修改libhello/CMakeLists.txt文件
    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
    SET(SRC_LIBhello.c)
    ADD_DEFINITIONS("-DLIBHELLO_BUILD")
    ADD_LIBRARY(libhelloSHARED${SRC_LIB})
    SET(LIBRARY_OUTPUT_PATH${PROJECT_BINARY_DIR}/lib)
    SET_TARGET_PROPERTIES(libhelloPROPERTIES OUTPUT_NAME "hello")
        接下来可以在build目录下使用cmake进行构建,构建完成后就可以编译和执行。
    H:CmakeTestExp6uild>cmake.. -G"NMake Makefiles"
    H:CmakeTestExp6uild>nmake
        注:在bin目录下的hello.exe无法运行,必须先把lib目录下的hello.dll拷贝到bin目录才能正常运行。
    转载:http://blog.csdn.net/fan_hai_ping/article/details/8208898
  • 相关阅读:
    Pyhton 单行、多行注释方法
    laravel中不使用 remember_token时退出报错,如何解决?
    PHP实现打印出库单,有没有实现过?
    是不等号的意思
    PHP如何输出合并单元格的表
    一起谈.NET技术,.Net创建Excel文件(插入数据、修改格式、生成图表)的方法 狼人:
    一起谈.NET技术,ASP.NET MVC 通过 FileResult 向浏览器发送文件 狼人:
    一起谈.NET技术,asp.net Ajax AutoComplete控件使用 狼人:
    一起谈.NET技术,Silverlight 拖动复制控件 狼人:
    一起谈.NET技术,ASP.NET Process Model之二:ASP.NET Http Runtime Pipeline[上篇] 狼人:
  • 原文地址:https://www.cnblogs.com/hoojjack/p/4441866.html
Copyright © 2011-2022 走看看