在Linux下面,如果要编译一个C语言源程序,我们要使用gcc编译器。
先将源文件编译成目标文件:gcc - c hello.c
生成hello.o文件,再将目标文件编译成可执行文件:gcc -o hello hello.o
如:
int main(int argc,char **argv)
{
printf("Hello Linux ");
}
(1)一般编译选项是扩展阅读:
在使用GCC编译器的时候,我们必须给出一系列必要的调用参数和文件名称。GCC编译器的调用参数大约有100多个,这里只介绍其中最基本、最常用的参数。具体可参考GCC Manual。
GCC最基本的用法是∶gcc [options] [filenames]
其中options就是编译器所需要的参数,filenames给出相关的文件名称。
网络_gcc
Ⅱ Linux 编译选项
gcc -E source_file.c
-E,只执行到预编译。直接输出预编译结果。
gcc -S source_file.c
-S,只执行到源代码到汇编代码的转换,输出汇编代码。
gcc -c source_file.c
-c,只执行到编译,输出目标文件。
gcc (-E/S/c/) source_file.c -o output_filename
-o, 指定输出文件名,可以配合以上三种标签使用。
-o 参数可以被省略。这种情况下编译器将使用以下默认名称输出:
-E:预编译结果将被输出到标准输出端口(通常是显示器)
-S:生成名为source_file.s的汇编代码
-c:生成名为source_file.o的目标文件。
无标签情况:生成名为a.out的可执行文件。
gcc -g source_file.c
-g,生成供调试用的可执行文件,可以在gdb中运行。由于文件中包含了调试信息因此运行效率很低,且文件也大不少。
这里可以用strip命令重新将文件中debug信息删除。这是会发现生成的文件甚至比正常编译的输出更小了,这是因为strip把原先正常编译中的一些额外信息(如函数名之类)也删除了。用法为 strip a.out
gcc -s source_file.c
-s, 直接生成与运用strip同样效果的可执行文件(删除了所有符号信息)。
gcc -O source_file.c
-O(大写的字母O),编译器对代码进行自动优化编译,输出效率更高的可执行文件。
-O 后面还可以跟上数字指定优化级别,如:
gcc -O2 source_file.c
数字越大,越加优化。但是通常情况下,自动的东西都不是太聪明,太大的优化级别可能会使生成的文件产生一系列的bug。一般可选择2;3会有一定风险。
gcc -Wall source_file.c
-W,在编译中开启一些额外的警告(warning)信息。-Wall,将所有的警告信息全开。
gcc source_file.c -L/path/to/lib -lxxx -I/path/to/include
-l, 指定所使用到的函数库,本例中链接器会尝试链接名为libxxx.a的函数库。
-L,指定函数库所在的文件夹,本例中链接器会尝试搜索/path/to/lib文件夹。
-I, 指定头文件所在的文件夹,本例中预编译器会尝试搜索/path/to/include文件夹。
Ⅲ 如何设置NDK的编译选项
1. 概述
首先回顾一下 Android NDK 开发中,Android.mk 和 Application.mk 各自的职责。
Android.mk,负责配置如下内容:
(1) 模块名(LOCAL_MODULE)
(2) 需要编译的源文件(LOCAL_SRC_FILES)
(3) 依赖的第三方库(LOCAL_STATIC_LIBRARIES,LOCAL_SHARED_LIBRARIES)
(4) 编译/链接选项(LOCAL_LDLIBS、LOCAL_CFLAGS)
Application.mk,负责配置如下内容:
(1) 目标平台的ABI类型(默认值:armeabi)(APP_ABI)
(2) Toolchains(默认值:GCC 4.8)
(3) C++标准库类型(默认值:system)(APP_STL)
(4) release/debug模式(默认值:release)
由此我们可以看到,本文所涉及的编译选项在Android.mk和Application.mk中均有出现,下面我们将一个个详细介绍。
2. APP_ABI
ABI全称是:Application binary interface,即:应用程序二进制接口,它定义了一套规则,允许编译好的二进制目标代码在所有兼容该ABI的操作系统和硬件平台中无需改动就能运行。(具体的定义请参考 网络 或者 维基网络 )
由上述定义可以判断,ABI定义了规则,而具体的实现则是由编译器、CPU、操作系统共同来完成的。不同的CPU芯片(如:ARM、Intel x86、MIPS)支持不同的ABI架构,常见的ABI类型包括:armeabi,armeabi-v7a,x86,x86_64,mips,mips64,arm64-v8a等。
这就是为什么我们编译出来的可以运行于Windows的二进制程序不能运行于Mac OS/Linux/Android平台了,因为CPU芯片和操作系统均不相同,支持的ABI类型也不一样,因此无法识别对方的二进制程序。
而我们所说的“交叉编译”的核心原理也跟这些密切相关,交叉编译,就是使用交叉编译工具,在一个平台上编译生成另一个平台上的二进制可执行程序,为什么可以做到?因为交叉编译工具实现了另一个平台所定义的ABI规则。我们在Windows/Linux平台使用Android NDK交叉编译工具来编译出Android平台的库也是这个道理。
这里给出最新 Android NDK 所支持的ABI类型及区别:
那么,如何指定ABI类型呢?在 Application.mk 文件中添加一行即可:
APP_ABI := armeabi-v7a //只编译armeabi-v7a版本APP_ABI := armeabi armeabi-v7a //同时编译armeabi,armeabi-v7a版本APP_ABI := all //编译所有版本
3. LOCAL_LDLIBS
Android NDK 除了提供了Bionic libc库,还提供了一些其他的库,可以在 Android.mk 文件中通过如下方式添加依赖:
LOCAL_LDLIBS := -lfoo
其中,如下几个库在 Android NDK 编译时就默认链接了,不需要额外添加在 LOCAL_LDLIBS 中:
(1) Bionic libc库
(2) pthread库(-lpthread)
(3) math(-lmath)
(4) C++ support library (-lstdc++)
下面我列了一个表,给出了可以添加到“LOCAL_LDLIBS”中的不同版本的Android NDK所支持的库:
下面是我总结的一些常用的CFLAGS编译选项:
(1)通用的编译选项
-O2 编译优化选项,一般选择O2,兼顾了优化程度与目标大小
-Wall 打开所有编译过程中的Warning
-fPIC 编译位置无关的代码,一般用于编译动态库
-shared 编译动态库
-fopenmp 打开多核并行计算,
-Idir 配置头文件搜索路径,如果有多个-I选项,则路径的搜索先后顺序是从左到右的,即在前面的路径会被选搜索
-nostdinc 该选项指示不要标准路径下的搜索头文件,而只搜索-I选项指定的路径和当前路径。
--sysroot=dir 用dir作为头文件和库文件的逻辑根目录,例如,正常情况下,如果编译器在/usr/include搜索头文件,在/usr/lib下搜索库文件,它将用dir/usr/include和dir/usr/lib替代原来的相应路径。
-llibrary 查找名为library的库进行链接
-Ldir 增加-l选项指定的库文件的搜索路径,即编译器会到dir路径下搜索-l指定的库文件。
-nostdlib 该选项指示链接的时候不要使用标准路径下的库文件
(2) ARM平台相关的编译选项
-marm -mthumb 二选一,指定编译thumb指令集还是arm指令集
-march=name 指定特定的ARM架构,常用的包括:-march=armv6, -march=armv7-a
-mfpu=name 给出目标平台的浮点运算处理器类型,常用的包括:-mfpu=neon,-mfpu=vfpv3-d16
-mfloat-abi=name 给出目标平台的浮点预算ABI,支持的参数包括:“soft”, “softfp” and “hard”
Ⅳ 条件编译选项 什么意思
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件下才进行编译,即对一部分内容指定编译条件,这就是“条件编译”。(conditional compile) 条件编译语句排版时,需考虑以下三种位置: (1)条件编译语句块与函数定义体之间不存在相互嵌套(主要在(.h)文件中) ◆ 条件编译关键字语句顶格左对齐; ◆ 所含的#include语句(块) #define语句(块)甚至是被嵌套下级条件编译语句块,按照语句块嵌套的排版方式进行缩进排版 。 (2)条件编译语句块嵌套在函数体之外(主要在(.c)文件中) 这种情况下,条件编译语句块不影响函数体 ◆ 条件编译关键字语句顶格左对齐; ◆ 所含的函数体定义无需缩进,依旧按照单个函数体定义的排版方式进行。 (3)条件编译语句嵌套在函数体内 (主要在(.c)文件中) a)当条件编译语句块与被包语句所属的语句块之间没有逻辑路径交叉时,以下两种方式均可 ◆ 按照语句块嵌套方式进行缩进排版 (推荐); ◆ 条件编译语句不影响原先语句块排版,条件编译语句与所包含的关键字语句块左对齐 。 b)当条件编译语句块与被包语句所属的语句块之间存在逻辑路径交叉时 ◆ 条件编译语句顶格左对齐,其它语句按照正常顺序排版。 条件编译的形式如下所示(NNN、MMM等都是在某处已经定义为 1 或者 0 的): #if NNN statement1; #elif MMM statement2; #else statement3; #endif 条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。 1.#if指令 #if指令检测跟在制造另关键字后的常量表达式。如果表达式为真,则编译后面的代码,直到出现#else、#elif或#endif为止;否则就不编译。 2.#endif指令 #endif用于终止#if预处理指令。 #define DEBUG 0 main() { #if DEBUG printf("Debugging\n"); #endif printf("Running\n"); } 由于程序定义DEBUG宏代表0,所以#if条件为假,不编译后面的代码直到#endif,所以程序直接输出Running。 如果去掉#define语句,效果是一样的。 3.#ifdef和#ifndef #define DEBUG main() { #ifdef DEBUG printf("yes\n"); #endif #ifndef DEBUG printf("no\n"); #endif } #if defined等价于#ifdef; #if !defined等价于#ifndef 4.#else指令 #else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码。#endif指令将中指上面的条件块。 #define DEBUG main() { #ifdef DEBUG printf("Debugging\n"); #else printf("Not debugging\n"); #endif printf("Running\n"); } 5.#elif指令 #elif预处理指令综合了#else和#if指令的作用。 #define TWO main() { #ifdef ONE printf("1\n"); #elif defined TWO printf("2\n"); #else printf("3\n"); #endif } 程序很好理解,最后输出结果是2。 6.其他一些标准指令 #error指令将使编译器显示一条错误信息,然后停止编译。 #line指令可以改变编译器用来指出警告和错误信息的文件号和行号。 #pragma指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息
Ⅳ 急急!c++编译器的选项和调用!
不论是不是用IDE, 和编译结果是控制台APP 还是WIN32APP, 没有关系的。
为什么要用CL 编译win32程序,不用IDE? 原因何在?
CL编译win32肯定没问题的,具体用法可以参考CL帮助, 我记得很简单的, 给你示例如下:
C:Program Files (x86)Microsoft Visual Studio 11.0VCin>vcvars32.bat
C:Program Files (x86)Microsoft Visual Studio 11.0VCin>cl
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
┈┈来自:网络香港交流吧, 诚邀大家帮忙关注!!!
Ⅵ linux makefile gcc 什么编译选项
这个没有什么特殊的要求。你只要按照你需要的正确的语法规则和编译顺序,将 gcc 编译器对 C 语言源程序的编译选项(例如:对源程序只编译不连接的选项为:-c、或者是生成指定的运行文件:-o my_outputfile,等等)写到 makefile 文本文件中即可...
Ⅶ 请教编译选项mole和mole capable的区别
编译是编译器在你程序没有运行的时候帮你检查错误 调试是你用调试器在程序运行以后,根据运行状况来检查错误 在写程序的时候,两个环节都是需要的 顺便你看的书不太准确。所谓的文件中写上# include "afx.h"(或者其他头文件),那么就只需要调试。
Ⅷ 如何设置编译选项 ubuntu
这个就要看你的具体的编译器了。例如:在 UBUNTU 系统下,使用的是 gcc C 语言编译器,那么就一定要遵循 gcc 的编译选项规定。例如:gcc myfile.c,该命令产生的是一个缺省的输出运行文件 a.out;gcc -o myrunfile myfile.c,该命令将会产生一个输出文件为 myrunfile 的运行文件;gcc -c myfile.c,该命令是只产生一个 myfile.o 的中间文件,只编译、不连接。除此之外,你还需要注意 makefile 文件的编写规则,因为该文件才是真正要把所有的源程序的编译选项按照一定的规则写到 makefile 文件中,然后再整体对源程序进行编译、连接。
Ⅸ vc的各编译选项都是什么意思
VC编译选项
/Od 禁用优化(默认值) disable optimizations (default)
/Ox 最大化选项。(/Ogityb2 /Gs) maximum opts. (/Ogityb1 /Gs)
/Og 启用全局优化 enable global optimization
/Oy[-] 启用框架指针省略 enable frame pointer omission
/Oi 启用内建函数 enable intrinsic functions
-代码生成-
/G3 为 80386 进行优化 optimize for 80386
/G4 为 80486 进行优化 optimize for 80486
/GR[-] 启用 C++ RTTI enable C++ RTTI
/G5 为 Pentium 进行优化 optimize for Pentium
/G6 为 Pentium Pro 进行优化 optimize for Pentium Pro
/GX[-] 启用 C++ 异常处理(与 /EHsc 相同) enable C++ EH (same as /EHsc)
/EHs 启用同步 C++ 异常处理 enable synchronous C++ EH
/GD 为 Windows DLL 进行优化 optimize for Windows DLL
/GB 为混合模型进行优化(默认) optimize for blended model (default)
/EHa 启用异步 C++ 异常处理 enable asynchronous C++ EH
/Gd __cdecl 调用约定 __cdecl calling convention
/EHc extern“C”默认为 nothrow extern "C" defaults to nothrow
/Gr __fastcall 调用约定 __fastcall calling convention
/Gi[-] 启用增量编译 enable incremental compilation
/Gz __stdcall 调用约定 __stdcall calling convention
/Gm[-] 启用最小重新生成 enable minimal rebuild
/GA 为 Windows 应用程序进行优化 optimize for Windows Application
/Gf 启用字符串池 enable string pooling
/QIfdiv[-] 启用 Pentium FDIV 修复 enable Pentium FDIV fix
/GF 启用只读字符串池 enable read-only string pooling
/QI0f[-] 启用 Pentium 0x0f 修复 enable Pentium 0x0f fix
/Gy 分隔链接器函数 separate functions for linker
/GZ 启用运行时调试检查 enable runtime debug checks
/Gh 启用钩子函数调用 enable hook function call
/Ge 对所有函数强制堆栈检查 force stack checking for all funcs
/Gs[num] 禁用堆栈检查调用 disable stack checking calls
-输出文件-
/Fa[file] 命名程序集列表文件 name assembly listing file
/Fo 命名对象文件 name object file
/FA[sc] 配置程序集列表 configure assembly listing
/Fp 命名预编译头文件 name precompiled header file
/Fd[file] 命名 .PDB 文件 name .PDB file
/Fr[file] 命名源浏览器文件 name source browser file
/Fe 命名可执行文件 name executable file
/FR[file] 命名扩展 .SBR 文件 name extended .SBR file
/Fm[file] 命名映射文件 name map file
-预处理器-
/FI 命名强制包含文件 name forced include file
/C 不吸取注释 don't strip comments
/U 移除预定义宏 remove predefined macro
/D{=|#} 定义宏 define macro
/u 移除所有预定义宏 remove all predefined macros
/E 将预处理定向到标准输出 preprocess to stdout
/I 添加到包含文件的搜索路径 add to include search path
/EP 将预处理定向到标准输出,不要带行号 preprocess to stdout, no #line
/X 忽略“标准位置” ignore "standard places"
/P 预处理到文件 preprocess to file
-语言-
/Zi 启用调试信息 enable debugging information
/Zl 忽略 .OBJ 中的默认库名 omit default library name in .OBJ
/ZI 启用调试信息的“编辑并继续”功能 enable Edit and Continue debug info
/Zg 生成函数原型 generate function prototypes
/Z7 启用旧式调试信息 enable old-style debug info
/Zs 只进行语法检查 syntax check only
/Zd 仅要行号调试信息 line number debugging info only
/vd{0|1} 禁用/启用 vtordisp disable/enable vtordisp
/Zp[n] 在 n 字节边界上包装结构 pack structs on n-byte boundary
/vm 指向成员的指针类型 type of pointers to members
/Za 禁用扩展(暗指 /Op) disable extensions (implies /Op)
/noBool 禁用“bool”关键字 disable "bool" keyword
/Ze 启用扩展(默认) enable extensions (default)
- 杂项 -
/?, /help 打印此帮助消息 print this help message
/c 只编译,不链接 compile only, no link
/W 设置警告等级(默认 n=1) set warning level (default n=1)
/H 最大化外部名称长度 max external name length
/J 默认 char 类型是 unsigned default char type is unsigned
/nologo 取消显示版权消息 suppress right message
/WX 将警告视为错误 treat warnings as errors
/Tc 将文件编译为 .c compile file as .c
/Yc[file] 创建 .PCH 文件 create .PCH file
/Tp 将文件编译为 .cpp compile file as .cpp
/Yd 将调试信息放在每个 .OBJ 中 put debug info in every .OBJ
/TC 将所有文件编译为 .c compile all files as .c
/TP 将所有文件编译为 .cpp compile all files as .cpp
/Yu[file] 使用 .PCH 文件 use .PCH file
/V 设置版本字符串 set version string
/YX[file] 自动的 .PCH 文件 automatic .PCH
/w 禁用所有警告 disable all warnings
/Zm 最大内存分配(默认为 %) max memory alloc (% of default)
-链接-
/MD 与 MSVCRT.LIB 链接 link with MSVCRT.LIB
/MDd 与 MSVCRTD.LIB 调试库链接 link with MSVCRTD.LIB debug lib
/ML 与 LIBC.LIB 链接 link with LIBC.LIB
/MLd 与 LIBCD.LIB 调试库链接 link with LIBCD.LIB debug lib
/MT 与 LIBCMT.LIB 链接 link with LIBCMT.LIB
/MTd 与 LIBCMTD.LIB 调试库链接 link with LIBCMTD.LIB debug lib
/LD 创建 .DLL Create .DLL
/F 设置堆栈大小 set stack size
/LDd 创建 .DLL 调试库 Create .DLL debug libary
/link [链接器选项和库] [linker options and libraries]
Ⅹ Compile,Make和Build的区别
在Java的集成开发环境中,比如Eclipse、IDEA中,有常常有三种与编译相关的选项Compile、Make、Build三个选项。这三个选项最基本的功能都是完成编译过程。但又有很大的区别,区别如下:
1、Compile:只编译选定的目标,不管之前是否已经编译过。
2、Make:编译选定的目标,但是Make只编译上次编译变化过的文件,减少重复劳动,节省时间。(具体怎么检查未变化,这个就不用考虑了,IDE自己内部会搞定这些的)
3、Build:是对整个工程进行彻底的重新编译,而不管是否已经编译过。Build过程往往会生成发布包,这个具体要看对IDE的配置
了,Build在实际中应用很少,因为开发时候基本上不用,发布生产时候一般都用ANT等工具来发布。Build因为要全部编译,还要执行打包等额外工
作,因此时间较长。