不管用不用C/C++编程,想要理解Linux中的源码安装方式,个人认为学习编译环境及编译过程也是非常有必要的。

  • c/c++代码-----cmake编译----->makefile/project-----make编译----->可执行程序
  • cmake,一个开源的跨平台自动化构建工具, 可以跨平台地生成各式各样的 makefile 或者 project 文件, 支持利用各种编译工具(如make)生成可执行程序或链接库。
    cmake需要通过自己构建 CMakeLists.txt脚本文件来生成 makefile
  • make,可以根据 makefile 文件自动编译链接生成可执行程序或库文件。

一、ubuntu下安装编译环境:

1.安装build-essential(一般默认安装)
apt install build-essential

build-essential软件包安装时会将所依赖的c/c++的编译环境包一并安装。查看build-essential依赖:

hy@hy-F117:~/桌面$ apt-cache depends build-essential
build-essential
 |依赖: libc6-dev
  依赖: <libc-dev>
    libc6-dev
  依赖: gcc
  依赖: g++
  依赖: make
    make-guile
  依赖: dpkg-dev
2.安装cmake
apt install cmake

二、简单的实现:

实例来源于(不做修改):https://github.com/SFUMECJF/cmake-examples-Chinese

1.工程目录内(root@hy-F117:/home/hy/桌面/program)新建2个文件
root@hy-F117:/home/hy/桌面/program# tree

├── CMakeLists.txt

├── main.cpp

main.cpp

#include <iostream>

int main(int argc, char *argv[])
{
   std::cout << "Hello CMake!" << std::endl;
   return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.5) #设置CMake最小版本
project (hello_cmake) #设置工程名
add_executable(hello_cmake main.cpp) #生成可执行文件
2.编译生成规则文件
root@hy-F117:/home/hy/桌面/program# mkdir build
root@hy-F117:/home/hy/桌面/program# cd build/
root@hy-F117:/home/hy/桌面/program/build# cmake ../
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- 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: /home/hy/桌面/program/build

将发现build目录下生成很多文件,这就是在通过CMakeList规则下编译成的预编译文件。

root@hy-F117:/home/hy/桌面/program/build# tree
.
├── CMakeCache.txt
├── CMakeFiles
│   ├── 3.16.3
│   │   ├── CMakeCCompiler.cmake
│   │   ├── CMakeCXXCompiler.cmake
│   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   ├── CMakeSystem.cmake
│   │   ├── CompilerIdC
│   │   │   ├── a.out
│   │   │   ├── CMakeCCompilerId.c
│   │   │   └── tmp
│   │   └── CompilerIdCXX
│   │       ├── a.out
│   │       ├── CMakeCXXCompilerId.cpp
│   │       └── tmp
│   ├── cmake.check_cache
│   ├── CMakeDirectoryInformation.cmake
│   ├── CMakeOutput.log
│   ├── CMakeTmp
│   ├── hello_cmake.dir
│   │   ├── build.make
│   │   ├── cmake_clean.cmake
│   │   ├── DependInfo.cmake
│   │   ├── depend.make
│   │   ├── flags.make
│   │   ├── link.txt
│   │   └── progress.make
│   ├── Makefile2
│   ├── Makefile.cmake
│   ├── progress.marks
│   └── TargetDirectories.txt
├── cmake_install.cmake
└── Makefile

8 directories, 26 files
3.编译成可执行程序
root@hy-F117:/home/hy/桌面/program/build# make
Scanning dependencies of target hello_cmake
[ 50%] Building CXX object CMakeFiles/hello_cmake.dir/main.cpp.o
[100%] Linking CXX executable hello_cmake
[100%] Built target hello_cmake
root@hy-F117:/home/hy/桌面/program/build# tree
.
├── CMakeCache.txt
├── CMakeFiles
│   ├── 3.16.3
│   │   ├── CMakeCCompiler.cmake
│   │   ├── CMakeCXXCompiler.cmake
│   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   ├── CMakeSystem.cmake
│   │   ├── CompilerIdC
│   │   │   ├── a.out
│   │   │   ├── CMakeCCompilerId.c
│   │   │   └── tmp
│   │   └── CompilerIdCXX
│   │       ├── a.out
│   │       ├── CMakeCXXCompilerId.cpp
│   │       └── tmp
│   ├── cmake.check_cache
│   ├── CMakeDirectoryInformation.cmake
│   ├── CMakeOutput.log
│   ├── CMakeTmp
│   ├── hello_cmake.dir
│   │   ├── build.make
│   │   ├── cmake_clean.cmake
│   │   ├── CXX.includecache 	//new
│   │   ├── DependInfo.cmake
│   │   ├── depend.internal 	//new
│   │   ├── depend.make
│   │   ├── flags.make
│   │   ├── link.txt
│   │   ├── main.cpp.o     	//new
│   │   └── progress.make
│   ├── Makefile2
│   ├── Makefile.cmake
│   ├── progress.marks
│   └── TargetDirectories.txt
├── cmake_install.cmake
├── hello_cmake 		//new
└── Makefile

8 directories, 30 files

这里build目录下生成的hello_cmake就是可执行程序

4.执行可执行程序
root@hy-F117:/home/hy/桌面/program/build# ./hello_cmake 
Hello CMake!

三、关于cmake入门学习思路

1.学会写简单CMakeLists.txt
2.经典入门实例:

https://github.com/SFUMECJF/cmake-examples-Chinese

3.辉常哥对gcc、make、cmake的诠释

作者:辉常哥

  • 1.gcc是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。
  • 2.当你的程序只有一个源文件时,直接就可以用gcc命令编译它。
  • 3.但是当你的程序包含很多个源文件时,用gcc命令逐个去编译时,你就很容易混乱而且工作量大
  • 4.所以出现了make工具make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。
  • 5.makefile是什么?简单的说就像一首歌的乐谱,make工具就像指挥家,指挥家根据乐谱指挥整个乐团怎么样演奏,make工具就根据makefile中的命令进行编译和链接的。
  • 6.makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。
  • 7.makefile在一些简单的工程完全可以人工手下,但是当工程非常大的时候,手写makefile也是非常麻烦的,如果换了个平台makefile又要重新修改。
  • 8.这时候就出现了Cmake这个工具,cmake就可以更加简单的生成makefile文件给上面那个make用。当然cmake还有其他功能,就是可以跨平台生成对应平台能用的makefile,你不用再自己去修改了。
  • 9.可是cmake根据什么生成makefile呢?它又要根据一个叫CMakeLists.txt文件(学名:组态档)去生成makefile。
  • 10.到最后CMakeLists.txt文件谁写啊?亲,是你自己手写的。
  • 11.当然如果你用IDE,类似VS这些一般它都能帮你弄好了,你只需要按一下那个三角形。