CMake是一个跨平台的Makefile生成工具,可以根据特定的规则生成相应的Makefile文件,并对C/C++源代码进行编译和管理。

有一篇博客介绍CMake的使用,比较通俗易懂,链接地址是:Cmake 详解

CMake的官方下载地址为:https://cmake.org/download/

官方文档地址为:CMake 3.16 Documentation

官方的CMake指南地址为:CMake Tutorial

一、CMake中添加对C++11的支持

1、在对应的CMakeLists.txt文件中加入以下语句:

add_definitions(-std=c++11)

或者

 if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-std=c++11 -g ${CMAKE_CXX_FLAGS}")
endif(CMAKE_COMPILER_IS_GNUCXX)

2、延伸 如何写cmake使其包含c++11特性 (-std=c++11如何写进cmakeList.txt)

使用的g++版本和cmake版本分别是g++ 4.8.2和cmake 2.8

之前写cmkae编译带有c++11特性的代码有这么一句:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

但是总会出现cc1plus: error: unrecognized command line option “-std=c++11” 报错。

所以set(QMAKE_CXXFLAGS “-std=c++11”) 类似的写法肯定不行。

后来发现是std=c++11 这种写法老版本不支持。

ok

直接测试新写法 CMakeLists.txt文件如下所示:

#CMakeLists.txt
project(test)
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST}${PROJECT_NAME}.cpp) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

测试c++11代码如下:

//test.cc
#include <iostream>
#include<vector>
using namespace std;
int main()
{
const std::vector<int>v(1);
auto a = v[0];//a为int类型
cout <<"a : "<< a <<endl;
decltype(v[0]) b = 0;//b为const int&类型,即std::vector<int>::operator[](size_type)const的返回类型
auto c = 0;//c为int类型
auto d = c;//d为int类型
decltype(c) e;//e为int类型,c实体的类型
decltype((c)) f = e;//f为int&类型,因为(c)是左值
decltype(0) g;//g为int类型,因为0是右值 return 0;
}

examples_CMake项目

github上面有一个韩国人jacking75写的简单的cmake使用示例,

examples_CMake项目地址是:https://github.com/jacking75/examples_CMake

CMake例子

范例介绍

示例代码在CMake_example目录中。

01 helloworld 一个简单文件中的-C ++代码
  • main.cpp
#include <iostream>

int main()
{
auto name = "jacking";
std::cout << "hello world: " << name << std::endl;
return 0;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_definitions(-std=c++11)
add_executable(Main main.cpp)
02 helloworld-设置编译器选项。 -Wall,C ++ 14
  • main.cpp
#include <iostream>

int main()
{
auto name = "jacking";
std::cout << "hello world: " << name << std::endl;
return 0;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_definitions("-Wall -std=c++14")
add_executable(Main main.cpp)
03 helloworld-如果您有除主代码文件以外的其他代码文件
  • main.cpp
#include "test.h"

int main()
{
TEST test;
test.Print();
return 0;
}
  • test.h
class TEST
{
public:
void Print();
};
  • test.cpp
#include "test.h"

#include <iostream>

void TEST::Print()
{
std::cout << "Test::Print" << std::endl;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_executable(Main
main.cpp
test.cpp
)
04 helloworld-如果mai.cpp以外的文件位于其他目录中

源代码04_helloworld目录结构如下:

[root@ltcos01 04_helloworld]$ tree -L 2
.
├── CMakeLists.txt
├── main.cpp
├── test01
│ ├── test01.cpp
│ └── test01.h
└── test02
├── test02.cpp
└── test02.h 2 directories, 6 files
  • main.cpp
#include "test01/test01.h"
#include "test02/test02.h" int main()
{
TEST01 test01;
test01.Print(); TEST02 test02;
test02.Print();
return 0;
}

test01目录下 有test01.h和test01.cpp这两个文件

  • test01/test01.h
class TEST01
{
public:
void Print();
};
  • test01/test01.cpp
#include "test01.h"
#include <iostream> void TEST01::Print()
{
std::cout << "Test01::Print" << std::endl;
}

test02目录下有test02.h和test02.cpp这两个文件

  • test02/test02.h
class TEST02
{
public:
void Print();
};
  • test02/test02.cpp
#include "test02.h"
#include <iostream> void TEST02::Print()
{
std::cout << "Test02::Print" << std::endl;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_executable(Main
main.cpp
test01/test01.cpp
test02/test02.cpp
)
05 helloworld-reference 创建静态文件后

05_helloworld源代码目录树结构如下所示:

[root@ltcos01 05_helloworld]$ tree -L 2
.
├── CMakeLists.txt
├── main.cpp
├── test01
│ ├── CMakeLists.txt
│ ├── test01.cpp
│ └── test01.h
└── test02
├── CMakeLists.txt
├── test02.cpp
└── test02.h 2 directories, 8 files
  • main.cpp
#include "test01/test01.h"
#include "test02/test02.h" int main()
{
TEST01 test01;
test01.Print(); TEST02 test02;
test02.Print();
return 0;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_subdirectory(test01)
add_subdirectory(test02)
add_executable(Main main.cpp)
target_link_libraries(Main Test01 Test02)

test01目录下有test01.h和test01.cpp以及相应的CMakeLists.txt文件

  • test01/test01.h
class TEST01
{
public:
void Print();
};
  • test01/test01.cpp
#include "test01.h"

#include <iostream>

void TEST01::Print()
{
std::cout << "Test01::Print" << std::endl;
}
  • test01/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_library(Test01 STATIC
test01.cpp
)

上面的test01目录下的CMakeLists.txt的add_library(Test01 STATIC test01.cpp)指令会生成相应的静态库文件libTest01.a

test02目录下和test01目录结构一样,也有test02.h和test02.cpp以及相应的CMakeLists.txt文件

  • test01/test02.h
class TEST02
{
public:
void Print();
};
  • test02/test02.cpp
#include "test02.h"

#include <iostream>

void TEST02::Print()
{
std::cout << "Test02::Print" << std::endl;
}
  • test02/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_library(Test02 STATIC
test02.cpp
)

同样的,在上面的test02目录下执行cmake命令会生成相应的静态库文件libTest02.a。具体操作过程如下:新建一个build目录,然后进入到build目录下执行cmake …运行上一级目录即test02下的CMakeLists.txt文件,操作如下:

[root@ltcos01 test02]$ ls
build CMakeLists.txt test02.cpp test02.h
[root@ltcos01 test02]$ cd build/
[root@ltcos01 build]$ ls
[root@ltcos01 build]$ cmake ..
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /data/public/home/cchufeng/GithubProjects/examples_CMake/CMake_example/05_helloworld/test02/build
[root@ltcos01 build]$ make
Scanning dependencies of target Test02
[ 50%] Building CXX object CMakeFiles/Test02.dir/test02.cpp.o
[100%] Linking CXX static library libTest02.a
[100%] Built target Test02
[root@ltcos01 build]$ ls
CMakeCache.txt CMakeFiles cmake_install.cmake libTest02.a Makefile
[root@ltcos01 build]$
06 helloworld-指定编译器
  • main.cpp
#include <iostream>

int main()
{
auto name = "jacking";
std::cout << "hello world: " << name << std::endl;
return 0;
}
  • CMakeLists.txt
PROJECT(hello)

set(CMAKE_CXX_COMPILER g++)
add_definitions("-Wall -std=c++14") ADD_EXECUTABLE(main main.cpp)
07 helloworld-使用外部库(此处为Boost库)
  • main.cpp
#include <boost/thread.hpp>
#include <iostream> int main()
{
std::cout << "Boost.Thread !!!" << std::endl;
boost::thread Thread1( [] ()
{
for( int i = 0; i < 5; ++i )
{
std::cout << "Thread Num : " << i << std::endl;
}
} ); Thread1.join();
return 0;
}
  • CMakeLists.txt
PROJECT(hello)

set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_FLAGS "-m64")
add_definitions("-Wall -std=c++14") INCLUDE_DIRECTORIES(/$ENV{HOME}/Dev/C++/ThirdParty/boost_1_60_0)
LINK_DIRECTORIES(/$ENV{HOME}/Dev/C++/ThirdParty/boost_1_60_0/stage/gcc/lib) ADD_EXECUTABLE(hello-boost hello-boost.cpp) TARGET_LINK_LIBRARIES(hello-boost pthread boost_thread boost_system boost_chrono)

C++中使用CMake编译管理项目的更多相关文章

  1. AndroidNDK开发中使用CMake编译JNI

    虽然一直在做NDK的开发工作,但是由于项目比较久远,都是使用Makefile进行底层编译,对于目前AndroidStudio官方提供的CMake编译方式并不是很了解,现在学习下这种已经不算新潮的新方式 ...

  2. 在linux中使用cmake编译运行cocos2d-x 3.4 projects

    原因: 由于不想在真机环境和 ide中调试环境, 只想在linux端进行 调试和运行, 需要使用cmake对现有的游戏进行编译(cocos2dx-lua 3.4) 修改步骤: 1.修改framewor ...

  3. eclipse中设置在编译运行项目之前自动保存修改的文件

    Window -> Preferences -> General -> Workspace -> “Save automatically before build” Windo ...

  4. 用CMAKE编译配置的项目进行调试的方法

    在Linux 下用CMAKE编译的项目进行Debug 需进行设置: 1.在未设置之前 进行调试可能会出现错误报告:No source available for ...等一系列错误,这些错误可能就是你 ...

  5. 管理项目中的贴图-Texture overview插件

    Texture overview插件管理项目中的贴图 1. Assetstore地址 2. 总览项目中所有贴图 3. 针对不同平台的贴图压缩设置 在插件的右上角 4. 支持多选批量修改 5. 点击表头 ...

  6. 在Eclipse中编译maven项目出的问题

    在Eclipse中编译Maven项目,运行 jetty:run 指令的时候会出错,在 JRE选项卡中加入: -Dorg.mortbay.util.URI.charset=GBK-Xms512m -Xm ...

  7. 如何使用cygwin去编译cocos2dx项目中的C++文件

    将生成的cocos2dx的Android项目导入到eclipse 可以先测试一下如何编译C++项目: 1.打开cygwin,进入到Android项目对应的目录下面去: 2.编译脚本 在编译脚本之间,如 ...

  8. itest 开源测试管理项目中封装的下拉列表小组件:实现下拉列表使用者前后端0行代码

    导读: 主要从4个方面来阐述,1:背景:2:思路:3:代码实现:4:使用 一:封装背景       像easy ui 之类的纯前端组件,也有下拉列表组件,但是使用的时候,每个下拉列表,要配一个URL ...

  9. VS2013中Nuget程序包管理器控制台使用入门(三)-项目实战(原创)

    VS2013中Nuget程序包管理器控制台使用入门(三)-项目实战 1.给指定项目安装Newtonsoft.Json ,Version 4.5.11 PM> Install-Package Ne ...

随机推荐

  1. HTML5-video(播放暂停视频;打开关闭声音;进度条)

    <!DOCTYPE html> <html> <head> <title>HTML5-video(播放暂停视频:打开关闭声音:进度条)</titl ...

  2. ZPL文件打印

    ZPL:全称是Zebra Printer Language,目前能够直接打印zpl文件的打印机只有斑马打印机 如何打印zpl文件呢? 软件类: 一.Print Conductor(桌面打印软件) ht ...

  3. JavaScript、ES6中的类和对象

           面向对象可以用于描述现实世界的事物,但是事物分为具体的(特指的)事物和抽象的(泛指的)事物. 面向对象思维的特点: 1.抽取(抽象)对象共有的属性和行为组织(封装)成一个类(模板) 2. ...

  4. JSP学习(3)

    JSP学习(3) JSP内置对象 Web容器创建的一组对象,不使用new关键字就可以使用的内置对象 用户服务器请求 缓冲区:Buffer,就是内存的一块区域,用来保存临时数据. get与post的区别 ...

  5. 十大热门AI芯片

    资料来源:头条<人工智能影响力报告>中的人工智能十大热门芯片 iPhone X内部搭载了一颗全新定制的处理器——A11 Boinic,用来承担人脸识别和移动支付的工作负荷.双核心A11芯片 ...

  6. 脚本_修改 Linux 系统的最大打开文件数量

    #!bin/bash#作者:liusingbon#功能:修改 Linux 系统的最大打开文件数量#追加两行配置参数到文件/etc/security/limits.conf的末尾,修改最大打开文件数量为 ...

  7. Centos 7 环境下安装 RabbitMQ 3.6.10

    一.单机安装 在Centos7系统下部署(阿里云服务),使用yum安装 hostnamectl set-hostname rabbit01 #永久修改 1.1安装Erlang,因为RabbitMQ 是 ...

  8. 03scikit-learn非监督学习

    In [1]: from sklearn.decomposition import PCA from sklearn.datasets import load_iris pca = PCA(n_com ...

  9. 美国的科技公司是如何使用加密的DNS

    加密设备和“以隐私为中心”的提供商之间的DNS流量可以阻止某人窥探您的浏览器所指向的位置,或者使用DNS攻击将其发送到其他地方. 该网络中立性的死亡和法规对互联网服务供应商如何处理客户的网络流量的松动 ...

  10. 利用docker制作一个带有redis软件的镜像,供其他人使用

    1. 宿主机在etc/apt/下创建一个haha的文件夹 2.宿主机将haha文件夹映射到容器的虚拟系统中etc/apt/ 3. 此时,可以在宿主机和容器虚拟机中同步创建和删除文件 4. 将宿主机中的 ...