165365比分网

gcc/g++编译选项与常用指令

📅 2025-10-16 17:57:56 👤 admin 👁️ 4899 ❤️ 737
gcc/g++编译选项与常用指令

一、相关资料

Warning Options (Using the GNU Compiler Collection (GCC)) gcc编译选项_挽风~的博客-CSDN博客

二、相关介绍

下载gcc/g++

下载地址1:ftp://gcc.gnu.org/pub 下载地址2:http://ftp.debian.org/debian/

1. gcc/g++编译(无CMake)

1.1 单文件编译

对于单文件"hello.cpp", 生成hello(hello.exe)所需要执行的bash命令:

gcc -v -o hello hello.c

1.2 多文件编译(无依赖)

但当涉及多文件编译时,我们的命令会十分复杂,比如一个main.cpp文件依赖于Foo1.cpp,Foo2.cpp,…Foo10,我们需要先将这10个文件编译成.o文件,再将各.o文件和main.o进行链接,代码如下:

g++ -std=c++17 -O2 -o Foo1.o -c Foo1.cpp

g++ -std=c++17 -O2 -o Foo2.o -c Foo2.cpp

g++ -std=c++17 -O2 -o Foo3.o -c Foo3.cpp

g++ -std=c++17 -O2 -o Foo4.o -c Foo4.cpp

g++ -std=c++17 -O2 -o Foo5.o -c Foo5.cpp

g++ -std=c++17 -O2 -o Foo6.o -c Foo6.cpp

g++ -std=c++17 -O2 -o Foo7.o -c Foo7.cpp

g++ -std=c++17 -O2 -o Foo8.o -c Foo8.cpp

g++ -std=c++17 -O2 -o Foo9.o -c Foo9.cpp

g++ -std=c++17 -O2 -o Foo10.o -c Foo10.cpp

g++ -std=c++17 -O2 -o main.o -c main.cpp

g++ -std=c++17 -O2 main.o Foo1.o Foo2.o Foo3.o Foo4.o Foo5.o Foo6.o Foo7.o Foo8.o Foo9.o Foo10.o -o main

1.3 多文件编译(有依赖)

上述编译过程还算简单,因为各子文件还不相互依赖,但如果子文件有相互依赖关系,比如foo1.cpp依赖于foo10.cpp我们编译的顺序有必须更改,在文件数目更大的工程中,一行一行输入命令进行编译是不现实的,所以我们引入了Makefile,对于上述编译任务,我们的MakeFile如下,我们只需输入make一句命令即可完成编译。

COMPILER = g++ -std=c++17 -O2 -I./include

OBJECTS = Foo1.o Foo2.o Foo3.o Foo4.o Foo5.o Foo6.o Foo7.o Foo8.o Foo9.o Foo10.o main.o

TARGET = main

$(TARGET): $(OBJECTS)

$(COMPILER) -o $@ $^ -lprotobuf

$(OBJECTS): %.o: %.cpp

$(COMPILER) -o $@ -c $<

$(DEPENDENCIES): %.d: %.cpp

$(COMPILER) -o $@ -MM $<

include $(DEPENDENCIES)

.PHONY: clean

clean:

rm $(OBJECTS) $(DEPENDENCIES) $(TARGET)

1.4 总结

Makefile 规定了一套编译规则,使用什么编译器,编译器使用什么样的编译选项,每个文件都有什么依赖关系。在编译的时候,能够直接根据 makefile 来确定哪些文件依赖于其他的哪些文件,从而把编译顺序、需不需要重新编译以及链接都自动检测出来。在Linux环境下,MakeFile本身可以看做一个shell脚本。

2. ld 指令

ld(ld-linux.so)默认搜索 /lib 和 /usr/lib 这两个目录。

3. ldd指令

ldd 指令,全称 list dynamic dependencies,用于检查动态库依赖关系。

$ldd test

linux-vdso.so.1 (0x00007fff065e4000)

liba.so => not found

libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa1d384e000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa1d345d000)

libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa1d30bf000)

/lib64/ld-linux-x86-64.so.2 (0x00007fa1d3dd9000)

libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa1d2ea7000

参数解释

linux-vdso.so.1为一个虚拟的库 Virtual Dynamic Shared Object,所以没有路径,包含一些内核api,比如 syscall() 这个函数就是在linux-vdso.so.1里头。内核把包含某 .so 的内存页在程序启动的时候映射入其内存空间,对应的程序就可以当普通的 .so 来使用里面的函数。

/lib64/ld-linux-x86-64.so.2为链接器,是程序中第一个被加载的,通过 ldopen 来动态加载剩下的库。

libstdc++.so.6和libc.so.6应该是c++和c的标准库。

libgcc_s.so.1 是gcc运行时库,提供一些gcc支持的api。

4. readelf指令

Linux命令学习手册-readelf

readelf,用于查看elf文件。

readelf -d -s -W test

Dynamic section at offset 0xd78 contains 29 entries:

Tag Type Name/Value

0x0000000000000001 (NEEDED) Shared library: [liba.so]

0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]

0x0000000000000001 (NEEDED) Shared library: [libc.so.6]

参数解释

-d,表示查看dynamic section。-s,查看符号。-W,显示符号全名。NEEDED,表示本elf文件需要加载的动态库。

5. LD_DEBUG指令

LD_DEBUG=libs,对链接库加载过程进行debug,会打印出 error while loading shared libraries的搜索过程。

LD_DEBUG=libs ./test

7315: find library=liba.so [0]; searching

7315: search path=/opt/ros/melodic/lib/tls/haswell/x86_64:/opt/ros/melodic/lib/tls/haswell:/opt/ros/melodic/lib/tls/x86_64:/opt/ros/melodic/lib/tls:/opt/ros/melodic/lib/haswell/x86_64:/opt/ros/melodic/lib/haswell:/opt/ros/melodic/lib/x86_64:/opt/ros/melodic/lib (LD_LIBRARY_PATH)

7315: trying file=/opt/ros/melodic/lib/tls/haswell/x86_64/liba.so

7315: trying file=/opt/ros/melodic/lib/tls/haswell/liba.so

...................................................................

7315: trying file=/opt/ros/melodic/lib/x86_64/liba.so

7315: trying file=/opt/ros/melodic/lib/liba.so

7315: search cache=/etc/ld.so.cache

7315: search path=/lib/x86_64-linux-gnu/tls/haswell/x86_64:..../usr/lib/x86_64:/usr/lib (system search path)

7315: trying file=/lib/x86_64-linux-gnu/tls/haswell/x86_64/liba.so

7315: trying file=/lib/x86_64-linux-gnu/tls/haswell/liba.so

...................................................................

7315: trying file=/usr/lib/liba.so

7315:

./test: error while loading shared libraries: liba.so: cannot open shared object file: No such file or directory

三、常用的编译选项

严格的编译参数有利于在编译时发现问题,提高代码质量。

-c

-c指定源文件。

-fPIC

动态库基本原理和使用方法,-fPIC选项的来龙去脉

-fPIC表示编译为位置无关代码,用于动态链接重定位。使用gcc生成so文件时,一般要加一个 -fPIC 选项。 使用 -fPIC 选项,会生成 PIC 代码。.so 要求为 PIC,以达到动态链接的目的,否则,无法实现动态链接。动态链接执行很复杂,比静态链接执行时间长;但是,极大的节省了 size。

# 使用g++产生地址无关代码

g++ --shared -fPIC -o add.so add.cc

# 查看是否使用PIC

# 如果不是PIC,则不会有任何输出

readelf -d libbook.so | grep TEXTREL

-g

-g表示加入调试信息,可用dgb调试。

-o

-o指定输出名称。

-std

-std指定c++标准。

-w相关

通过 -W 开头,能指定开启许多警告,与之对应通过 -Wno- 也能关闭指定的警告。

-w

-w,禁用所有警告。

-Werror

-Werror,所有警告变成error。

-Werror=xxx

-Werror=xxx,指定的警告变成error。例如:-Werror=switch,表示 -Wswitch控制的警告变成error。

-Wno-error=xxx

-Wno-error=xxx,指定的警告不变成error,即使 -Werror 被指定。例如:-Wno-error=switch,表示 -Wswitch控制的警告不变成error。

-Wxxx

-Wxxx,打开指定的警告。例如:-Wimplicit。

-Wno-xxx

-Wno-xxx,关闭特定的警告。例如:-Wno-implicit。

-Wall

-Wall 开启一组常见的警告,包括但不限于未使用变量、函数未声明等。它允许编译器发现一些潜在的代码问题,但并不包括所有可能的警告。

-Wall 列出下列警告:

-Waddress

-Warray-bounds=1 (only with -O2)

-Warray-parameter=2 (C and Objective-C only)

-Wbool-compare

-Wbool-operation

-Wc++11-compat -Wc++14-compat

-Wcatch-value (C++ and Objective-C++ only)

-Wchar-subscripts

-Wcomment

-Wduplicate-decl-specifier (C and Objective-C only)

-Wenum-compare (in C/ObjC; this is on by default in C++)

-Wformat

-Wformat-overflow

-Wformat-truncation

-Wint-in-bool-context

-Wimplicit (C and Objective-C only)

-Wimplicit-int (C and Objective-C only)

-Wimplicit-function-declaration (C and Objective-C only)

-Winit-self (only for C++)

-Wlogical-not-parentheses

-Wmain (only for C/ObjC and unless -ffreestanding)

-Wmaybe-uninitialized

-Wmemset-elt-size

-Wmemset-transposed-args

-Wmisleading-indentation (only for C/C++)

-Wmissing-attributes

-Wmissing-braces (only for C/ObjC)

-Wmultistatement-macros

-Wnarrowing (only for C++)

-Wnonnull

-Wnonnull-compare

-Wopenmp-simd

-Wparentheses

-Wpessimizing-move (only for C++)

-Wpointer-sign

-Wrange-loop-construct (only for C++)

-Wreorder

-Wrestrict

-Wreturn-type

-Wsequence-point

-Wsign-compare (only in C++)

-Wsizeof-array-div

-Wsizeof-pointer-div

-Wsizeof-pointer-memaccess

-Wstrict-aliasing

-Wstrict-overflow=1

-Wswitch

-Wtautological-compare

-Wtrigraphs

-Wuninitialized

-Wunknown-pragmas

-Wunused-function

-Wunused-label

-Wunused-value

-Wunused-variable

-Wvla-parameter (C and Objective-C only)

-Wvolatile-register-var

-Wzero-length-bounds

-Wextra

-Wextra 打开更多的警告,包括一些 -Wall 没有涵盖到的。这可能包括一些更严格的规则,帮助进一步提高代码质量。

-Wextra 列出没被 -Wall 列出的警告:

-Wclobbered

-Wcast-function-type

-Wdeprecated-copy (C++ only)

-Wempty-body

-Wenum-conversion (C only)

-Wignored-qualifiers

-Wimplicit-fallthrough=3

-Wmissing-field-initializers

-Wmissing-parameter-type (C only)

-Wold-style-declaration (C only)

-Woverride-init

-Wsign-compare (C only)

-Wstring-compare

-Wredundant-move (only for C++)

-Wtype-limits

-Wuninitialized

-Wshift-negative-value (in C++03 and in C99 and newer)

-Wunused-parameter (only with -Wunused or -Wall)

-Wunused-but-set-parameter (only with -Wunused or -Wall)

-Wfatal-errors

-Wfatal-errors,使得编译器在遇到第一个error后就终止编译。

-Wl

-Wl用于告诉编译器后续的参数传给连接器,链接器的参数用","逗号隔开,不允许有空格。

-pedantic

-pedantic,列出违背严格的c/c++标准的所有警告。

-pedantic-errors

-pedantic-errors,列出违背严格的c/c++标准的所有错误。

其他编译选项

-Wnon-virtual-dtor,当类用于多态时,即基类被继承时,析构函数非虚时会发出警告。-Wold-style-cast,当使用c语言式的类型转换将发出警告。-Woverloaded-virtual,当子类重载了基类虚函数时,会发出警告,因为此时基类定义的虚函数被子类隐藏了。-Wswitch-default,当switch语句没有default分支时,发出警告。-Wshadow,当一个变量掩盖了另一个变量时给出警告。-Wcast-qual,当类型转换丢失限定信息时给出警告。-Wextra-semi,当类函数定义后出现多余的分号给出警告。

FAQ

Q:GPU是否能加速gcc编译?

Is it possible to use GPU acceleration on compiling multiple programs on a gcc compiler?

If your question is, “can I use the GPU to speed up non-CUDA generic code compilation?” the answer is currently no. The GPU is good at certain things like parallel tasks, bad at others like branches which compilers are all about. The good news is, you can use a network of PCs with CPUs to get 2-10x compile speedups, depending on how optimized your code is already, and you can get the fastest multi-core CPU and high-speed SSD available for your desktop to get gains for less hassle before you resort to network builds.

IF what you are asking is, “Can you automatically write GPU-accelerated code for use with GCC and LLVM?” the answer is yes. NVIDIA and Google make open-source LLVM-based compiler projects:

NVIDIA CUDA LLVM:

https://developer.nvidia.com/cuda-llvm-compilerhttps://en.wikipedia.org/wiki/NVIDIA_CUDA_Compiler

GOOGLE GPUCC:

http://llvm.org/devmtg/2015-10/slides/Wu-OptimizingLLVMforGPGPU.pdf

上一则传输
钥的意思
下一则传输
龙猫能活多久

相关星图