Windows下的 C++ 編譯工具(MinGW-w64 + CMake)

引言

假如想在 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.

 

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章