CMake is a cross-platform Makefile generation tool that can generate corresponding Makefiles according to specific rules and compile and manage C/C++ source code. There are two blog posts about CMake that are easy to understand.

  • Cmake,
  • CMake entry combat
  • The official download address of CMake is cmake.org/download/
  • The official Documentation address is CMake 3.16 Documentation
  • The official CMake Tutorial address is CMake Tutorial

Add C++11 support to CMake

1. Add the following statements to the corresponding cmakelists. TXT file:

add_definitions(-std=c++11)
Copy the code

or

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

2, extensionHow to write cmake to include c++11 features (-std=c++11)

C++ 4.8.2 and cmake 2.8, respectively.

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

Cc1plus: error: unrecognized command line option “-std=c++11” Set (QMAKE_CXXFLAGS “-std=c++11”) will not work. It turns out that STD =c++11 is not supported in older versions. Ok direct test new writing cmakelists.txt file as follows:

#CMakeLists.txtProject (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()
Copy the code

Test c++11 code as follows:

//test.cc
#include <iostream>
#include<vector>
using namespace std; 
int main(a)
{
    const std::vector<int>v(1);
    auto a = v[0];// A is an int
        cout <<"a : "<< a <<endl;
    decltype(v[0]) b = 0;//b is the return type of STD ::vector
      
       ::operator[] (size_type) const int&
      
    auto c = 0;//c is an int
    auto d = c;//d is an int
    decltype(c) e;//e is an int, and c is the type of the entity
    decltype((c)) f = e;//f is of type int& because (c) is an lvalue
    decltype(0) g;//g is an int because 0 is an rvalue
    
    return 0;
}
Copy the code

Examples_CMake project

Github has a simple example of cmake written by jacking75, examples_CMake project address: github.com/jacking75/e…

CMake example

Sample introduction

The sample code is in the CMake_example directory.

01 HelloWorld A simple file in -c ++ code
  • main.cpp
#include <iostream>

int main(a)
{
  auto name = "jacking";
  std::cout << "hello world: " << name << std::endl;
  return 0;
}
Copy the code
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_definitions(-std=c++11)
add_executable(Main main.cpp)
Copy the code
02 HelloWorld – Sets compiler options. -Wall, C ++ 14
  • main.cpp
#include <iostream>

int main(a)
{
  auto name = "jacking";
  std::cout << "hello world: " << name << std::endl;
  return 0;
}
Copy the code
  • CMakeLists.txt
Cmake_minimum_required (VERSION 2.8) add_definitions ("-Wall -std=c++14")
add_executable(Main main.cpp)
Copy the code
03 HelloWorld – If you have a code file other than the main one
  • main.cpp
#include "test.h"

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

#include <iostream>

void TEST::Print(a)
{
    std::cout << "Test::Print" << std::endl;
}
Copy the code
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_executable(Main
  main.cpp
  test.cpp
)
Copy the code
04 HelloWorld – If files other than mai. CPP are in another directory

The 04_helloworld directory structure is as follows:

[root@ltcos01 04_helloWorld]$├─ ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├─ class.txt ├── exclude.org.txt 2 directories, 6 filesCopy the code
  • main.cpp
#include "test01/test01.h"
#include "test02/test02.h"

int main(a)
{
  TEST01 test01;
  test01.Print(a); TEST02 test02; test02.Print(a);return 0;
}
Copy the code

The test01 directory contains the test01.h and test01.cpp files

  • test01/test01.h
class TEST01
{
public:
  void Print(a);
};
Copy the code
  • test01/test01.cpp
#include "test01.h"
#include <iostream>

void TEST01::Print(a)
{
    std::cout << "Test01::Print" << std::endl;
}
Copy the code

The test02 directory contains the test02.h and test02.cpp files

  • test02/test02.h
class TEST02
{
public:
    void Print(a);
};
Copy the code
  • test02/test02.cpp
#include "test02.h"
#include <iostream>

void TEST02::Print(a)
{
    std::cout << "Test02::Print" << std::endl;
}
Copy the code
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_executable(Main
  main.cpp
  test01/test01.cpp
  test02/test02.cpp
)
Copy the code
05 Helloworld-reference After creating a static file

05_helloWorld source directory tree structure is as follows:

[root@ltcos01 05_helloWorld]$tree -L 2. ├─ Cmakelists.txt ├─ main.cpp ├─ cmakelists.txt │ ├─ │ ├─ 02.txt TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXT TXTCopy the code
  • main.cpp
#include "test01/test01.h"
#include "test02/test02.h"

int main(a)
{
    TEST01 test01;
    test01.Print(a); TEST02 test02; test02.Print(a);return 0;
}
Copy the code
  • 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)
Copy the code

The test01 directory contains test01.h and test01.cpp, along with the corresponding cmakelists.txt files

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

#include <iostream>

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

The add_library(test01 STATIC test01.cpp) command in cmakelists. TXT from the test01 directory above will generate the corresponding STATIC library file libtest01.a

The test02 directory has the same structure as the test01 directory, test02.h and test02.cpp and the corresponding cmakelists.txt files

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

#include <iostream>

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

Similarly, executing the cmake command in the test02 directory above produces the corresponding static library file libtest02.a. Create a build directory, go to the build directory and run cmake.. Run cmakelists. TXT from test02 as follows:

[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]$ 
Copy the code
06 HelloWorld – Specifies the compiler
  • main.cpp
#include <iostream>

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

set(CMAKE_CXX_COMPILER g++)
add_definitions("-Wall -std=c++14")

ADD_EXECUTABLE(main main.cpp)
Copy the code
07 HelloWorld – Using an external library (in this case Boost library)
  • main.cpp
#include <boost/thread.hpp>
#include <iostream>

int main(a)
{
    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(a);return 0;
}
Copy the code
  • 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)
Copy the code