C/C++培训
美国上市C/C++培训机构

400-111-8989

热门课程

在没有IDE的情况下,如何编译链接C/C++程序?

  • 发布:Debug
  • 来源:非正常程序员
  • 时间:2017-09-20 17:10

我们在开发程序的时候都会用到IDE(集成开发环境),我用的时间最长的是Visual Studio 2008,这样我们在编辑代码以及做编译操作都会非常的方便,但是我们编译程序真的只能依赖于像IDE这样的庞然大物吗?这肯定不是必须的,在这篇文章里,我们换一种思路,抛开臃肿的IDE,采用原始的方法来编译、链接以及运行一个工程。

在开始之前先讲一下微软的编译器cl.exe。cl是微软提供的C/C++编译器,我们在集成开发环境(IDE)中点击编译,真正工作的其实是cl程序。单纯使用cl编译器是在命令行模式中。不止是cl编译器,还有后面提到的link、rc,这些都是命令行使用方式。那么抛开集成开发环境,我们只要使用cl程序,就可以达到我们编译源代码的目的。有人说与IDE中编译相比,命令行模式编译速度更快,并可以避免被IDE产生的一些附加信息干扰,会有一些优点,但其实使用IDE会有更大的好处,使用方便,可以把更多的心思放在代码上等等,我个人平时工作的时候都是使用IDE进行编译,对于接下来说的命令行模式的编译只不过提供了另外一种思路。

我们写代码的时候很大一部分比重依赖于集成开发环境(IDE),比如我在Windows平台下开发C/C++代码的时候用的是微软的VS 2008,但是我们如果在没有IDE的情况下如何去编译链接我们的项目呢?

首先我们要搞清楚的是,编译链接到底是怎么一回事儿?首先我们在写好代码的时候需要将代码转换成机器码,也就是二进制文件,这就是程序,才可以在机器上运行,而编译,就是将代码转换成机器码的其中一个步骤。我们利用编译器,将代码转换成为obj目标文件,在通过链接器将新生成的目标文件和代码中调用到库函数的目标文件以及一些资源链接在一起,形成最终的执行文件。这就是编译器和链接器做的工作。

好了,我们刚才提到了我们的编译器cl以及连接器link,我们要开始使用他们了,但还有一点准备工作是我们目前要做的。微软的编译器和链接器的安装,有这些东东才能用呀。在VS各个版本或者较早的VC里面都有这些工具,安装VS就可以找到他们,我使用的是VS 2008,而我的安装路径是默认的C盘,cl程序和link程序应该在“C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin”这个路径下,如果你在这个路径中没有找到,可以搜索“cl.exe”,这样就可以找到对应的路径。由于这些程序在使用的时候是命令行模式,在打开命令提示符后我们直接输入命令“cl”,这个时候会提示找不到该命令,这很尴尬,因为我们没有配置环境变量,关于环境变量简单说一句,就说一句,你可以这样理解,就是我们本来要想在命令提示符的当前文件夹中输入一个程序名来执行,但是这个程序却不在这个当前文件夹下,如果将程序所在目录配置到环境变量中,那么我们打开命令提示符直接敲击命令就可以了,根本不用担心找不到这个命令。如果有装过Java的JDK和JRE的童鞋会清楚这是怎么一回事,如果想了解更多的环境变量的内容,可以上网查找,资料很多,这里不做扩展。到目前为止,我们知道了我们要配置路径,才能方便的使用,但是我在这里提供另外一种思路,也是我们采用cl编译器最惯用的一种做法,不是配置环境变量,而是使用“vcvars32.bat”批处理。

说来话很简单,这个批处理就是为了在命令提示窗口中怕找不到cl和link以及资源编译的rc等等这些命令准备的。这个批处理处于cl.exe文件的同级目录下,你可以直接将这个批处理通过拖拽的方式拖到命令提示符中,然后点击回车,搞定,在输入cl发现命令可以使用。亦或者,你可以通过“call”命令,直接在命令提示符中输入“call "%VS90COMNTOOLS%"vsvars32.bat”(将最外面的引号里面的东西全复制),直接执行了这个批处理,这样更方便,效果和拖拽的方式一样。这种调用批处理的方式有个地方需要注意一下,就是关闭了这个命令提示窗后再打开命令提示窗,需要重新执行“vcvars32.bat”批处理文件。OK,不管你使用什么样的方式,这个做完后,准备工作就算是完成了,我们可以自由自在的使用命令了,啦啦啦~

在这个地方我会演示编译单文件以及编译多个文件,先从单文件开始,我在自己的D盘里创建一个名为“test”的文件夹,在里面创建一个C++文件叫做“hello.cpp”,这个代码很简单,就是在屏幕输出“Hello World”。

hello.cpp

#include <stdio.h>

int main()

{

printf("Hello World !\n");

return 0;

}

目前代码写完了,默认的情况下,利用cl.exe编译生成的obj会在命令提示符中的当前位置出现,如果我想默认生成在D盘test文件夹中就要把命令提示符当前位置改变。在命令提示符中输入“cd /d d:\test”指令,进入到D盘,注意里面的“/d”,不加这个不会从默认的C盘转到D盘,还需要额外加上“d:”才能跳转到D盘,这个是cmd命令的使用,有点跑题了,我们在回来,这个做完之后直接使用cl命令。“cl /c hello.cpp”,注意这个地方的参数,加上“/c”,代表着只编译不链接,不加这个会在编译过后直接调用link进行链接,最终直接生成exe文件,在这里我们先编译,要不然我们就用不到link命令了,就没办法讲link(手动尴尬),这个时候会在test文件夹下生成一个obj文件,我们调用link命令直接链接这个obj,输入命令“link hello.obj”,完成后会在test文件夹中看到“hello.exe”,直接在命令提示符里调用新生成的程序,你就会看到屏幕上输出“Hello World !”了,怎么样,简单吧!

那么现在我们来大体看看cl和link常用的功能有哪些,我们在此做一个汇总。

cl基本使用

cl有很多选项,请通过“cl /?”获取完整列表。这里列出了一些最重要的选项(选项的前缀可以是'-'或'/')。

无选项:

>cl foo.c bar.c

说明:编译出foo.obj,bar.obj并自动调用链接器link链接得到foo.exe。

/c:只编译不链接

>cl /c foo.c bar.c

说明:编译出foo.obj,bar.obj,但不调用链接器。

/link <lib>:指定要链接的Library

>cl /link kernel32.lib foo.c

说明:编译出foo.obj,并链接kernel32.lib,得到foo.exe。

/I <dir>:把目录加入include搜录路径中

/D<name>{=|#}<text>:定义预处理器

>cl /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE

说明:定义2个预处理器。

link基本使用

link也同样有很多很多的选项,下面仅列出一些常用选项。

[/debug]:产生调试信息

link /out:main.exe main.obj

说明:链接main.obj并生成main.exe。

[/pdb:<target>]:产生调试符号文件

link /debug /out:main.exe main.obj

说明:链接main.obj并生成带有调试信息的main.exe。

[/out:<target>]:指定输出文件

link /debug /pdb:main.pdb /out:main.exe main.obj

说明:链接main.obj并生成带有调试信息的main.exe以及调试符号文件main.pdb。

[/subsystem:<target>]:指定子系统

link /subsystem:windows /out:main.exe main.obj kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

说明:编译windows程序,入口函数自动设为WinMain,其中kernel32.lib,...,odbccp32.lib等为windows程序必须链接的lib。

[/libpath:<dir>]:把目录加入lib搜索路径中。如果有多个路径,则要写多次/libpath

link /libpath:../common /out:main.exe main.obj lua.lib

说明:链接../common中的lua.lib。

值得注意的是:

如果同时提供main和WinMain,那么必须手工指定/subsystem。

如果只提供main,则链接器自动指定/subsystem:console。

这些是比较常用的一些,还有很多不进行一一说明,现在说一下编译链接多个文件。在这里只是单纯的说一说,不进行贴图,不附上代码,来,跟上我的节奏!

还是test文件夹,在里面有hello.cpp,同时创建一个汽车类,分别对应car.h头文件和car.cpp头文件,在hello.cpp中创建这个类对象,并调用里面的公开函数,这样,一个多文件的小程序诞生了,我们同样,先编译,“cl /c hello.cpp car.cpp”,这样会生成两个obj文件,hello.obj以及car.obj,在调用“link hello.obj car.obj”进行链接,这样就会在文件夹里生成“hello.exe”文件,注意,如果把car.obj写在hello.obj前面,“link car.obj hello.obj”,这样默认未指定生成文件名的情况下,生成的exe文件名字就是car.exe。大家GET到了吗?

那么讲完编译链接,还有一个是在Windows开发环境当中使用到的,那就是在上文偶尔提到过的资源编译器rc.exe。这个文件在我电脑里的“C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin”这个路径下,同样需要执行“vcvars32.bat”才能使用该命令。那么这个命令到底是干什么的?在Windows应用程序中,图标、菜单、位图、工具条、对话框等是以资源的形式存在的。开发人员也可以自定义资源类型。如果一个程序使用了资源,那么它在构建时需要对资源进行编译。程序所使用的资源会在资源脚本文件(*.rc)中进行描述编写,编译时,资源编译器会将*.rc文件编译为可链接的.res文件。我们还是同样在test文件夹中写入hello.rc资源文件,在里面随便写上资源代码:

hello.rc

/////////////////////////////////////////////

//

// Icon

//

IDR_MAINFRAME ICON DISCARDABLE "C://Hello.ico"

这样我们调用命令“rc /n /v /fo Hello.res Hello.rc”,这样就会生成hello.res文件,通过link命令,将res于obj同时链接,形成新的exe文件,那么rc命令不进行详细的讲解了,如果感兴趣的朋友可以去网上查看更详细的信息。

到目前为止,cl和link以及rc命令基本就讲到这里,因为使用这些命令的方法还有很多很多,这点大家如果用到的话在查一下编译器说明书,查到你所需要的内容。就目前来看,这篇文章致力于给大家提供一个全新的思路,开发开中并不意味这这么使用效率会高,在我的工作经历中不会使用这种命令行进行编译,我们都会在IDE里进行编译链接,这样更方便,快捷,通过有界面的方式会是体验更友好,更舒服。那么话说回来,命令行的方式也并非一无是处,有很多大咖还是会这样使用的。

其实今天讲的命令如果不讲“nmake”的使用的话,这些命令的使用效率并不高,你想想我们如果编译上百个文件的话,用这种方式还不得哭晕,那么下一个讲解的主题就是关于整体编译脚本的编写,在Linux开发环境中也会经常用到,那么在windows环境里这个命令是“nmake”,将我们的编译链接步骤写成脚本就可以了,由于篇幅的原因,这个部分我打算留在未来下一个主题进行讲解。


预约申请免费试听课

上一篇:C语言数据的基本类型有哪些?
下一篇:我为什要学C语言

免费C++开发工具有哪些?整理11款给你!

免费C++开发工具有哪些?C++免费开发工具简介

C++开发有哪些好的辅助工具

程序员快速入门C++的3大方法

选择城市和中心
贵州省

广西省

海南省