Multiple Source Files in a Project

Started by
4 comments, last by v0dKA 19 years, 10 months ago
I wondered about this long ago when I quit DOS and started Windows programming, but never bothered to ask. I just sort of accepted the fact that it works, and tried to never bother about it again, but... How does execution work in multiple source files? I''m used to the old traditional DOS way of programming with a single source file to handle everything. But Visual C++ (6.0... does it matter?) always precompiles like 10 source files to handle the different parts of the applications (child frame, document, view, etc...). This sort of bothers me since I don''t know how it compiles that. Say I have a variable declared in source file #4, and I use it in source file #3. What then? Which order does it compile in? What if I throw a new source file of my own, after/before what will that code segment be executed? VERY CONFUSED, PLEASE HELP!!!! .:<<-v0d[KA]->>:.
.:<<-v0d[KA]->>:.
Advertisement
lol I remember wondering about how all this worked a long time ago. Here is a basic run through of how the compiler works to pull off multiple file compilation. First let''s run through the process with only one file. We can call this project.c.

1. You write the code into a nice little text file and save it as project.c

2. When you hit the build button and it runs through checking for errors and turns project.c into project.obj obj = object code. That is that project.c is changed from C to Machine code.

3. Then the linker on the compiler runs. Now basically without you even knowing it.... you have been doing multiple file programming and you didn''t even know it. Even in DOS 8-0

When you are doing DOS programming and you do this
#include <stdio.h>

This means you want need to make calls to the functions from the "standard input / output" library. Well if you search your drive you will find a correspoding stdio.lib file that was shipped with your compiler that corresponds to stdio.h.

What happens is that when you compile your project.c the compiler will see that you included stdio.h and therefore any calls that you make to that code will be fine. Otherwise if you don''t include that header, it won''t find the code and give you an error.

Now the stdio.lib is actually the machine code version of the stdio.c file that someone at microsoft made, compiled, and released for you to use with the compiler. stdio.lib is actually the same as stdio.obj with a library extension.

Anyhow when your compiler hits the link stage, it will see that you have included stdio.h and therefore it will take your project.obj and stdio.lib and "link" them together into one piece of machine code. Then it names that piece of code project.exe

So in a nut shell, every time you #include something, you are telling your compiler to link in another piece of code that someone else already compiled into machine code format.

The only difference between this and multiple file projects that you make, is that you start with the source code and #include your own header files that correspond with your own C files

So if you have have Part1.c that calls functions in Part2.c that you created. you will have to put
#include "part2.h" into part.c telling the compiler that you want to link part2.c into part1.c after they are both converted to machine code.

So the compiler starts with part1.c part2.c and part2.h
builds part1.obj and part2.obj from those. Then it will link both of the obj files together to form the executable part1.exe

I hope this clears things up for you. If not let me know and we will talk about it some more. You can find me on our own forums at Neuron.





Sincerely,
Randy Trulson
www.GamePotato.com
www.NeuronGames.com
Sincerely,Randy Trulsonwww.NeuronGames.com
I have a question along these lines that I think I should mention

And thank you Randy of Neuron for that clear and comprehensive post on compiling and linking! I really enjoyed reading it. I have been doing a lot of compiler experimentation and figuring out this stuff. The only things that still confuse me are... when to include extern "C" and why C++ "decorates" functions and stuff, how .dll's give the calling application the right pointers to the functions, and the real different between .lib and .obj and why all libraries are compiled as .libs instead of .obj. Also I don't get why some libraries pick and choose functions to put into your .exe depending on your needs and other libraries just dump everything on you (D3DX?).

But I do have a question: What is the proper way to share globals between separately compiled source files? Does it work to just include the variable/class/whatever in the header and then include the header in both source files? And if you declare the same variable (same type/same name) in multiple source files, will the linker be able to realize they are the same variable when you link to make your exe?

Thanksabunch!

[edited by - Boder on June 5, 2004 5:55:46 AM]
One thing that took me a while to realize was that when you include a header file, the compiler puts everything in that file on top of your code. Here''s an example...

Timer functions
===========================timer.h===========================getTime(){   implementation}setTime(){   implementation}===========================


Your main file

===========================main.cpp===========================#include "timer.h"main(){    cout << "hello world";    getTime();}===========================


This is close to what happens. Everything in timer.h gets copied over to where you included it. This is why if you declare a function below a function call, you''ll get an error, because the compiler doesn''t know where to look for the function.

===========================almost actual code===========================getTime(){   implementation}setTime(){   implementation}main(){    cout << "hello world";    setTime();}


What actually happens (correct me if i''m wrong anyone) is that after compilation, your code looks sorta like this with only the functions you used being in the code. They are pasted where the function is called.

===========================actual code===========================main(){    cout << "hello world";    setTime()    {       implementation    }}
About the function being pasted, I believe that happens if the compiler optimizes by inlining the function. You can suggest to the compiler to inline (inline func(){}) or force the compiler to do so (__forceinline funct(){} in VC++).

But I''m still wondering if there is anyone out there who can explain the difference between ".lib" and ".obj" I mean I can link 2 obj and obj''s and lib''s, but probably not libs and libs. Why do APIs and standard libraries use lib instead of obj?

Anyone know what flags/options to set in order to make cl.exe (command-line compiler in VC++) compile a .lib? Help much appreciated thanks!

Part of the confusion probably comes from the fact that .lib files can be either static or import libraries.

In the case of static libraries, they simply contain .obj files. When you link with static libraries, the actual code ends up in your .exe or .dll file.

In the case of import libraries, the .lib file contains references to entry points (functions) in a DLL. When you link with import libraries, your .exe or .dll just ends up with those references, which are resolved at run time by the loader.

As far as I know, you can''t create .lib files with cl.exe. Instead, you have to first produce your .obj files and then use lib.exe (or link -lib) to add them to a library. For example:

C:\temp\test>cl /c test.cC:\temp\test>lib /out:test.lib test.objC:\temp\test>dir /b test.*test.ctest.libtest.objC:\temp\test>lib /nologo /list test.libtest.obj


Cheers,

Facet

This topic is closed to new replies.

Advertisement