编译过程 [英] The compilation process

查看:180
本文介绍了编译过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以解释编译的工作原理吗?



我似乎不知道编译的工作原理。



更具体来说,这里是一个例子..我想写一些代码在MSVC ++ 6加载一个Lua状态..






  • 设置库的附加目录并将文件包含到正确的目录中

  • used extern C(因为Lua只是C,所以我听到了)

  • 包含正确的头文件




但是我仍然得到一些错误在MSVC ++ 6关于未解决的外部符号(对于我使用的Lua函数)。



尽管我想知道如何解决这个问题并继续前进,但我认为如果我了解所涉及的基本过程会更好,所以任何人都可以写一个很好的解释这个?我想知道的是过程..它可能看起来像这样:



步骤1:




  • 输入:源代码

  • 处理:解析(可能在此处添加更多详细信息)




步骤2:




  • 输入:无论从步骤1输出什么,加上可能需要的任何其他内容(库?DLLs?.so?.lib?)

  • / li>
  • 输出:无论输出什么



谢谢..



也许这将解释什么符号是什么,什么链接是什么对象代码或什么。 。



感谢..对不起是一个noob ..



这不必是语言的具体..但随时用您最舒适的语言表达它...:)



EDIT :所以无论如何,我能够得到错误解决,结果是,我必须手动添加.lib文件到项目;在IDE设置或项目设置中简单指定库目录(.lib所在的位置)不起作用。



但是,下面的答案有些帮助我理解过程更好。非常感谢!如果有人还想写一个彻底的指南,请做..:)



编辑:仅供参考,我发现两个文章由一个作者(迈克迪尔)解释这相当不错:)
检查编译过程:第1部分
检查编译过程:第2部分

解决方案

一个两阶段的C语言和相关语言的过程,尽管IDE可能把它作为一个单一的过程。



1 /你编写你的源代码并运行它通过编译器。在这个阶段的编译器需要你的源和你要链接的其他东西的头文件(见下文)。



编译包括转动你的源文件转换为目标文件。对象文件具有您编译的代码和足够的信息,以便知道他们需要什么其他东西,但不是在哪里找到其他东西(例如,LUA库)。



2 /链接,下一个阶段,是将所有的对象文件与库相结合来创建可执行文件。我不会在这里讨论动态链接,因为这会使解释复杂化而没有什么好处。



不仅需要指定链接器可以找到其他代码的目录,您需要指定包含该代码的实际库。



例如,考虑下面的简化C代码( xx.c )和命令。

  #include< bob.h> 
int x = bob_fn(7);

cc -c -o xx.obj xx.c

xx.c 文件更改为 xx.obj bob.h 包含 bob_fn()的原型,以便编译成功。 -c 指示编译器生成目标文件而不是可执行文件, -o xx.obj 设置输出文件名。



bob_fn()的实际代码头文件但在 /bob/libs/libbob.so ,所以要链接,你需要像:

  cc -o xx.exe xx.obj -L / bob / libs; / usr / lib -lbob 

这会从 xx.obj 创建 xx.exe 在给定路径中搜索) libbob.so (通常由链接器添加lib和.so)。在此示例中, -L 设置库的搜索路径。 -l <​​/ code>指定要在必要时包含在可执行文件中的库。链接器通常采用bob,并在 -L 指定的搜索路径中找到第一个相关库文件。



库文件实际上是一个目标文件的集合(如何一个zip文件包含多个其他文件,但不一定压缩) - 当发现未定义的外部的第一个相关事件时,目标文件从库并像添加到可执行文件一样 xx.obj 文件。这通常继续,直到没有更多的未解决的外部。 相关库是对bob文本的修改,它可以查找 libbob.a libbob.dll libbob.so bob.a bob.dll bob.so 等。相关性由链接器本身决定,并应记录。



它的工作原理取决于链接器,但基本上是这样。



1 /所有的对象文件包含一个未解决的外部列表,他们需要解决。链接器将所有这些对象放在一起,并修复它们之间的链接(尽可能解决尽可能多的外部)。



2 / / em>未解析,链接器会梳理库文件,寻找可以满足链接的目标文件。如果它找到它,它拉它 - 这可能导致进一步未解决的外部,因为拉入的对象可能有自己的外部列表需要满足。



3 /重复步骤2,直到没有更多的未解决的外部或没有可能从库列表解决它们(这是你的开发,因为你没有包括LUA库文件)。



我之前提到的复杂性是动态链接。这是你链接到一个例程(一种标记)的桩,而不是实际的例程,它在加载时(当你运行可执行文件时)解决。诸如Windows公共控件之类的东西在这些DLL中,所以他们可以改变,而不必将对象重新链接到一个新的可执行文件。


Can anyone explain how compilation works?

I can't seem to figure out how compilation works..

To be more specific, here's an example.. I'm trying to write some code in MSVC++ 6 to load a Lua state..

I've already:

  • set the additional directories for the library and include files to the right directories
  • used extern "C" (because Lua is C only or so I hear)
  • include'd the right header files

But i'm still getting some errors in MSVC++6 about unresolved external symbols (for the Lua functions that I used).

As much as I'd like to know how to solve this problem and move on, I think it would be much better for me if I came to understand the underlying processes involved, so could anyone perhaps write a nice explanation for this? What I'm looking to know is the process.. It could look like this:

Step 1:

  • Input: Source code(s)
  • Process: Parsing (perhaps add more detail here)
  • Output: whatever is output here..

Step 2:

  • Input: Whatever was output from step 1, plus maybe whatever else is needed (libraries? DLLs? .so? .lib? )
  • Process: whatever is done with the input
  • Output: whatever is output

and so on..

Thanks..

Maybe this will explain what symbols are, what exactly "linking" is, what "object" code or whatever is..

Thanks.. Sorry for being such a noob..

P.S. This doesn't have to be language specific.. But feel free to express it in the language you're most comfortable in.. :)

EDIT: So anyway, I was able to get the errors resolved, it turns out that I have to manually add the .lib file to the project; simply specifying the library directory (where the .lib resides) in the IDE settings or project settings does not work..

However, the answers below have somewhat helped me understand the process better. Many thanks!.. If anyone still wants to write up a thorough guide, please do.. :)

EDIT: Just for additional reference, I found two articles by one author (Mike Diehl) to explain this quite well.. :) Examining the Compilation Process: Part 1 Examining the Compilation Process: Part 2

解决方案

From source to executable is generally a two stage process for C and associated languages, although the IDE probably presents this as a single process.

1/ You code up your source and run it through the compiler. The compiler at this stage needs your source and the header files of the other stuff that you're going to link with (see below).

Compilation consists of turning your source files into object files. Object files have your compiled code and enough information to know what other stuff they need, but not where to find that other stuff (e.g., the LUA libraries).

2/ Linking, the next stage, is combining all your object files with libraries to create an executable. I won't cover dynamic linking here since that will complicate the explanation with little benefit.

Not only do you need to specify the directories where the linker can find the other code, you need to specify the actual library containing that code. The fact that you're getting unresolved externals indicates that you haven't done this.

As an example, consider the following simplified C code (xx.c) and command.

#include <bob.h>
int x = bob_fn(7);

cc -c -o xx.obj xx.c

This compiles the xx.c file to xx.obj. The bob.h contains the prototype for bob_fn() so that compilation will succeed. The -c instructs the compiler to generate an object file rather than an executable and the -o xx.obj sets the output file name.

But the actual code for bob_fn() is not in the header file but in /bob/libs/libbob.so, so to link, you need something like:

cc -o xx.exe xx.obj -L/bob/libs;/usr/lib -lbob

This creates xx.exe from xx.obj, using libraries (searched for in the given paths) of the form libbob.so (the lib and .so are added by the linker usually). In this example, -L sets the search path for libraries. The -l specifies a library to find for inclusion in the executable if necessary. The linker usually takes the "bob" and finds the first relevant library file in the search path specified by -L.

A library file is really a collection of object files (sort of how a zip file contains multiple other files, but not necessarily compressed) - when the first relevant occurrence of an undefined external is found, the object file is copied from the library and added to the executable just like your xx.obj file. This generally continues until there are no more unresolved externals. The 'relevant' library is a modification of the "bob" text, it may look for libbob.a, libbob.dll, libbob.so, bob.a, bob.dll, bob.so and so on. The relevance is decided by the linker itself and should be documented.

How it works depends on the linker but this is basically it.

1/ All of your object files contain a list of unresolved externals that they need to have resolved. The linker puts together all these objects and fixes up the links between them (resolves as many externals as possible).

2/ Then, for every external still unresolved, the linker combs the library files looking for an object file that can satisfy the link. If it finds it, it pulls it in - this may result in further unresolved externals as the object pulled in may have its own list of externals that need to be satisfied.

3/ Repeat step 2 until there are no more unresolved externals or no possibility of resolving them from the library list (this is where your development was at, since you hadn't included the LUA library file).

The complication I mentioned earlier is dynamic linking. That's where you link with a stub of a routine (sort of a marker) rather than the actual routine, which is later resolved at load time (when you run the executable). Things such as the Windows common controls are in these DLLs so that they can change without having to relink the objects into a new executable.

这篇关于编译过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆