命令行编译C++(Linux下、Windows下)

C++ 编译过程

  一般而言,对于 C++ 程序编译有以下4个阶段:

  • 预处理(preprocessing)
    对源程序中的伪指令(以#开头的指令)和特殊符号进行处理。伪指令包括宏定义、条件编译指令、头文件包含指令等。
  • 编译(compilation)
    将预处理后的文件编译生成后缀为 .s 的汇编语言文件,。编译程序所要做的工作是通过记法分析和语法分析,在确认所有指令都符合语法规则后,将其翻译成等价的中间代码或汇编代码。
  • 汇编(assembly)
    将汇编文件汇编生成后缀为 .o 的目标文件(二进制)。汇编过程实际上是指把汇编语言代码翻译成目标机器指令的过程。
  • 链接(linking)
    将多个目标文件和库连接生成后缀为 .out 或 .exe 的可执行文件。链接程序的主要工作就是将有关的目标文件彼此相连接,即将在一个文件中引用的符号现该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。
    链接处理分为两种:
    • 静态链接(static linking)
      简单说,指链接器在链接时将库(静态库)的内容拷贝到可执行程序中。
    • 动态链接(dynamic linking)
      简单说,指程序运行时才将库(动态链接库)连接到程序中。

Linux系统

参考《An Introduction to GCC》

使用gcc(GNU编译器套件)

  gcc 最开始的时候是 GNU C Compiler,就是一个 c 编译器。但是后来因为这个项目里边集成了更多其他不同语言的编译器, GCC 就代表 the GNU Compiler Collection,所以表示一堆编译器的合集。g++ 则是GCC的 c++ 编译器。
  现在调用 gcc 的时候,已经不是当初那个 c 语言编译器了,更确切地说它是一个驱动程序,根据代码的后缀名来判断调用 c 编译器还是 c++ 编译器(g++)。即代码后缀是 .c,则调用 c 编译器和 linker 去链接 c 的 library,代码后缀是 .cpp,则调用 g++ 编译器,但是这里 gcc 不会自动和 c++ 库链接。

  • 基本参数
      shell 窗口中执行 gcc –help 列出基本参数:

    $ gcc --help
    
    # 省略一部分输出
    
    -E                       Preprocess only; do not compile, assemble or link
    -S                       Compile only; do not assemble or link
    -c                       Compile and assemble, but do not link
    -o <file>                Place the output into <file>
    
    # 省略一部分输出
    
  • $ cd ~/design-pattern/factory/
    $ ls
    Factory.cpp  Factory.h  main.cpp  Product.cpp  Product.h
    • 编译
      如上所述,gcc 不会自动和 c++ 库链接,所以这里只编译,否则会有一堆链接错误

      $ gcc *.cpp -c
      $ ls # 可以看到编译生成 *.o 对象文件(二进制)
      Factory.cpp  Factory.o  main.o       Product.h
      Factory.h    main.cpp   Product.cpp  Product.o
    • 链接

      • 上面强调 gcc 不会自动链接 c++ 库,这里我们可以手动链接 c++ 库
      $ gcc *.o -lstdc++
      $ ls
      a.out        Factory.h  main.cpp  Product.cpp  Product.o
      Factory.cpp  Factory.o  main.o    Product.h
      $ ./a.out
      Concrete Facotry
      Concrete Product...
      • 因 gcc 不会自动链接 c++ 库,所以可直接用 g++ 链接 .o 文件生成 .out 可执行文件
      $ g++ *.o
      $ ls
      a.out        Factory.h  main.cpp  Product.cpp  Product.o
      Factory.cpp  Factory.o  main.o    Product.h
      $ ./a.out
      Concrete Facotry
      Concrete Product...
    • 综上,可直接使用 g++ 编译链接 c++ 程序生成可执行文件

      $ g++ *.cpp
      $ ls
      a.out  Factory.cpp  Factory.h  main.cpp  Product.cpp  Product.h
      $ ./a.out
      Concrete Facotry
      Concrete Product...

include 包含文件搜索路径

  include 包含文件在编译的时候使用,GCC 搜索头文件路径的顺序:

  1. 当前目录(#include “” 方式会搜索当前目录,#include <> 方式不会搜索当前目录
  2. -I 选项指定的目录
  3. gcc 环境变量 CPLUS_INCLUDE_PATH 指示的目录(c 程序使用的是 C_INCLUDE_PATH
  4. gcc 的默认目录

    /usr/local/include
    /usr/include
    /usr/lib/x86_64-linux-gnu/5.4.0/include

    gcc 的默认目录,不是由 $PATH 环境变量指定的,而是由 g++ 的配置 prefix 指定。

lib 库文件搜索路径

  链接的时候使用,搜索顺序:

  • 静态库文件

    1. -L 选项指定的路径
    2. gcc 的环境变量 LIBRARY_PATH
    3. gcc 的默认目录
    /lib
    /usr/local/lib
    /usr/lib
  • 动态库文件
    1. 编译代码时指定的路径(gcc 的参数 -Wl, -rpath 指定)
    2. 环境变量 LD_LIBRARY_PATH 指定的路径(多个路径用冒号 : 分隔)
    3. 配置文件 /etc/ld.so.conf 指定的路径
    4. 默认的动态库路径 /lib,/usr/lib

-I(大写的i)、 -include、 -L、 -l(小写的L) 参数说明

  • -I 扩展 gcc 在编译时对包含文件的搜索路径,即不使用 -I 参数时,只会在上述默认路径下搜索。

    $ cd ~/design-pattern/factory/
    $ ls
    Factory.cpp  Factory.h  main.cpp  Product.cpp  Product.h
    $ mv *.h ../
    $ gcc -c -I ../ *.cpp
    $ ls
    Factory.cpp  Factory.o  main.cpp  main.o  Product.cpp  Product.o
    $ gcc
  • -include 指定包含头文件,很少用,因为一般头文件都在源代码中用 #include xxx实现了。
  • -L 扩展 gcc 在链接时对库文件的搜索路径,即不使用 -L 参数时,只会在上述默认路径下搜索。

    $ gcc *.cpp -I ../ -L /usr/lib/gcc/x86_64-linux-gnu/5.4.0 -lstdc++
    
    # or
    
    $ g++ *.cpp -I ../ -L /usr/lib/gcc/x86_64-linux-gnu/5.4.0
    $ ./a.out
    Concrete Facotry
    Concrete Product...
  • -l 紧接库名,指定程序要链接的库。
    这里注意库名库文件名的区别,以文件 ./usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.so 为例,libstdc++.so 为库文件名,而库名则是 stdc++。如

    $ gcc *.cpp -I ../ -lstdc++
    $ ls
    a.out  Factory.cpp  Factory.o  main.cpp  main.o  Product.cpp  Product.o
    $ ./a.out
    Concrete Facotry
    Concrete Product...

-shared 参数说明

  用于编译生成动态库。

Windows系统

  cl.exe 和 link.exe 分别是 visual studio IDE 中的编译器和链接器。

使用cl.exe编译器

  • 用法

    usage: cl [ option... ] filename... [ /link linkoption... ]
  • 基本参数

    • -I: 指定第一个寻找头文件的目录(如果指定多个目录,则使用多个-I)
    • -c: 只编译不链接
    • -EHsc: 指示编译器启用 C++ 异常处理
  • 例:

  Windows下命令中使用路径时,注意特殊字符要使用转义字符”\”,如下路径中包含\,空格和括号,前面均加转义符”\”,或者将路径用引号括起来。
  gitbash窗口:

    $ cl *.cpp -c -EHsc -I C:\\Program\ Files\ \(x86\)\\Microsoft\ Visual\ Studio\ 14.0\\VC\\include -I C:\\Program\ Files\ \(x86\)\\Windows\ Kits\\10\\Include\\10.0.10240.0\\ucrt
    # or
    $ cl *.cpp -c -EHsc -I "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt" -I "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include"

使用link.exe链接器

  • 用法
usage: LINK [options] [files] [@commandfile]
  • 基本参数(以下参数在windows cmd窗口中执行有效,在bash中不过)
    • /LIBPATH: 指定要在环境库路径之前搜索的路径
    • /OUT: 指定输出文件名
  • 例:

  windows cmd 窗口(bash下测试不过):

$ link *.obj /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib" /LIBPATH:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib" /LIBPATH:"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86" /OUT:fac.exe

编译器控制的LINK选项

参考MSDN https://msdn.microsoft.com/zh-cn/library/92b5ab4h.aspx https://msdn.microsoft.com/zh-cn/library/btw8x58e.aspx

  除非指定 -c 选项,否则 cl.exe 会自动调用 link.exe 。以下为 cl 中影响链接的常用功能(注意当参数有指定输出文件时,要带冒号:):

  • /Fo: filename: 指定生成的 .obj 文件名
  • /Fe: filename: 传递 /OUT:filename 给 link.exe, 指定生成的 .exe 文件名

环境变量

参考MSDN https://msdn.microsoft.com/zh-cn/library/kezkeayy.aspx https://msdn.microsoft.com/zh-cn/library/6y6t9esh.aspx

  CL 和 LINK 用到的环境变量有:

  • cl.exe
    • INCLUDE: 指示 C/C++ 源文件中使用 #include 包含的文件,如头文件等。标准 C/C++ 开发,会使用 Visual C++ 的安装路径下 vc\include 子目录中的包含文件, Windows API 开发,会使用Platform SDK 的安装路径下 vc\include 子目录中的包含文件。
    • LIBPATH: 指定用于搜索使用 #using 引用的元数据文件的目录。
  • link.exe
    • LIB: 指定搜索对象、库或其他文件的路径。标准 C/C++ 开发,会使用 Visual C++ 的安装路径下 vc\lib 子目录中的包含文件, Windows API 开发,会使用Platform SDK 的安装路径下 vc\lib 子目录中的包含文件link.exe会从如下路径搜索对象文件和库文件:
      • 当前路径
      • 命令行上由 /BASE 指定的路径
      • 使用 LIB环境变量中的路径。
    • TMP: 链接时寻找 OMF 或 .res 文件时,会从这个路径中寻找。

我本机的系统环境变量设置脚本

echo off

setx -m WIN_KIT "C:\Program Files (x86)\Windows Kits"
setx -m WIN_SDK "C:\Program Files (x86)\Microsoft SDKs"
setx -m VS_INSTALL_DIR "C:\Program Files (x86)\Microsoft Visual Studio 14.0"
setx -m Microsoft_SDK "C:\Program Files (x86)\Microsoft SDKs"

setx -m PATH "%VS_INSTALL_DIR%\VC\bin;%PATH%"

rem INCLUDE
rem -------
setx -m INCLUDE "%VS_INSTALL_DIR%\VC\INCLUDE;%VS_INSTALL_DIR%\VC\ATLMFC\INCLUDE;%WIN_KIT%\10\Include\10.0.10240.0\ucrt"

rem LIB
rem ---
setx -m LIB "%VS_INSTALL_DIR%\VC\lib;%VS_INSTALL_DIR%\VC\ATLMFC\LIB;%Microsoft_SDK%\Windows\v7.1A\Lib;%WIN_KIT%\10\Lib\10.0.10240.0\ucrt\x86;%WIN_KIT%\10\Lib\10.0.10240.0\ucrt\x64"

rem LIBPATH
rem -------
setx -m LIBPATH "%VS_INSTALL_DIR%\VC\lib;%VS_INSTALL_DIR%\VC\ATLMFC\LIB;%WIN_KIT%\10\Lib\10.0.10240.0\ucrt\x86;%Microsoft_SDK%\10\Lib\10.0.10240.0\ucrt\x86"

pause

使用 CL 生成可执行文件

  环境变量设置好后,即可通过 cl 在命令行一步生成 C++ 的可执行文件,例

$ cd /e/program/designPattern/Factory/Factory

$ ls *.cpp
Factory.cpp  main.cpp  Product.cpp

$ cl *.cpp -EHcs -Fe: fac
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

Factory.cpp
main.cpp
Product.cpp
Generating Code...
Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:fac.exe
Factory.obj
main.obj
Product.obj

$ ls *.cpp *.obj *.exe
fac.exe*  Factory.cpp  Factory.obj  main.cpp  main.obj  Product.cpp  Product.obj

$ ./fac.exe
Concrete Facotry
Concrete Product...
  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 由于Godot引擎本身是使用C++编写的,因此可以在Windows环境下使用Visual Studio编译生成ARM Linux可执行文件。 编译过程如下: 1. 首先需要安装Visual Studio和Windows SDK,并配置好编译环境。 2. 下载Godot源代码,并使用scons工具构建Godot。 3. 配置编译选项,设置目标平台为ARM Linux。 4. 编译Godot源代码,生成可执行文件。 5. 将生成的可执行文件部署到目标平台上。 请注意,这个编译过程需要一定的技术知识,如果您不熟悉编译操作,建议您先了解相关知识。 ### 回答2: 在Windows编译Godot引擎到ARM Linux需要进行一系列步骤。下面是一个简单的教程: 1. 安装必要的软件:首先,您需要安装Git进行版本控制,CMake用于构建工程,以及交叉编译工具链(即arm-linux-gnueabihf)用于生成ARM Linux目标代码。您可以在其官方网站上找到并下载这些软件。 2. 克隆Godot源代码:使用Git工具,在命令行中克隆Godot引擎的源代码仓库。执行以下命令:git clone https://github.com/godotengine/godot.git 3. 配置交叉编译工具链:通过设置环境变量或在CMake配置过程中指定交叉编译工具链的路径,让CMake知道您想要构建ARM Linux目标。 4. 生成Makefile文件:使用CMake配置和生成Godot引擎的Makefile文件。在命令行中进入克隆的Godot源代码目录,并执行以下命令:cmake -B <build_directory> -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release。 5. 编译Godot引擎:在步骤4中生成的构建目录中,执行以下命令编译Godot引擎:cmake --build <build_directory> --config Release。 6. 生成导出模板:在成功编译Godot引擎后,在构建目录中执行以下命令来生成ARM Linux的导出模板:scons platform=linuxbsd target=release_debug tools=no。 7. 导出ARM Linux应用程序:根据您的需求,您可以使用Godot编辑器或命令行工具导出ARM Linux的应用程序。导出后,您将获得一个与ARM Linux操作系统兼容的可执行文件。 请注意,这个教程并不是详尽无遗的,并且可能会因不同的配置和源代码版本而有所不同。因此,在进行这个编译过程时,最好参考Godot官方文档中的具体指引和要求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值