cmake是linux平台下重要的工具,可以方便的组织makefile。之前一直在windows平台下进行软件开发,在vs2010的IDE里,只要一点run程序就能跑出结果。但是程序的编译并没有那么简单。
写一个程序大约可以分为以下几个部分

  1. coding,写代码,可以写在记事本里。
  2. 组织编译文件。说明各个代码文件之间的关系。
  3. make&link,根据组织好的编译文件和连接关系,将编译好的碎片组织成一个完整的可执行文件。

cmake完成的工作就组织编译文件,说明代码对库的调用关系以便于代码对库进行链接。

helloworld

用cmake组织一个helloworld程序是开始cmake学习的基础。首先要有两个文件夹,一个存放源文件一个存放build之后得到的文件。
文件夹组织为
project
├── build
└── src
├── CMakeLists.txt
└── hello.cpp

其中src中存放.cpp文件和CMakeLists.txt文件。这里尤其要注意一点

  1. 如果用了c++的库,那么必须写成.cpp,否则会无法识别c++的库函数如cout
  2. CMakeLists.txt一定不能拼错!!!!!头两个字母都是大写,最后有s,文件格式是.txt
project(HELLO)
set(SRC_LIST hello.cpp)
add_executable(hello ${SRC_LIST})

CMakeLists.txt文件
可以看出CMakeLists.txt的编写方式还是处处表达它的unix基因,变量定义和取值的方式都和shellscript精神相呼应。

  1. 关键字set用来定义变量这里既可以用SRC_LIST也可用其他字母,但是最好好记。
  2. add_executable语句用来生成可执行文件
  3. CMakeLists.txt里的add表达的大多是生成的意思。${SRC_LIST}是取值的意思,和linux变量取值一样~~~

#include <iostream>
using namespace std;
int main()
{
cout<<"hello world"<<endl;
return 1;
}

hello.cpp文件


这里的main函数似乎不能使用void定义,否则会提示main函数必须有返回值,应该是编译器的问题。

分离式编程

分离式编程指的是分开函数,头文件,main函数并把它放在不同的文件中的编程方式。好处是文件层次分明,方便管理和代码重用。
文件结构如下
project
├── build
└── src
├── CMakeLists.txt
├── function.cpp
├── function.h
├── hello.cpp
└── main.cpp


其中CMakeLists.txt里的内容为

project(HELLO)
set(SRC_LIST main.cpp function.cpp)
add_executable (hello ${SRC_LIST})

可以看出,这里除了添加了main.cpp之外还添加了function.cpp,但是注意没有.h文件什么事。

如果用qt 打开CMakeLists.txt的话,在文件组织里是会显示.h文件的。

.h文件里包含了头文件iostream,并声明了打印函数,在function.cpp中完成了打印函数的定义。

多文件夹分离式编译

所实现的功能一多就很麻烦,需要很多代码。代码都混在一起是一件很纠结的事情,所以使用不同的文件夹存放代码。
project5
├── build
├── CMakeLists.txt
├── lib
│ ├── CMakeLists.txt
│ ├── CMakeLists.txt~
│ ├── function.cpp
│ └── function.h
└── src
├── CMakeLists.txt
├── CMakeLists.txt~
└── main.cpp

这里可以看出,在工程文件夹下有build文件夹,lib文件夹,src文件夹三种,每个文件夹下都要有CMakeLists.txt来说明文件夹之间的关系和文件夹内容。

project文件夹下:总CMakeLists.txt

project(HELLO)
add_subdirectory(lib)
add_subdirectory(src)

这里有生成子目录lib和子目录src,这个子目录是在build文件夹下,不是工程文件夹下。

lib文件夹下: 库CMakeLists.txt

set(LIB_SRC function.cpp)
add_library (libhello ${LIB_SRC})
set(PROJECT_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
  1. 设置编译生成库的源文件
  2. 生成库
  3. 设置库的输出目录,其中PROJECT_BINARY_DIR,是指工程二进制文件目录,简而言之,build目录。

在CMakeGUI中第二个选项是where to build the binaries,选了build。

src文件夹下:源文件CMakeLists.txt

include_directories(${PROJECT_SOURCE_DIR}/lib)
#link_directories(${PROJECT_BINARY_DIR}/lib)
set(APP_SRC main.cpp)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
add_executable (hello ${APP_SRC})
target_link_libraries(hello libhello)
  1. 头文件所在位置。PROJECT_SOURCE_DIR是在CMakeGUI中选择的源文件所在位置。
  2. 库文件所在位置,原本库文件直接生成在build文件夹中,就不需要此句。但是现在修改了库文件输出位置,必须重新说明。
  3. 设置变量APP_SRC的内容
  4. 设置可执行文件输出位置
  5. 生成可执行文件hello,其变量是APP_SRC
  6. 设置可执行文件所要链接的库。

下面是完整的源代码
main.cpp

#include "function.h"
int main()
{
print();
return 0;
}

function.cpp

#include "function.h"
using namespace std;
int print()
{
cout<<"this is a cmakeprogram"<<endl;
return 0;
}

function.h

#include <iostream>
int print();

动态链接库

把add_library(XXlib XXXX)改成addlibrary(XXlibSHARED{XXXX})

版权声明:本文为博主原创文章,未经博主允许不得转载。

CMake学习(1)---简单程序与库的更多相关文章

  1. CMake - boost - 可运行程序 - 静态库

    CMake - boost 最后更新日期:2014-04-25by kagula 阅读前提:<CMake入门(二)>.Linux的基本操作 环境: Windows 8.1 64bit英文版 ...

  2. c++学习笔记2(c++简单程序)

    c++的简单程序 练习一: #include <iostream>int main(){std::cout<<"你好c++\n";int x;std::ci ...

  3. 《从0到1学习Flink》—— Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门

    准备工作 1.安装查看 Java 的版本号,推荐使用 Java 8. 安装 Flink 2.在 Mac OS X 上安装 Flink 是非常方便的.推荐通过 homebrew 来安装. brew in ...

  4. 学习用CMake来编写Qt程序

    最近开始学习CMake,因为项目需求需要用到Qt,自带的qmake会出现许多问题(比如文件修改之后有时候qmake不会侦测到不会重新编译,需要手动去编译等),于是开始尝试使用CMake来编写Qt程序, ...

  5. cmake 学习笔记(一)

    最大的Qt4程序群(KDE4)采用cmake作为构建系统 Qt4的python绑定(pyside)采用了cmake作为构建系统 开源的图像处理库 opencv 采用cmake 作为构建系统 ... 看 ...

  6. 一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库 RxJava,相当好

    https://github.com/ReactiveX/RxJava https://github.com/ReactiveX/RxAndroid RX (Reactive Extensions,响 ...

  7. cmake学习笔记(五)

    在cmake 学习笔记(三) 中简单学习了 find_package 的 model 模式,在cmake 学习笔记(四)中了解一个CMakeCache相关的东西.但靠这些知识还是不能看懂PySide使 ...

  8. cmake 学习笔记(二)

    在 Cmake学习笔记一 中通过一串小例子简单学习了cmake 的使用方式. 这次应该简单看看语法和常用的命令了. 简单的语法 注释 # 我是注释 命令语法 COMMAND(参数1 参数2 ...) ...

  9. Linux学习笔记——如何使用共享库交叉编译

    0.前言     在较为复杂的项目中会利用到交叉编译得到的共享库(*.so文件).在这样的情况下便会产生下面疑问,比如:     [1]交叉编译时的共享库是否须要放置于目标板中,假设须要放置在哪个文件 ...

随机推荐

  1. 优化C++程序编译效率的一些方法

    优化是一件非常重要的事情.作为一个程序设计者,你肯定希望自己的程序既小又快.DOS时代的许多书中都提到,“某某编译器能够生成非常紧凑的代码”,换言之,编译器会为你把代码尽可能地缩减,如果你能够正确地使 ...

  2. 从零开始学ios开发(十九):Application Settings and User Defaults(上)

    在iphone和ipad中,有一个东西大家一定很熟悉,那个东西就是Settings. 这次要学习的东西说白了很简单,就是学习如何在Settings中对一个app的某些属性进行设置,反过来,在app中更 ...

  3. [转] c和python利用setsockopt获得端口重用

    假如端口被socket使用过,并且利用socket.close()来关闭连接,但此时端口还没有释放,要经过一个TIME_WAIT的过程之后才能使用.为了实现端口的马上复用,可以选择setsockopt ...

  4. 11.1Daily Scrum

    人员 任务分配完成情况 明天任务分配 王皓南 主网页的框架搭建,任务编号760 研究代码,学习相应语言,讨论设计思路 申开亮 学习数据库的操作,任务编号761 研究代码,学习相应语言,讨论设计思路 王 ...

  5. SSH与EJB 比较

    SSH完全的开源产品,如果用SSH就必然会用到大量的开源的东东,从数据库到逻辑到控制到前端,开源产品大拼装, 其中SSH中的三大核心,Struts相当于JSF,spring相当于EJB,hiberna ...

  6. 例题-文件系统的放大 (LVM):

    纯粹假设的,我们的 /home 不够用了,你想要将 /home 放大到 7GB 可不可行啊? 答: 因为当初就担心这个问题,所以 /home 已经是 LVM 的方式来管理了.此时我们要来瞧瞧 VG 够 ...

  7. c++ uuid生成法则

    http://www.jb51.net/LINUXjishu/39614.html CentOS #include <uuid/uuid.h> 找不到文件解决方法: sudo yum in ...

  8. ?--Porg.springframework.beans.MethodInvocationException: Property 'username' threw exception; nested exception is java.lang.NullPointerException

    使用BoneCP作为连接池,在启动Tomcat报出以下异常: 一月 02, 2016 2:12:17 下午 org.apache.tomcat.util.digester.SetPropertiesR ...

  9. MemSQL Start[c]UP 2.0 - Round 1

    A. Eevee http://codeforces.com/contest/452/problem/A 字符串水题 #include<cstdio> #include<cstrin ...

  10. 请求--拦截器--action经过

    引用我这里想知道的是同名的多个参数,会被自动的放置在List或者数组中,我想知道是怎么实现的,因为取一个参数和取多个同名的参数是不同的方法: 一个是request.getParameter 一个是re ...