zoukankan      html  css  js  c++  java
  • Ubuntu下cmake教程实践从入门到会用

    如果你下载别人的开源代码,你会发现很多人的项目中有个CMakeLists.txt。其实这是因为他们用cmake这个软件来编译整个项目。

    为何要用cmake?
    如果不用cmake的话那么我们一般会用visual studio这种软件来编译运行整个项目。但是这里有个问题我visual studio2010的项目很可能vs2017打不开。这就很麻烦。于是人们开始想我能不能有个软件,我们写好各个模块的依赖关系,以及如何编译。把这些信息写成一个文件形式,然后这个软件能根据这个文件编译整个项目。并且最好能跨平台编译,比如我下载的代码要求既能在win10上编译也要能在win7上编译还得在linux上编译。并且编译后的可执行文件能兼容当前操作系统。没错。cmake都能做到。如果你下载的某个开源软件不兼容你的操作系统,最好的办法就是你下载它的源代码,然后在你的操作系统上重新编译运行一遍。

    案例1:cmake入门

    1.1 创建文件

    首先当然得安装cmake这个网上教程多如牛毛就不讲了。
    然后在当前目录下创建这两个文件(如下所示CMakeLists.txt这个文件名是固定的而且大小写不要错了,main.c是我们写的c语言代码):

    .
    ├── CMakeLists.txt
    └── main.c
    

    上述两个文件的内容分别如下:
    <文件CMakeLists.txt的内容>

    PROJECT(HELLO)
    AUX_SOURCE_DIRECTORY(. DIR_SRCS)
    ADD_EXECUTABLE(hello ${DIR_SRCS})
    

    注意:PROJECT()它是指定当前这个项目的名字,你可以随便写的没关系的。AUX_SOURCE_DIRECTORY()中的第一个参数是指定源文件所在文件夹(在本例子中是当前目录,就是一个点),第二个参数是把源文件夹所有源文件名存到DIR_SRCS这个变量中。ADD_EXECUTABLE()它指定的是把哪些源文件编译成目标文件。以及目标文件名叫啥。这这个例子中的目标文件名叫做hello你可以随便写的没关系的。但是后面那个源文件地址${DIR_SRCS}这个不能随便写,它的意思是读取DIR_SRCS这个变量的值(在本例子中这个变量值是源文件名)。

    <文件main.c的内容>

    #include<stdio.h>
    int main()
    {
        printf("hello world! my first cmake");
        return 0;
    }
    

    1.2 编译

    1. 把命令行的工作目录切换到在当前有CMakeLists.txt的这个目录下,
    2. 然后输入cmake ./,注意后面那是两个符号“点+斜杠”表示编译当前目录。你会发现你当前目录下多了很多文件。
    3. 然后输入make产生目标可执行文件。然后你会发现当前文件夹下面多了一个可执行文件hello。你可以试试./hello运行这个可执行文件。
    $ make
    Scanning dependencies of target hello
    [ 50%] Building C object CMakeFiles/hello.dir/main.c.o
    [100%] Linking C executable hello
    [100%] Built target hello
    

    到这里就完全入门了cmake,是不是很简单。但是你会发现源代码和目标文件以及编译的中间代码都在一个文件夹里面,这个就非常烦人。一般处理方式就是把源代码和目标文件分开。接下来就是介绍如何将源代码和目标文件分开编译。

    案例2:cmake工程化

    我们把源代码放在src这个文件夹内,bin目录暂时为空到时候把编译后的文件全放到bin文件夹中。记得在当前目录和src目录下面两个目录都要创建CMakeLists.txt

    .
    ├── bin
    ├── CMakeLists.txt
    └── src
        └── main.c
        ├── CMakeLists.txt
    

    当然当前目录下的CMakeLists.txt内容也需要变化(src目录下的CMakeLists.txt内容为空):

    PROJECT(HELLO)
    ADD_SUBDIRECTORY(src)
    AUX_SOURCE_DIRECTORY(./src DIR_SRCS)
    ADD_EXECUTABLE(hello ${DIR_SRCS}
    

    你会发现多了一行ADD_SUBDIRECTORY(src ),其中ADD_SUBDIRECTORY()的参数是源代码存放的文件夹。
    然后我们执行编译命令:cmake .,然后你会发现bin这个文件夹里面多了很多内容。接下来我们只需要进入到bin这个文件夹执行make命令来生成可执行文件。

    案例3:cmake使用头文件等外部依赖

    现在我们在案例2的基础上在src目录下增加一a.h头文件。

    .
    ├── bin
    ├── CMakeLists.txt
    └── src
        └── main.c
        ├── a.h
        ├── CMakeLists.txt
    
    

    然后src/CMakeLists.txt这个文件此时需要增加内容了:

    AUX_SOURCE_DIRECTORY(. LIB_FILES)       # 这个表示获取当前src目录下所有文件名并存入LIB_FILES这个变量中
    ADD_LIBRARY(LIBS ${LIB_FILES})                   # 这个表示将${LIB_FILES}这些文件加入库中,然后并且复制一份到LIBS这个变量中
    

    项目根目录下的CMakeLists.txt的文件内容也需要改动:

    PROJECT(HELLO)
    AUX_SOURCE_DIRECTORY(./src DIR_SRCS)
    ADD_EXECUTABLE(hello ${DIR_SRCS})   
    TARGET_LINK_LIBRARIES(hello ${LIBS}) # 向可执行文件hello提供链接库LIBS是前面提到的变量
    

    cmake编译生成中间代码,以及make编译生成目标可执行文件和前面的操作一样。都是回到项目根目录下:
    输入:

    $ cmake .
    $ make
    

    参考文献:
    [1] https://www.ibm.com/developerworks/cn/linux/l-cn-cmake/

    知乎 https://www.zhihu.com/people/yuanmuou/activities
  • 相关阅读:
    人一生最后悔五件事
    C# 实现程序只启动一次(多次运行激活第一个实例,使其获得焦点,并在最前端显示)
    socket 编程 学习2
    Linux内核源码阅读以及工具(转)
    迭代法
    C语言程序设计 C语言中的时间函数(转)
    线段的平移
    数独(sudoku)的生成与破解(转)
    PageBase,ControlBase,Base Class
    Oracle “万年虫”
  • 原文地址:https://www.cnblogs.com/ailitao/p/11047270.html
Copyright © 2011-2022 走看看