CFLAGS 详解
GCC常见参数配置

GCC常见参数配置简介gcc 和 g++现在是gnu中最主要和最流⾏的c & c++编译器 .gcc/g++在执⾏编译⼯作的时候,总共需要以下⼏步:1.预处理,⽣成.i的⽂件[预处理器cpp]2.将预处理后的⽂件不转换成汇编语⾔,⽣成⽂件.s[编译器egcs]3.有汇编变为⽬标代码(机器代码)⽣成.o的⽂件[汇编器as]4.连接⽬标代码,⽣成可执⾏程序[链接器ld]GCC能够处理的后缀有:a. *.c *.C (C语⾔)b. *.cxx *.cc (C++语⾔)c. *.m (⾯向对象的C)d. *.i (预处理后的C语⾔源⽂件)e. *.ii (预处理后的C++语⾔源⽂件)f. *.s *.S (汇编语⾔)h. *.h (头⽂件)⽬标⽂件可以是:1. *.o 编译连接后的⽬标⽂件2. *.a 库⽂件gcc与g++有什么区别共同点: gcc和g++都是GNU(组织)的⼀个编译器。
误区⼀:gcc只能编译c代码,g++只能编译c++代码1.后缀为.c的,gcc把它当作是C程序,⽽g++当作是c++程序;后缀为.cpp的,两者都会认为是c++程序,注意,虽然c++是c的超集,但是两者对语法的要求是有区别的。
C++的语法规则更加严谨⼀些。
2.编译阶段,g++会调⽤gcc,对于c++代码,两者是等价的,但是因为gcc命令不能⾃动和C++程序使⽤的库联接,所以通常⽤g++来完成链接,为了统⼀起见,⼲脆编译/链接统统⽤g++了,这就给⼈⼀种错觉,好像cpp程序只能⽤g++似的。
误区⼆:gcc不会定义__cplusplus宏,⽽g++会实际上,这个宏只是标志着编译器将会把代码按C还是C++语法来解释,如上所述,如果后缀为.c,并且采⽤gcc编译器,则该宏就是未定义的,否则,就是已定义。
误区三:编译只能⽤gcc,链接只能⽤g++严格来说,这句话不算错误,但是它混淆了概念,应该这样说:编译可以⽤gcc/g++,⽽链接可以⽤g++或者gcc -lstdc++。
gcc命令行详解

gcc命令行详解1、gcc包含的c/c++编译器gcc、cc、c++、g++gcc和cc是一样的,c++和g++是一样的,一般c程序就用gcc编译,c++程序就用g++编译2、gcc的基本用法gcc test.c这样将编译出一个名为a.out的程序gcc test.c -o test这样将编译出一个名为test的程序-o参数用来指定生成程序的名字3、为什么会出现undefined reference to 'xxxxx'错误?首先这是链接错误,不是编译错误,也就是说如果只有这个错误,说明你的程序源码本身没有问题,是你用编译器编译时参数用得不对,你没有指定链接程序要用到得库,比如你的程序里用到了一些数学函数,那么你就要在编译参数里指定程序要链接数学库,方法是在编译命令行里加入-lm4、-l参数和-L参数-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?-lname,在连接时,装载名字为“libname.a”的函数库:-lm表示连接名为“libm.a”的数学函数库。
就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了好了现在我们知道怎么得到库名,当我们自已要用到一个第三方提供的库名字libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.so配套的头文件)放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。
LOCAL_CFLAGS参数说明

LOCAL_CFLAGS参数说明
1、-Wall
是打开警告开关
2、-O
代表默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3⾼级优化,-Os代码空间优化
3、-g
是⽣成调试信息,⽣成的可执⾏⽂件具有和源代码关联的可调试的信息
4、-fopenmp
OpenMp是由OpenMP Architecture Review Board牵头提出的,并已被⼴泛接受的,⽤于共享内存并⾏系统的多处理器程序设计的⼀套指导性的编译处理⽅案(Compiler Directive)。
OpenMP⽀持的编程语⾔包括C语⾔、C++和Fortran;⽽⽀持OpenMp的编译器包括Sun Compiler,GNU Compiler和Intel Compiler等。
OpenMp提供了对并⾏算法的⾼层的抽象描述,程序员通过在源代码中加⼊专⽤的pragma来指明⾃⼰的意图,由此编译器可以⾃动将程序进⾏并⾏化,并在必要之处加⼊同步互斥以及通信。
当选择忽略这些pragma,或者编译器不⽀持OpenMp时,程序⼜可退化为通常的程序(⼀般为串⾏),代码仍然可以正常运作,只是不能利⽤多线程来加速程序执⾏。
5、-D
增加全局宏定义
6、-ffast-math
浮点优化选项 -ffast-math:极⼤地提⾼浮点运算速度
7、-mfloat-abi=softfp 浮点运算。
gcc编译器 CFLAGS 标志参数说明

gcc编译器 CFLAGS 标志参数说明2012-11-14 15:10:28分类:LINUXCFLAGS = -g -O2 -Wall -Werror -Wno-unused编译出现警告性错误unused-but-set-variable,变量定义但没有使用,解决方法:增加CFLAGS 或CPPFLAGS参数如下:CPPFLAGS=" -Werror -Wno-unused-but-set-variable" || exit 1Gcc总体选项列表后缀名所对应的语言-S只是编译不汇编,生成汇编代码-E只进行预编译,不做其他处理-g在可执行程序中包含标准调试信息-o file把输出文件输出到file里-v打印出编译器内部编译各过程的命令行信息和编译器的版本-I dir在头文件的搜索路径列表中添加dir目录-L dir在库文件的搜索路径列表中添加dir目录-static链接静态库-llibrary连接名为library的库文件·“-I dir”正如上表中所述,“-I dir”选项可以在头文件的搜索路径列表中添加dir目录。
由于Linux 中头文件都默认放到了“/usr/include/”目录下,因此,当用户希望添加放置在其他位置的头文件时,就可以通过“-I dir”选项来指定,这样,Gcc就会到相应的位置查找对应的目录。
比如在“/root/workplace/Gcc”下有两个文件:#includeint main(){printf(“Hello!!\n”);return 0;}#include这样,就可在Gcc命令行中加入“-I”选项:[root@localhost Gcc] Gcc hello1.c –I /root/workplace/Gcc/ -o hello1这样,Gcc就能够执行出正确结果。
小知识在include语句中,“<>”表示在标准路径中搜索头文件,““””表示在本目录中搜索。
Gcc基本命令参数

CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到sparc CPU平台上才能运行。当然两个平台用的都是linux
这种方法在异平台移植和嵌入式开发时用得非常普遍
相对与交叉编译,我们平常做的编译就叫本地编译,也就是在当前平台编译,编译得到
另外,大部分libxxxx.so只是一个链接,以RH9为例,比如libm.so它链接到/lib/libm.s
o.x,/lib/libm.so.6又链接到/lib/libm-2.3.2.so,
如果没有这样的链接,还是会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx
库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一个链接就可以了
-LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。
-lLIBRARY 连接时搜索指定的函数库LIBRARY。
-m486 针对 486 进行代码优化。
-o FILE 生成指定的输出文件。用在生成可执行文件时。
-O0 不进行优化处理。
-O 或 -O1 优化生成代码。
-O2 进一步优化。
gcc与g++
Linux 中最重要的软件开发工具是 GCC。GCC 是 GNU 的 C 和 C++ 编译器。实际上,GCC 能够编译三种语言:C、C++ 和 Object C(C 语言的一种面向对象扩展)。利用 gcc 命令可同时编译并连接 C 和 C++ 源程序。
GCC 可同时用来编译 C 程序和 C++ 程序。一般来说,C 编译器通过源文件的后缀名来判断是 C 程序还是 C++ 程序。在 Linux 中,C 源文件的后缀名为 .c,而 C++ 源文件的后缀名为 .C 或 .cpp。
MakeFile详解

引用其它的Makefile-实例
有这样几个Makefile:a.mk、b.mk、c.mk,还有 一个文件叫foo.make,以及一个变量$(bar),其 包含了e.mk和f.mk,那么,下面的语句: include foo.make *.mk $(bar) 等价于: include foo.make a.mk b.mk c.mk e.mk f.mk
在大多数时候,由于源文件太多,编译生成的中间目标文 件太多,而在链接时需要明显地指出中间目标文件名,这
对于编译很不方便,所以,通常要给中间目标文件打个包,
在Windows 下这种包叫“库文件”(Library File),也就 是 .lib 文件,在UNIX 下,是Archive File,也就是 .a 文件。
定义变量和引用变量
变量的定义和应用与Linux环境变量一样,变量名 要大写,变量一旦定义后,就可以通过将变量名 用圆括号括起来,并在前面加上“$”符号来进行 引用。 变量的主要作用: 1、保存文件名列表 2、保存可执行命令名,如编译器 3、保存编译器的参数 变量一般都在makefile的头部定义。按照惯例, 所有的makefile变量都应该是大写。
者,通常是你需要告诉编译器头文件的所在位置,只要所有的语法正
确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应 该对应于一个中间目标文件(O 文件或是OBJ 文件)。
孙钦东
程序的编译和链接
链接时,主要是链接函数和全局变量。链接器并不管函数
所在的源文件,只管函数的中间目标文件(Object File)。
clean: -rm -f $(EXEC) *.elf *.gdb *.o
gflags用法

gflags用法gflags用法详解1. 简介gflags是一个用于解析命令行参数的开源库,可以方便地为C++和Java程序添加命令行参数,提供了简单易用的API和丰富的功能。
2. 安装C++版本下载和编译可以在gflags的官方GitHub仓库中下载源码,并按照README文件中的说明进行编译安装。
可以选择静态链接或者动态链接方式。
#### 配置项目将gflags的头文件路径添加到项目的include路径中,并将库文件路径添加到链接路径中。
#### 使用gflags 在需要使用gflags的源文件中,引入gflags的头文件<gflags/>。
Java版本下载和配置可以在gflags的官方GitHub仓库中下载Java版的gflags,并将下载好的gflags添加到项目的classpath中。
#### 使用gflags在需要使用gflags的Java源文件中,引入gflags的命名空间import *;。
3. 基本用法定义命令行参数在代码中使用DEFINE_<type>(flagname, default_value, description)宏定义一个命令行参数。
- <type>:参数类型,如int32、uint64、bool、double等。
- flagname:参数名,可以使用大小写字母、数字和下划线。
- default_value:参数的默认值。
- description:参数的描述信息。
解析命令行参数在main函数的开头调用google::ParseCommandLineFlags(&argc, &argv, true)来解析命令行参数,该函数会自动从命令行中获取参数值,并赋给对应的变量。
使用命令行参数用FLAGS_flagname访问参数的值,例如FLAGS_log_dir。
示例#include <gflags/>DEFINE_int32(num_iterations, 100, "Number of iterations ");DEFINE_bool(use_gpu, false, "Use GPU for computation"); int main(int argc, char* argv[]) {google::ParseCommandLineFlags(&argc, &argv, true);// 使用命令行参数for (int i = 0; i < FLAGS_num_iterations; ++i) { // 进行迭代计算}return 0;}4. 高级用法设置参数类型可以通过SetUsageMessage(message)设置命令行参数的使用说明。
cflags 参数

cflags 参数CFLAGS参数是在编译C语言程序时使用的参数,它用于指定编译器的选项和标志,以对程序进行优化或进行其他特定的操作。
本文将介绍CFLAGS参数的常见用法和作用。
一、CFLAGS参数的基本概念和作用CFLAGS参数是GCC编译器的一个选项,用于指定编译器的标志和选项。
通过使用CFLAGS参数,我们可以在编译C语言程序时指定一些特定的选项,以对程序进行优化或进行其他操作。
CFLAGS参数可以用于指定编译器的优化级别、警告级别、调试信息等。
二、CFLAGS参数的常见用法1. 指定优化级别优化级别用于指定编译器对程序进行优化的程度。
常见的优化级别包括-O0、-O1、-O2和-O3。
其中,-O0表示不进行优化,-O1表示进行基本的优化,-O2表示进行更多的优化,-O3表示进行最大程度的优化。
通过在CFLAGS参数中指定相应的优化级别,可以根据需求选择合适的优化程度。
2. 指定警告级别警告级别用于指定编译器产生警告信息的程度。
常见的警告级别包括-Wall、-Werror和-Wextra。
其中,-Wall表示生成所有常见的警告信息,-Werror表示将警告信息作为错误处理,-Wextra表示生成更多的警告信息。
通过在CFLAGS参数中指定相应的警告级别,可以帮助开发者发现潜在的问题,并改善代码质量。
3. 指定调试信息调试信息用于在程序运行过程中进行调试。
常见的调试信息选项包括-g、-ggdb和-g3。
其中,-g表示生成基本的调试信息,-ggdb 表示生成供GDB调试器使用的调试信息,-g3表示生成更详细的调试信息。
通过在CFLAGS参数中指定相应的调试信息选项,可以方便地进行程序的调试工作。
4. 其他选项除了上述常见的用法外,CFLAGS参数还可以用于指定其他一些选项,如指定include路径、定义宏等。
通过在CFLAGS参数中添加相应的选项,可以灵活地控制编译过程。
三、CFLAGS参数的使用示例下面是一些使用CFLAGS参数的示例:1. 指定优化级别为-O2和警告级别为-Wall:CFLAGS=-O2 -Wall2. 指定调试信息为-g和优化级别为-O1:CFLAGS=-g -O13. 指定调试信息为-ggdb和警告级别为-Werror:CFLAGS=-ggdb -Werror4. 指定include路径为/usr/include和定义宏DEBUG:CFLAGS=-I/usr/include -DDEBUG通过在Makefile或命令行中使用上述示例中的CFLAGS参数,可以根据具体需求对C语言程序进行编译。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
CFLAGS 详解CFLAGS 是决定Gentoo 系统效能与稳定的关键之一。
恰当的CFLAGS 能在效能、编译时间、与系统稳定度中取得平衡,失败的CFLAGS 可能导致编译失败,甚至系统损毁。
那么,在茫茫CFLAGS 海中,如何才能捞到命中注定那根针呢?此文件的CFLAGS 针对x86 与x86-64 平台上的GCC 3.4 (GNU Compiler Collections - /) 为主,若您使用其它编译器(如icc、compaq c compiler) 或其它平台(如PowerPC、Alpha),本章可能50% 以上的东西您都用不上。
各位请先参考笔者从网络上整理出,有关服务器与工作站需求的信息。
当然,服务器或桌面的需求绝对不只这些,这里仅列出跟设计CFLAGS 比较有关的项目。
以下是整理出的列表:1. 服务器系统:长时间启动(一天24 小时,一年365 天,全年无休)非常稳定(uptime 在99.999% [注] 以上)高安全性(别怀疑,CFLAGS 跟安全性也有很大的关系)在长时间启动的前提下,能自己照顾自己。
效能不是第一考虑互动反应不用很快,够用就好。
2. 桌面、工作站:启动时间没有那么长(使用者要用的时候才开机)可以不用那么稳定(多半有使用者直接在处理,uptime 可以降到99.99% 或更低)效能也是考虑重点互动反应快(如加载一页网页,与其让他在三秒时整面显示出来,不如让它每秒显示一点可是在四秒时才全部显示完毕。
)所以,得到了桌面系统的CFLAGS 设计要点:1. 程序启动时间短2. 反应速度快3. 效能高4. 稳定可以稍差(容许范围内)减少执行档的大小,可以同时减少了内存用量,也节省了一些磁盘空间。
同时,桌面系统最大的效能瓶颈就在磁盘驱动器,减少档案大小也间接降低了磁盘的存取次数,可以加速程序的启动,提升第一次执行的反应速度。
CFLAGS 选项再来,让我们看看gcc 中关键的几个选项。
这里只简单介绍这些选项的功能,若要详细说明请参考man gcc。
增加选项的数量,同时也增加编译的时间。
所有的选项都会增加编译时间,有特别说明"会增加编译时间" 的选项,表示会增加"大量的" 编译时间(跟其它选项比起来...)。
比较安全的选项首先是安全的选项:•指令参数与用法[注二]说明建议•-O-O (-O1), -O0, -O2, -O3, -Os依照后面数字的大小,针对效能最佳化的程度也不同(稳定度也可能递减)。
其中-Os 是个比较特殊的等级,针对原始码大小最佳化。
可使用-Os,降低程序加载的时间。
• -fforce-mem-fforce-addr-fforce-mem, -fno-force-mem-fforce-addr, -fno-force-addr强制在运算前将内存中的数值(mem) 或内存位置(addr) 复制到缓存器中。
启动这两个选项可以做出较好的程序代码。
这两个是好东西,启动它们!其中-fforce-mem 已在-O2, -O3, -Os 中启动,所以若您有用这三个选项的其中一个,只要-fforce-addr 就够了。
• -fomit-frame-pointer-fomit-frame-pointer, -fno-omit-frame-pointer若非必要,不将函式的frame pointer 放进缓存器中。
这将避免您的程序储存、设定、以及还原frame pointer;也在许多函式中省下一个缓存器。
这个选项可能让某些平台上的除错工作变成不可能!。
若平台支持不使用frame pointer 除错,这个选项将在-O, -O2, -O3, -Os 中启动。
很抱歉,x86 刚好是非这个不可才能除错的平台之一。
但是... 您想对您的桌面进行除错吗?若答案为非,您可以放心启动这个选项。
• -finline-functions-finline-functions, -fno-inline-functions将所有简单的函式整合进呼叫他们的函式中。
编译器会自动试探并决定那些函式值得被整合。
于-O3 时启动。
虽然这个选项会增加程序大小,但是他却是个增进效能的好东西。
我建议您在这里启动它,然后使用下面一个指令指定inline 条件。
• -finline-limit-finline-limit=nn 为决定函式是否能被inline 的伪指令长度。
预设的值为600。
这个数值越小,程序启动的速度越快,但是运算的速度越慢。
作为桌面使用,我建议-finline-limit=400。
• -fmove-all-movables-freduce-all-givs-fmove-all-movables, -fno-move-all-moveables-freduce-all-givs, -fno-redduse-all-givs这两个是循环最佳化技术,将无关循环内容的运算改在循环外执行。
编译出的执行档可能更快也可能更慢,结果跟程序的写法有很大的关系。
虽然说效能跟程序写法有关,但是大部份的状况下这两个选项会做出比较小与比较快的程序代码,所以我建议您启动他们!• -freorder-blocks-freorder-functions-freorder-blocks, -fno-reorder-blocks-freorder-functions, -fno-reorder-functions藉由重新编排程序区块来增进效能以及减少执行档大小。
这两个也是好东西,所以我建议您启动它们。
缺点是会让编译时间变长。
-freorder-blocks 于-O2, -O3 时启动,于-Os 中关闭。
-freorder-functions 于-O2, -O3, -Os 时启动。
• -fexpensive-optimizations-fexpensive-optimizations, -fno-expensive-optimizations执行几个会加长编译时间的非主要最佳化程序。
于-O2, -O3, -Os 中预设开启。
虽然会增加编译时间,但是能增加效能也能减少执行档大小,所以建议启用。
• -falign-functions-falign-labels-falign-loops-falign-jumps-falign-functions, -falign-functions=n-falign-labels, -falign-labels=n-falign-loops, -falign-loops=n-falign-jumps, -falign-jumps=n依照大于n 的最小2 的次方字节对齐函式(functions)、标签(labels)、循环(loops)、跳跃(jumps) 的起头,跳过至多n 字节。
我知道这很抽象,解释起来要花很多篇幅,所以请各位使用默认值,亦即指定-falign-functions, -falign-labels, -falign-loops, -falign-jumps,但是不指定=n。
于-O2, -O3 时启动。
于-Os 中关闭。
• -frename-registers-frename-registers, -fno-rename-registers在作过缓存器定位之后,使用剩下来的缓存器。
这个最佳化在有很多缓存器的CPU 上最明显(如ARM、PowerPC... 等。
x86 不属于他们的一份子)。
会增加除错的困难度。
虽然在x86 上不明显,但是还是有用。
而且x86-64 提供更多的缓存器,所以建议您还是应该打开它。
于-O3 时启动。
• -fweb-fweb, -fno-web建立经常使用的缓存器网络。
提供更佳的缓存器使用率。
不过也会增加除错的困难度。
这个是安全选项中比较偏向实验性质的选项,虽然建议您启动,但是若启动之后程序不稳,请将它关闭。
于-O3 时启动。
实验性质的选项以下是真的实验性质的东西,若启动之后系统不稳,请将他们关闭。
• 指令参数与用法说明建议• -ffast-math-ffast-math, -fno-fast-math设定-fno-math-errno, -funsafe-math-optimizations, -fno-trapping-math,-ffinite-math-only, -fno-rounding-math, 以及-fno-signaling-nans 这几个选项,以及设定预先处理器的__FAST_MATH__ 宏。
这些技术虽然较快,但是违反IEEE 或ISO 的规则,并且很有可能让程序算出错误的数值。
这是危险的东西,可能造成运算结果的错误(1.1+1.2=1.4!?当然没那么离谱啦...),建议不使用。
• -funit-at-a-time-funit-at-a-time, -fno-unit-at-a-time在制作执行文件前分析整个编译单位。
提供某些额外最佳化套用的机会,但会使用更多内存。
这个东西还蛮安全的,请放心使用它!• -funroll-loops-fold-unroll-loops-funroll-loops, -fno-unroll-loops-fold-unroll-loops, -fno-old-unroll-loops展开可以在编译阶段决定次数的循环,可能让程序执行的更快或更慢。
-fold-unroll-loops 使用旧的算法。
由于这个会让程序变大许多,所以建议不使用。
• -funroll-all-loops-fold-unroll-all-loops-funroll-all-loops, -fno-unroll-all-loops-fold-unroll-all-loops, -fno-old-unroll-all-loops即使循环执行次数不确定,还是将所有循环展开。
大部份状况下会让程序跑得更慢。
又比较慢又会变大,所以别用...• -fprefetch-loop-arrays-fprefetch-loop-arrays, -fno-prefetch-loop-arrays若目标机器支持,在存取大型数组循环执行之前预先将数组加载至内存。
于-Os 中关闭。
其实不太会有需要存取大型数组的循环(多媒体、数据库、科学计算软件中才比较常见),所以您可以放心将此选项关闭。
• -ffunction-sections-fdata-sections-ffunction-sections, -fno-function-sections-fdata-sections, -fno-data-sections将函式或资料物品放至自己的区段中。
大部份使用ELF 目标格式的系统以及执行Solaris 2 的SPARC 系统支持这些最佳化。