我们都知道c程序源代码经过 组建 编译 连接 .c -> .obj -> .exe 生成可执行文件及简单的软件。那么我们怎么找到这个可执行文件呢?并且把它拿出到其他地方使用呢? 下面介绍详细的操作步骤。
-
C/C++程序编译步骤 如何生成可执行文件
2011-03-28 23:00:00C/C++语言很多人都比较熟悉,这基本上是每位大学生必学的一门编程语言,通常还都是作为程序设计...VC的“舒适”开发环境屏蔽了很多编译的细节,这无疑降低了初学者的入门门槛,但是也“剥夺”了他们“知其所以然”的C/C++语言很多人都比较熟悉,这基本上是每位大学生必学的一门编程语言,通常还都是作为程序设计入门语言学的,并且课程大多安排在大一。刚上大学,孩子们还都很乖,学习也比较认真,用心。所以,C/C++语言掌握地也都不错,不用说编译程序,就是写个上几百行的程序都不在话下,但是他们真的知道C/C++程序编译的步骤么?
我想很多人都不甚清楚,如果他接下来学过“编译原理”,也许能说个大概。VC的“舒适”开发环境屏蔽了很多编译的细节,这无疑降低了初学者的入门门槛,但是也“剥夺”了他们“知其所以然”的权利,致使很多东西只能死记硬背,遇到相关问题就“丈二”。实际上,我也是在学习Linux环境下编程的过程中才逐渐弄清楚C/C++源代码是如何一步步变成可执行文件的。
总体来说,C/C++源代码要经过:预处理、编译、汇编和连接四步才能变成相应平台下的可执行文件。大多数时候,程序员通过一个命令就能完成上述四个步骤。比如下面这段C的“Hello world!”代码:
File: hw.c#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello World!/n");
return 0;
}
如果用gcc编译,只需要一个命令就可以生成可执行文件hw:xiaosuo@gentux hw $ gcc -o hw hw.c
xiaosuo@gentux hw $ ./hw Hello World!
我们可以用-v参数来看看gcc到底在背后都做了些什么动作:Reading specs from /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/specs
Configured with: /var/tmp/portage/sys-devel/gcc-3.4.6-r2/work/gcc-3.4.6/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/3.4.6 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.6 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.6/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.6/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include/g++-v3 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-libunwind-exceptions --disable-multilib --disable-libgcj --enable-languages=c,c++,f77 --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu
Thread model: posix
gcc version 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)
/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/cc1 -quiet -v hw.c -quiet -dumpbase hw.c -mtune=pentiumpro -auxbase hw -version -o /tmp/ccYB6UwR.s
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include
/usr/include
End of search list.
GNU C version 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10) (i686-pc-linux-gnu)
compiled by GNU C version 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.9).
GGC heuristics: --param ggc-min-expand=81 --param ggc-min-heapsize=97004
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../i686-pc-linux-gnu/bin/as -V -Qy -o /tmp/ccq8uGED.o /tmp/ccYB6UwR.s
GNU assembler version 2.17 (i686-pc-linux-gnu) using BFD version 2.17
/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o hw /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6 -L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6 -L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../../i686-pc-linux-gnu/lib -L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../.. /tmp/ccq8uGED.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crtn.o
稍微整理一下,去掉一些冗余信息后,如下:cc1 hw.c -o /tmp/ccYB6UwR.s
as -o /tmp/ccq8uGED.o /tmp/ccYB6UwR.s
ld -o hw /tmp/ccq8uGED.o
以上三个命令分别对应于编译步骤中的预处理+编译、汇编和连接。预处理和编译还是放在了一个命令(cc1)中进行的,可以把它再次拆分为以下两步:cpp -o hw.i hw.c
cc1 hw.i -o /tmp/ccYB6UwR.s
一个精简过的能编译以上hw.c文件的Makefile如下:.PHONY: clean
all: hw
hw: hw.o
ld -dynamic-linker /lib/ld-linux.so.2 -o hw /usr/lib/crt1.o /
/usr/lib/crti.o /
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbegin.o /
hw.o -lc /
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /
/usr/lib/crtn.o
hw.o: hw.s
as -o hw.o hw.s
hw.s: hw.i
/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/cc1 -o hw.s hw.c
hw.i: hw.c
cpp -o hw.i hw.c
clean:
rm -rf hw.i hw.s hw.o
当然,上面Makefile中的一些路径是我系统上的具体情况,你的可能与我的不同。
接下来我们按照编译顺序看看编译器每一步都做了什么。
首先是预处理,预处理后的文件hw.i:# 1 "hw.c"
# 1 "<built-in>"
# 1 "<command line>"
...
__extension__ typedef __quad_t __off64_t;
__extension__ typedef int __pid_t;
__extension__ typedef struct { int __val[2]; } __fsid_t;
...
extern int remove (__const char *__filename) __attribute__ ((__nothrow__));
extern int rename (__const char *__old, __const char *__new) __attribute__ ((__nothrow__));
...
int main(int argc, char *argv[])
{
printf("Hello World!/n");
return 0;
}
注:由于文件比较大,所以只留下了少部分具有代表性的内容。
可以看见预处理器把所有要包含(include)的文件(包括递归包含的文件)的内容都添加到了原始的C源文件中,然后把其输出到输出文件,除此之外,它还展开了所有的宏定义,所以在预处理器的输出文件中你将找不到任何宏。这也提供了一个查看宏展开结果的简便方法。
第二步“编译”,就是把C/C++代码“翻译”成汇编代码:.file "hw.c"
.section .rodata
.LC0:
.string "Hello World!/n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
subl $12, %esp
pushl $.LC0
call printf
addl $16, %esp
movl $0, %eax
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)"
这个汇编文件比预处理后的C/C++文件小了很多,去除了很多不必要的东西,比如说没用到的类型声明和函数声明等。
第三步“汇编”,将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux上一般表现为ELF目标文件。xiaosuo@gentux hw $ file hw.o
hw.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
最后一步“连接”,将上步生成的目标文件和系统库的目标文件和库文件连接起来,最终生成了可以在特定平台运行的可执行文件。为什么还要连接系统库中的某些目标文件(crt1.o, crti.o等)呢?这些目标文件都是用来初始化或者回收C运行时环境的,比如说堆内存分配上下文环境的初始化等,实际上crt也正是C RunTime的缩写。这也暗示了另外一点:程序并不是从main函数开始执行的,而是从crt中的某个入口开始的,在Linux上此入口是_start。以上Makefile生成的是动态连接的可执行文件,如果要生成静态连接的可执行文件需要将Makefile中的相应段修改:hw: hw.o
ld -m elf_i386 -static -o hw /usr/lib/crt1.o /
/usr/lib/crti.o /
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbeginT.o /
-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6 /
-L/usr/i686-pc-linux-gnu/lib /
-L/usr/lib/ /
hw.o --start-group -lgcc -lgcc_eh -lc --end-group /
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /
/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/../../../crtn.o
至此,一个可执行文件才最终创建完成。通常的项目中并不需要把编译过程分得如此之细,前三步一般是合为一体的,在Makefile中表现如下:hw.o: hw.c
gcc -o hw.o -c hw.c
实际上,如果对hw.c进行了什么更改,那么前三步大多数情况下都是不可避免的。所以把他们写在一起也并没有什么坏处,相反倒可以用--pipe参数告诉编译器用管道替代临时文件,从而提升编译的效率。 -
如何编译生成.exe可执行文件,并保存
2015-07-22 10:28:20我们都知道c程序源代码经过 组建 编译 连接 .c -> .obj -> .exe 生成可执行文件及简单的软件。那么我们怎么找到这个可执行文件呢?并且把它拿出到其他地方使用呢? 下面介绍详细的操作步骤。 ... -
Qt中如何给生成的可执行文件设置图标
2016-03-29 09:27:43近期由于需要大量使用QT来做毕业设计的程序的界面,也就顺带复习了下Qt的开发,在美化界面时,发现需要对编译的Release的exe可执行文件设置图标,于是查阅资料,发现还是在qt自己的文档里提供了解决方案,原文为英文...近期由于需要大量使用QT来做毕业设计的程序的界面,也就顺带复习了下Qt的开发,在美化界面时,发现需要对编译的Release的exe可执行文件设置图标,于是查阅资料,发现还是在qt自己的文档里提供了解决方案,原文为英文,我根据自己的理解并实践的步骤如下:
1、先要自己准备一个ico类型的图标文件,通常我们下载到的图标库大多是png类型的,因此,可以去下载一个转换工具,这类工具也很好找,vc自带的工具也可以生成ico文件,这里建议如果有png图标的朋友可以去greendown.cn去下载一个叫做ToYcon的工具,操作很简单。(PS:你没听过greendown?那你out了 呵呵)2、将ico文件拷贝到你的源码目录,新建一个名为myapp.rc的文件(其他的名字也可以,但后缀必须是rc,和vs开发时的资源文件一样),在其中写入如下内容:IDI_ICON1 ICON DISCARDABLE "myappico.ico"上面的ico文件名根据自己的实际情况填写,保存退出3、在qt项目的pro文件中添加一行:RC_FILE = myapp.rc4、用qmake或者creator重新build你的工程就该可以了 -
VC6生成的串口执行程序如何在其它电脑上运行
2013-07-12 15:28:32然后Rebuild All,生成可执行文件。 2. 在使用该执行的文件的目标电脑上,注册串口Active X控件: 2.1 先在自己的电脑(安装VC的电脑)上将MSCOMM32.ocx文件拷到目标电脑。该文件在自己电脑的C:\windows ...1. 在VC6的配置中,需选择“使用MFC作为静态链接库”
然后Rebuild All,生成可执行文件。
2. 在使用该执行的文件的目标电脑上,注册串口Active X控件:
2.1 先在自己的电脑(安装VC的电脑)上将MSCOMM32.ocx文件拷到目标电脑。该文件在自己电脑的C:\windows
system32路径下可以找到。
2.2 然后在目标电脑上注册该文件,步骤如下:
左下角控制窗口点击“运行”,弹出的窗口中输入: RegSvr32 X:\MSCOMM32.OCX
其中"X:"指2.1步骤中目标电脑拷入MSCOMM32.OCX存放的盘符。
完成注册后即可正常使用。
-
VC中怎样修改生成的EXE文件的图标
2014-07-05 15:48:42介绍如何将生成的.exe可执行程序的图标修改为自己的图标 -
VC程序如何保护初始化文件不被别人修改
2017-01-18 23:32:15vc程序中一些配置写在初始化文件setting.ini中,我只希望别人使用我程序生成的可执行文件,不希望别人更改初始化文件,有什么办法可以防止别人修改我的初始化文件呢,除了更改文件类型和后缀名,改了后缀名还是可以... -
C语言文件编写完成以后 如何生成一个exe.文件啊
2008-10-20 09:17:00源程序编译通过以后 如果用的是vc6、7、8系列的话直接按f7 就会自动生成EXE文件|||编写完成后进行编译 点右上一个感叹号就...如果是VC++的话 按钮也不同 (1) 是由源程序生成可执行文件 编译好的exe文件放在工程目录下 -
如何在VC工程生成的exe当中添加不常见的资源(比如说zip包)
2011-10-10 16:34:44在vc工程当中除了添加ico、对话框资源、菜单资源和位图资源等标准资源类型之外,它还支持自定义资源类型...我所做的工程就是在用户双击可执行文件之后解压一个zip文件,我希望zip文件加载到exe文件中,而不希望是两个文 -
如何在map文件中生成行信息?
2011-05-16 17:43:00在 VC 中,我们可以按下 Alt+F7 ,打开“Project Settings”选项页,选择 C/C++ 选项卡,并在最下面的 ...最后按下 F7 来编译生成 EXE 可执行文件和 MAP 文件。 /Zd -
vc如何在GUI界面下显示命令窗
2015-09-04 16:35:21vc的方法如下: 生成事件(build event)->生成后事件(post-build event)->命令行(command line), 输入: editbin /SUBSYSTEM:CONSOLE $(OUTDIR)\filename.exe,(其中filename为...例如你的可执行文件名为Hello -
如何用c读取文件
2011-12-15 14:33:49应该用fscanf()函数来读取下面给个小例子: 保存代码时,以.C为后缀... 应该在Debug文件夹里面再运行程序(VC6.0编译程序时,生成的可执行文件放在Debug文件夹里面,里面要有"成绩.txt"文件)#include#includevoid ReadStuden -
[转载]如何改变VC中控件间的TAB切换顺序
2010-09-19 16:03:00然后用VC打开,重新生成执行文件执行一下: VC中控件的TAB切换顺序即是资源文件中上述BEGIN...END间先后出现的顺序---- 改变其中的控件出现顺序(在文本编辑器中)便可改变控件间的TAB切换顺序。 -
如何编译和选择,遇到无法打开文件“libboost_thread-vc120-mt-gd-1_58.lib的解决办法
2017-05-24 21:44:082.解压到文件夹,我解压到了E:\boost。 3.在开始菜单打开Visual Studio Tools,, 然后选择X86命令行提示。...5.此时会生成一个名为bjam.exe的可执行文件,使用这个工具来编译boost库,VS2013要指定输 -
VC2008 mfc90ud.dll无法找到问题如何解决
2011-09-19 22:36:41解决方案一:项目属性->配置属性->链接器->调试->生成映射文件 选择 Yes (/MAP)...解决方案二:工具—>选项—>项目和解决方案—>VC++目录,在可执行文件栏中加上如下路径: $(SystemRoot)\System32 $(SystemRoot) $ -
gcc编译c++文件_如何编译和运行C++程序?
2021-01-20 01:25:01C++ 和C语言类似,也要经过编译和链接后才能运行。在《C语言编译器》专题中我们讲到了 VS、Dev C++、VC 6.0、Code::Blocks、C-Free、GCC、Xcode 等常见 IDE 或编译器,它们除了...下图是 C/C++ 代码生成可执行文件... -
源码C语言VC_学习编程了解,源码如何被机器识别,接收命令进行操作?
2021-01-14 17:12:50什么是编译器(编程软件)?...比如C语言、C++这样的程序,当我们一行一行写下代码后,需要经过编译器的“翻译”才能变成可执行程序才可以执行。才可以实现代码到程序的转变,而这一切都需要编译器帮我... -
如何将Matlab程序编译成exe文件方法介绍
2017-07-26 14:38:15一、生成独立可执行的程序(exe文件)步骤 1、安装编译器。可有多种选择,matlab自带了一个LCC,但我使用的是MATLAB2014版本,直接运行会报错,我是安装了VS2010 2、设置编译器。在matlab命令行输入mbuild –setup,... -
vc中nmake.exe cl.exe 的使用
2013-08-09 12:11:00首先简单介绍一下程序是如何编译链接的。程序写好之后,我们进行编译和...makefile 就是被vc使用保存这些信息的方法之一,编译时程序nmake根据makefile中的信息,在用相应选项执行编译,用相应执行链接,最后生成可... -
c程序生成过程
2015-04-05 11:28:19但我们的程序是如何从代码编程计算机课可执行的文件的,好像不是很清楚,这个IDE悄悄帮我们做了好多事情。 我们的程序从代码变成机器可执行的机器码,一般经过 预编译,编译,汇编,链接。这几个步骤,为什么是这样... -
运行程序_如何编译和运行C++程序?
2021-01-12 03:13:04C++ 和C语言类似,也要经过编译和链接后才能运行。在《C语言编译器》专题中我们讲到了 VS、Dev C++、VC 6.0、Code::Blocks、C-Free、GCC、Xcode 等常见 IDE 或编译器,它们除了...下图是 C/C++ 代码生成可执行文件... -
c语言结束程序命令_如何编译和运行C++程序?
2020-11-27 02:59:45C++ 和C语言类似,也要经过编译和链接后才能运行。在《C语言编译器》专题中我们讲到了 VS、Dev C++、VC 6.0、Code::Blocks、C-Free、GCC、Xcode 等常见 IDE 或编译器,它们除了...下图是 C/C++ 代码生成可执行文件... -
如何配置VS+OPENCV 环境
2018-04-23 10:46:401、下载VS,下载OPENCV (如果需要做图像拼接下载opencv2.4.9)2、设置环境变量,path 如E:\opencv\opencv\build\x64\vc11\bin3、生成VS空项目-属性管理器-VC++目录-可执行文件目录-编辑修改包含目录,库目录,配置... -
《VC实战HTTP之POST》教程第一期更新完成
2015-11-10 10:07:45d、如何使用类似jsoncpp的开源库为己用; ④、获取本电脑公网ip地址; 15、全自动注册网易邮箱之流程分析: ①、多入口分析; ②、使用Chrome浏览器模拟手机浏览器; ③、根据抓包结果分析注册流程; 16、... -
CByteArray 和 CString 如何使用,麻烦大侠们看看我这个代码
2016-06-22 01:46:081> 没有可用于执行该转换的用户定义的转换运算符,或者无法调用该运算符 1>e:/w? /ABCRC/ABCRC/ABCRC.cpp(141) : error C2065: 1>Exception: error status 2 from d:/Program Files (x86)/Microsoft Visual Studio ... -
VS中warning LNK4204缺少引用模块的调试信息;正在链接对象,如同没有调试信息一样
2020-06-12 17:13:43错误原因:这种是在静态库时,才会出现的错误,缺少了vc100.pdb(VS2010是vc100.pdb,VS2008,是vc90.pdb...最早的调试信息格式是COFF格式,这种格式内嵌到可执行文件中的,它能记录函数、变量、行号、FPO等信息。 CodeView -
dvc视觉计算平台2
2013-11-06 22:34:21将源代码编译后生成的可执行文件放到部署目录下,请自行解决第三方程序文件(如OpenCV, OpenGL, Logcxx, msxml, IL, assimp等,需根据编译所依赖的版本),以及MSVCR,MSVCP,MFC等VC再分发文件。所需的配置文件已... -
make大作战
2011-02-22 09:48:00<br />(1)vc中实际调用cl.exe和link.exe来进行编译和链接工作。...而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系