Why Should I Recompile an Entire Program Just for a Library Update

Why should I recompile an entire program just for a library update?

If the signatures of the functions involved haven't changed, then "rebuilding" the program means that the object files must be linked again. You shouldn't need to compile them again.

An API is contract that describes the interface to the public functions in a library. When the compiler generates code, it needs to know what type of variables to pass to each function, and in what order. It also needs to know the return type, so it knows the size and format of the data that will be returned from the function. When your code is compiled, the address of a library function may be represented as "start of the library, plus 140 bytes." The compiler doesn't know the absolute address, so it simply specifies an offset from the beginning of the library.

But within the library, the contents (that is, the implementations) of the functions may change. When that happens, the length of the code may change, so the addresses of the functions may shift. It's the job of the linker to understand where the entry points of each function reside, and to fill those addresses into the object code to create the executable.

On the other hand, if the data structures in the library have changed and the library requires the callers to manage memory (a bad practice, but unfortunately common), then you will need to recompile the code so it can account for the changes. For example, if your code uses malloc(sizeof(dataStructure)) to allocate memory for a library data structure that's doubled in size, you need to recompile your code because sizeof(dataStructure) will have a larger value.

Should i rebuild a dependent lib after system update?

This is why package systems exist.

If your libhell binary library is dynamic library (that is a libhell.so shared object, with position independent code) and if the dependency libssl-dev didn't change its API (e.g. if its version number didn't change), then you don't need to recompile and reinstall your libhell.

If you feel that your libhell depends upon a changed feature (or data) of libssl-dev then you should recompile it.

Better recompile your libhell more often than needed.

See also the Program Library Howto

.NET No need to recompile program after library editing

.NET DLLs have some degree of backwards-compatibility. Adding a field is not a binary-breaking change.

C++ -- When recompilation is required

Classes are defined in the header file. The header file will be compiled into both the library that implements the class and the code that uses the class. I am assuming that you are taking as a given that you will need to recompile the class implementation after changing the class header file and that the question you are asking is whether you will need to recompile any code that references the class.

The problem that you are describing is one of binary compatibility (BC) and generally follows the following rules:

  1. Adding non-virtual functions anywhere in the class does not break BC.
  2. Changing any function definition (adding parameters )will break BC.
  3. Adding virtual functions anywhere changes the v-table and therefore breaks BC.
  4. Adding data members will break BC.
  5. Changing a parameter from non-default to default will not break BC.
  6. Any changes to inline functions will break BC (inline function should therefore be avoided if BC is important.)
  7. Changing compiler (or sometimes even compiler versions) will probably break BC unless the compilers adhere strickly to the same ABI.

If BC is a major issue for the platform you are implementing it could well be a good idea to separate out the interface and implementation using the Bridge pattern.

As an aside, the C++ language does not deal with the Application Binary Interface (ABI). If binary compatibility is a major issue, you should probably refer to your platform's ABI specification for more details.

Edit: updated adding data members. This will break BC because more memory will now be needed for the class than before.

Why do you need to recompile C/C++ for each OS?


Don't we target the CPU architecture/instruction set when compiling a C/C++ program?

No, you don't.

I mean yes, you are compiling for a CPU instruction set. But that's not all compilation is.

Consider the simplest "Hello, world!" program. All it does is call printf, right? But there's no "printf" instruction set opcode. So... what exactly happens?

Well, that's part of the C standard library. Its printf function does some processing on the string and parameters, then... displays it. How does that happen? Well, it sends the string to standard out. OK... who controls that?

The operating system. And there's no "standard out" opcode either, so sending a string to standard out involves some form of OS call.

And OS calls are not standardized across operating systems. Pretty much every standard library function that does something you couldn't build on your own in C or C++ is going to talk to the OS to do at least some of its work.

malloc? Memory doesn't belong to you; it belongs to the OS, and you maybe are allowed to have some. scanf? Standard input doesn't belong to you; it belongs to the OS, and you can maybe read from it. And so on.

Your standard library is built from calls to OS routines. And those OS routines are non-portable, so your standard library implementation is non-portable. So your executable has these non-portable calls in it.

And on top of all of that, different OSs have different ideas of what an "executable" even looks like. An executable isn't just a bunch of opcodes, after all; where do you think all of those constant and pre-initialized static variables get stored? Different OSs have different ways of starting up an executable, and the structure of the executable is a part of that.

Does Java recompile every file every time?

The Eclipse Java builder is incremental (see "Sidebar: the Java Builder" on this page), so it shouldn't be having to rebuild your entire project every time. Something unusual must be going on if it is indeed recompiling every single file.

Do I need to rebuild and redeploy every time I upgrade a COM library used from my dotNet app?


and can't find any tlb file for the COM in question.

It is normally embedded in the COM server DLL. Something you can see with Visual Studio, File + Open + File and select the DLL. You'll see a TYPELIB node, resource 1 is the type library.

You can decompile the type library by running Oleview.exe from the Visual Studio Command Prompt. File + View Typelib and select the DLL. Copy/paste the content of the right pane into a text editor and save it. If there is any change in this IDL then you must rebuild the import library and your program. Not doing so can cause very difficult to diagnose runtime problems that include access violation exceptions and calling the completely wrong method.

This is hard to automate, clearly you'll prefer a better way for the vendor to let you know about breaking changes. The programmer that worked on this server should be well aware of the need for this.

Why creating DLLs instead of compiling everything to a one big executable?

It's a tradeoff

(You figured that out yourself already ;))

For most projects, the customer doesn't care about how many files get installed, but he cares how many features are completed in time. Making life easier for developers benefits the user, too.

Some more reasons for DLL's

Some libraries don't play well together in the same build, but can be made to behave in a DLL (e.g. one DLL may use WTL3, the other requires WTL8).

Some of the DLL's may contain components to be loaded into other executables (global hooks, shell extensions, browser addons).

Some of the DLL's might be 3rd party, only available as DLL.

There may be reuse within the company - even if you see only one "public" product, it might be used in a dozen of internal projects using that DLL.

Some of the DLL's might have been built with a different environment thats not available for all developers in the company.

Standalone EXE vs. Installed product

Many products won't work as standalone executable anyway. They require installation, and the user not touching things he's not supposed to touch. Having one or more binaries doesn't matter.

Build Time Impact

Maybe you underestimate the impact of build times, and maintaining a stable build for large projects. If a build takes even 5 minutes, you could ephemistically call that "make developers think ahead, instead of tinker until it seems to work ok". But it's a serious time eater, and creates a serious distraction.

Build time of a single project is hard to improve. Working on VC9, build parallelization within one project is shaky, as is the incremental linker. Link times are especially hard to "optimize away" by faster machines.

Developer Independence

Another thing you might underestimate.

To use a DLL, you need a .dll and a .h.
To compile and link source code, you usually need to set up include directories, output directories, install 3rd party libraries, etc. It's a pain, really.



Related Topics



Leave a reply



Submit