引言

假如想在 Windows 下进行 C++ 的开发,可以直接使用 Visual Studio 和相应的 C++ 插件来实现,但编译和构建过程是不可见的。为了更彻底地了解 C++ 工程的编译和构建,可以借助另外两个工具在 Windows 环境下实现。

 

MinGW

是 Windows 系统下的一个编译环境,包含了 C++ 代码编译所需的三方库、头文件等,用于完成 C++ 源码的编译和链接。

  • 安装:

    在官网下载安装包:mingw-get-setup.exe ,双击开始安装,然后在 MinGW Installation Manager 中选择需要安装的工具库。Basic Setup 中的库都是比较常用的,例如编译代码使用的 g++ 工具,这些最好都选中并安装。

  • 配置:

    将安装目录的 bin 目录配置到系统环境变量中的 Path 中,启动 cmd 命令行,输入一下指令验证上面选择的库是否安装成功,例如 g++ 库:

    E:\C++\projects>g++ --version
    g++ (MinGW.org GCC-6.3.0-1) 6.3.0
    Copyright (C) 2016 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    输出上述内容则表示库安装成功。

  • 测试编译:

    随便编写一个 C++ 代码文件,然后使用 g++ 来编译生成可执行文件:

    #include <iostream>
    using namespace std;
    ​
    int main() 
    {
        cout << "Hello, World!";
        return 0;
    }

    先编译但不链接,然后链接生成可执行文件:

    $ g++ -c helloworld.cpp
    $ g++ helloworld.o -o helloworld.exe

    假如使用 -c 标识,则是编译但不链接,会生成对应的 .o 文件,不设置标识,则会直接生成最终的 .exe 可执行文件。

  • 静态关联:

    上述编译生成的可执行文件,双击打开都会提示 "无法启动此程序,因为计算机中丢失 libgcc_s_dw2-1.dll。..." 这样的错误(假如是在命令行中执行文件则不会报错,但会命令行窗口会一闪而过,看不到输出的结果)。这是因为 gcc 编译器 编译时默认使用的不是静态关联的方式,运行时找不到对应的库导致报错。

    解决方案:可以直接将缺失的 dll 库手动复制到可执行文件目录下,当然这不是根治的方法,其实只要在链接时带上标识 -static-libgcc 来指定静态关联即可解决此问题:

    $ g++ helloworld.o -o helloworld.exe -static-libgcc

    后面使用 CMake 来构建的话,可以在 CMakeList.txt 配置编译参数。

 

MinGW-w64

上面安装的 MinGW 只能编译生成 32 位的可执行程序,而 MinGW-w64 可以编译生成 64 位或 32 位的可执行程序。安装步骤如下:

  • 安装:

    可以从 mingw-w64 官网 下载最新的安装包,也可以直接从 SourceForge 中去下载 mingw-w64-install.exe

    下载完成后,直接双击安装包进行安装,除了修改一下安装目录,其余设置都是用默认设置接口。

    这里直接下载安装程序进行安装的话,在安装过程需需要去服务器下载资源,似乎速度很慢,所以最后我改成直接从 这里 下载离线的完整压缩包:

    根据自己的需求选择,此包为:64 位系统,且使用效率较好较新的 seh 异常处理模型(至于 win32 和 posix 的区别暂时还没搞懂)

  • 配置:

    通上面的 MinGW 一样,只需将安装目录下的 bin 目录配置到系统 Path 中即可。查询配置结果:

    $ gcc --version
    gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
    Copyright (C) 2018 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

在执行 gcc 命令时,加上 -m32 生成 32 位可执行程序,加上 -m64 生成 64 位可执行程序

 

CMake

一个跨平台的自动构建系统,使用一个 CMakeLists.txt 文件来描述构建过程(等同于 Linux 系统下编译构建 C/C++ 时使用的 Makefile 的作用),通常在编译一个多文件的工程时使用这样的工具。

  • 安装:

    直接下载官方 cmake-3.13.0-rc3-win64-x64.zip 包,解压即可,无需安装。

  • 配置:

    参考 MinGW 的配置方式,将解压后目录中的 bin 目录配置到系统 的 Path 参数中,通过命令行验证是否配置成功:

    E:\C++\projects>cmake --version
    cmake version 3.13.0-rc3
    ​
    CMake suite maintained and supported by Kitware (kitware.com/cmake).

    如上标识配置生效。

  • 测试:

    在测试目录下创建一个 CMakeLists.txt 文件:

    cmake_minimum_required (VERSION 3.0)    # cmake 最低版本
    ​
    project (helloworld)    # 工程名称
    ​
    add_executable(helloworld helloworld.cpp)   # 源文件
    ​
    if(WIN32)   # 静态关联配置
        set(CMAKE_CXX_FLAGS "-static-libgcc")
    endif(WIN32)

    打开 cmake-gui.exe ,然后 source 目录选择工程目录,bin 目录可以随便自定义,然后点击 Configure 选择 MinGW Makefiles ,无报错的话,在命令行进入 bin 目录,输入 mingw32-make 编译工程:

    E:\C++\projects\helloworld\build>mingw32-make
    Scanning dependencies of target helloworld
    [ 50%] Building CXX object CMakeFiles/helloworld.dir/helloworld.cpp.obj
    [100%] Linking CXX executable helloworld.exe
    [100%] Built target helloworld

    成功编译出目标文件 helloworld.exe ,在命令行中执行如下:

    E:\C++\projects\helloworld\build>helloworld.exe
    Hello World!
  • 命令行模式:

    上面我们使用借助 cmake-gui.exe 工具完成了工程的编译,而实际上也可以直接通过命令行来完成:

    $ mkdir build
    $ cd build
    $ cmake -G"Unix Makefiles" ../
    -- The C compiler identification is GNU 8.1.0
    -- The CXX compiler identification is GNU 8.1.0
    -- Check for working C compiler: E:/C++/installs/x86_64-8.1.0-release-posix-seh-
    rt_v6-rev0/mingw64/bin/gcc.exe
    -- Check for working C compiler: E:/C++/installs/x86_64-8.1.0-release-posix-seh-
    rt_v6-rev0/mingw64/bin/gcc.exe -- 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: E:/C++/installs/x86_64-8.1.0-release-posix-se
    h-rt_v6-rev0/mingw64/bin/c++.exe
    -- Check for working CXX compiler: E:/C++/installs/x86_64-8.1.0-release-posix-se
    h-rt_v6-rev0/mingw64/bin/c++.exe -- 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: E:/C++/projects/helloworld/build

    上面的步骤用于生成 makefile 文件,生成成功后,在执行 make 进行编译:

    $ make
    Scanning dependencies of target helloworld
    [ 50%] Building CXX object CMakeFiles/helloworld.dir/helloworld.cpp.obj
    [100%] Linking CXX executable helloworld.exe
    [100%] Built target helloworld

    然后在命令行中执行编译后的可执行文件:

    $ .\helloworld.exe
    Hello World!

 

CMakeLists.txt

关于 CMakeLists.txt 的语法还是需要再补充一下的,可以参考:cmake-tutorial

当然,在使用过程中会发现很多很微妙的地方,例如: link_directories 必须在 add_executable 之前使用,这样 target_link_libraries 才能从 link_directories 中指定的目录中去搜索库文件。

 

GCC 、Make 和 CMake

这里有必要梳理一下 gccmake 以及 cmake 的关系:

  • gcc

    即 GNU Compiler Collection(GNU 编译器套件),也可以理解为编译器,可用于编译很多种编程语言(如:C、C++、Objective-C、Java 等);

  • make

    可以看作一个智能的批处理工具,本身没有编译和链接功能,而是通过调用 makefile 文件中用户指定的命令来进行编译和链接的;

  • cmake

    可以根据 CMakeLists.txt 文件,跨平台来生成对应平台的 makefile 文件。

综上所述:

  • gcc 是用于编译和链接和工具,编译少量文件可以直接使用 gcc 命令完成,但当源文件很多,用 gcc 命令去逐个编译则是很混乱且工作量巨大。

  • 因此,需要借助 make 来来管理整个编译过程,make 安装 makefile 中的命令进行编译和链接,而 makefile 命令中就包含了调用 gcc 去编译某个源文件的命令。

  • 而当工程规模非常大时,且需要跨平台时,手写 makefile 也开始变得麻烦,这是可以借助 cmake 来生成 makefile 。

 

MinGW-w64 和 CMake 配置

MinGW-w64 就是 Windows 平台下集成了 gcc 和 make (gcc.exebin/mingw32-make.exe)的工具 ,上面我们已经分别配置好了 MinGW-w64 和 CMake ,为了更好地配合这两个工具来完成工程的编译,下面需要再完成一点点额外的配置:

打开 MinGW-w64 的 bin 目录,拷贝一份 mingw32-make.exe 改名为 make.exe

$ make --version
GNU Make 4.2.1
Built for x86_64-w64-mingw32
Copyright (C) 1988-2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

 

参考

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐