How do I merge zlib1.dll into my executable in C? - c

My executable needs zlib1.dll to run,
and I need to keep them together now and then.
How can I merge it into the executable to save the trouble?
I'm using cmake to build the executable.
UPDATE
zlib1.dll is not directly included by my programe,but required by libpng14-14.dll(one dll of the gtk bundle)

It sounds like you want to link statically so that your program does not require the presence of zlib1.dll in order to run. But zlib1.dll is a dynamic link library (that's what DLL stands for!), so you can't link it statically. The first thing you need to do is find a static version of this library. On windows, it will normally end with the .lib extension.
I'm not familiar with cmake, so I'll let someone else answer the part of the question about how to make cmake use the static library, once you have both.

Sorry there is no way to mix it. Either you must compile and link statically or dynamically. I tried it - it does not work.
So if libpng.dll needs a zlib.dll you can't turn zlib into a static library. You have to also compile libpng as a static library.
I've done this a few times, the makefiles from PNG, ZLIB, (and also the JPEG, TIFF image format libraries) are pretty good. If you need more then 30min to figure out what to do, you should look at it as a good training on your C makefile skills.

Related

Resources Path in C Libraries

I am writing a little C library that has some resources (namely, openCL code that I want to compile in runtime, but I'd expect this problem to be similar for images or arbitrary text files). I need to load these resources at run time.
If the resources were shipped with my project, I'd be able to use argv[0]. However, in my current scenario, my resources should be shipped with my library. I know, ahead of time, the location of my resources file relative to my .so file.
How do I get the path of the resources from my source code?
The way it's done usually, you have a INSTALL_PREFIX macro of some kind defined in your Makefile/whatever build system you use which is set by people before compiling your library. Then the Makefile passes it on to the compiler as a compiler flag so you can use it in code (in essence you know ahead of time the full path to the resources you're going to load without having to hardcode them).
If you're going to package your library eventually you'll probably want to use something like autoconf or cmake (have a look at how other projects do it). But for something simple like that you could get away with just a Makefile:
Makefile:
INSTALL_PREFIX=/usr
CFLAGS=-DINSTALL_PREFIX=$(INSTALL_PREFIX)
foo.c:
FILE *f = fopen(INSTALL_PREFIX "/share/mylib/data.txt", "r");

Why gcc does not support linking dynamical library into static binary

The background is following: there is 3'rd party provider that provides us with a libveryfancylib.so, in 32b. Softaware that uses the library has quite a load of other linux library dependencies (like QT) also, but they are open source, so no problem for statical linking. The target platform is 64b and running Debian 7.
We can ship the program with binary + dynamical libraries, no problem, but i would rather see single static binary with no dependencies.
So my question is: why i cannot link the dynamical library into static binary? I mean what bit of information is there missing, or is it just feature that is rarely needed -> not implemented.
We can ship the program with binary + dynamical libraries, no problem, but i would rather see single static binary with no dependencies.
What is the problem you are trying to solve?
You can follow the model most commercial applications on Linux do: put your executable, shared libraries and other resources in one directory (possibly with subdirectories). When linking your executable against those shared libraries pass -Wl,-rpath,'$ORIGIN' (in make use -Wl,-rpath,'$$ORIGIN') to the linker, so that when starting your application the runtime linker looks for required shared libraries in the same directory where executable is.
Then archive that directory and give it to your users.
There are programs for MS Windows that can do so, eg DLL to Lib and DLL to Static Lib.
In the open source world, there isn't really much of an incentive to develop such a tool as you can always recompile from source (but of course it's possible that someone somewhere did it anyway).
It's because dynamic libraries and static libraries are two different things. A static library is just an archive of object files (much like a zip archive). A dynamic library is more like an executable program.
So you can't really link anything into a static library, you can only add more object files.

How compiled c programs execute when my system is missing GTK header files?

I am trying to compile a simple ANSI C program which requires GTK header files.
I know how to link the source code with gtk.h when compiling with GCC.
My question is how come applications such as gedit (GTK lib) is running on my system considering that GTK header files are missing? Presumably Gedit was compiled on a system which did have the GTK library. But why does Gedit not require header files on my system during execution?
As a Java programmer to compile a program the class files always have to be packaged with the main executable. Also I would need the JVM installed on the target system.
Thank you for your helpful responses.
But why does Gedit not require header files on my system during
execution?
Header files are only needed in the preprocessing phase. Once the preprocessor is done with them the compiler never even sees them. Obviously, the target system doesn't need them either for execution (the same way .c files aren't needed).
You're probably thinking of libraries, and you're right. Indeed: if a program is dynamically linked and the target environment doesn't have the necessary libraries, in the right places, with the right versions it won't run. One way to ensure it will run on most systems is to statically link stuff, but this will also bloat your executable and make poorer use of memory.
Also I would need the JVM installed on the target system.
Well, for C nothing like that is needed since once you compile it you get native code. Native code is very different from the intermediate stuff (bytecode) you get from java. There's no need for anything like an interpreter: you just feed it your binary stuff to the CPU and it does its thing.
Everything the executable needs from the header files is built into the executable when it's compiled. In C, header files are just included literally in the source file when referenced and then compiled.

CMake: how to produce binaries "as static as possible"

I would like to have control over the type of the libraries that get found/linked with my binaries in CMake. The final goal is, to generate binaries "as static as possible" that is to link statically against every library that does have a static version available. This is important as would enable portability of binaries across different systems during testing.
ATM this seems to be quite difficult to achieve as the FindXXX.cmake packages, or more precisely the find_library command always picks up the dynamic libraries whenever both static and dynamic are available.
Tips on how to implement this functionality - preferably in an elegant way - would be very welcome!
I did some investigation and although I could not find a satisfying solution to the problem, I did find a half-solution.
The problem of static builds boils down to 3 things:
Building and linking the project's internal libraries.
Pretty simple, one just has to flip the BUILD_SHARED_LIBS switch OFF.
Finding static versions of external libraries.
The only way seems to be setting CMAKE_FIND_LIBRARY_SUFFIXES to contain the desired file suffix(es) (it's a priority list).
This solution is quite a "dirty" one and very much against CMake's cross-platform aspirations. IMHO this should be handled behind the scenes by CMake, but as far as I understood, because of the ".lib" confusion on Windows, it seems that the CMake developers prefer the current implementation.
Linking statically against system libraries.
CMake provides an option LINK_SEARCH_END_STATIC which based on the documentation: "End a link line such that static system libraries are used."
One would think, this is it, the problem is solved. However, it seems that the current implementation is not up to the task. If the option is turned on, CMake generates a implicit linker call with an argument list that ends with the options passed to the linker, including -Wl,-Bstatic. However, this is not enough. Only instructing the linker to link statically results in an error, in my case: /usr/bin/ld: cannot find -lgcc_s. What is missing is telling gcc as well that we need static linking through the -static argument which is not generated to the linker call by CMake. I think this is a bug, but I haven't managed to get a confirmation from the developers yet.
Finally, I think all this could and should be done by CMake behind the scenes, after all it's not so complicated, except that it's impossible on Windows - if that count as complicated...
A well made FindXXX.cmake file will include something for this. If you look in FindBoost.cmake, you can set the Boost_USE_STATIC_LIBS variable to control whether or not it finds static or shared libraries. Unfortunately, a majority of packages do not implement this.
If a module uses the find_library command (most do), then you can change CMake's behavior through CMAKE_FIND_LIBRARY_SUFFIXES variable. Here's the relevant CMake code from FindBoost.cmake to use this:
IF(WIN32)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ELSE(WIN32)
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
ENDIF(WIN32)
You can either put this before calling find_package, or, better, you can modify the .cmake files themselves and contribute back to the community.
For the .cmake files I use in my project, I keep all of them in their own folder within source control. I did this because I found that having the correct .cmake file for some libraries was inconsistent and keeping my own copy allowed me to make modifications and ensure that everyone who checked out the code would have the same build system files.

Compiled languages basics

please, could someone explain to me a few basic things about working with languages like C? Especially on Windows?
If I want to use some other library, what do I need from the library? Header files .h and ..?
What is the difference between .dll and .dll.a.? .dll and .lib? .dll and .exe? What is .def?
Does it matter how was the library compiled? I mean, is it possible to use, on Windows, a C++ library compiled by VC from within my C code compiled by MinGW?
To use another library, what is preferred way? LoadLibrary() or #include <>?
There are some libraries which only provide the source code or .dll - how to use such libraries? Do I have to recompile them every time I rebuild my project?
How do I create one big .exe? Is this called "static linking"?
How to include some random file into .exe? Say a program icon or start-up song?
How do I split my huge .c into smaller ones? Do I need to create for every part a header file which then I include in the part with WinMain() or main()?
If there is a library which needs another library, is it possible to combine these two into one file? Say, python26.dll needs msvcr90.dll and Microsoft.VC90.CRT.manifest
What happens if I don't free previously allocated memory? Is this going to be cleaned up if the program (process) dies?
Well, so many question... Thanks for every info!
1: If I want to use some other library, what do I need from the library? Header files .h and ..?
... and, usually a *.lib file which you pass as an argument to your linker.
2: What is the difference between .dll and .dll.a.? .dll and .lib? .dll and .exe? What is .def?
This might be useful: Static libraries, dynamic libraries, DLLs, entry points, headers … how to get out of this alive?
3: Does it matter how was the library compiled? I mean, is it possible to use, on Windows, a C++ library compiled by VC from within my C code compiled by MinGW?
Yes, it matters. For interop between compilers, the normal way is to use a C-style (not C++-style) API, with well-defined parameter-passing conventions (e.g. __stdcall), or to use 'COM' interfaces.
4: To use another library, what is preferred way? LoadLibrary() or #include <>?
#include is for the compiler (e.g. so that it can compile calls to the library); and LoadLibrary (or, using a *.lib file) is for the run-time linker/loader (so that it can substitute the actual address of those library methods into your code): i.e. you need both.
5: There are some libraries which only provide the source code or .dll - how to use such libraries? Do I have to recompile them every time I rebuild my project?
If it's only source then you can compile that source (once) into a library, and then (when you build your project) link to that library (without recompiling the library).
6: How do I create one big .exe? Is this called "static linking"?
Yes, compile everything and pass it all to the linker.
7: How to include some random file into .exe? Say a program icon or start-up song?
Define that in a Windows-specific 'resource file', which is compiled by the 'resource compiler'.
8: How do I split my huge .c into smaller ones? Do I need to create for every part a header file which then I include in the part with WinMain() or main()?
Yes.
9: If there is a library which needs another library, is it possible to combine these two into one file? Say, python26.dll needs msvcr90.dll and Microsoft.VC90.CRT.manifest
I don't understand your question/example.
10: What happens if I don't free previously allocated memory? Is this going to be cleaned up if the program (process) dies?
Yes.
If I want to use some other library, what do I need from the library? Header files .h and ..?
You need header .h or .hpp for C,C++ although some languages don't require header files. You'll also need .a, .so, .dll, .lib, .jar etc files. These files contain the machine code that you linker can link into your program. Goes without saying that the format of library is must be understood by you linker.
What is the difference between .dll and .dll.a.? .dll and .lib? .dll and .exe? What is .def?
dll and .a are library files, that contain code components that you can link into your own program. a .exe is your final program into which .a or .dll has already been linked.
Does it matter how was the library compiled? I mean, is it possible to use, on Windows, a C++ library compiled by VC from within my C code compiled by MinGW?
Yes, it is important that the library that you are using is compatible with your platform. Typically Unix libraries will not run on windows and vice versa, if you are using JAVA you are better off since a .jar files will usually work on any platform with JAVA enabled (though versions matter )
To use another library, what is preferred way? LoadLibrary() or #include <>?
include is not a way to use a library its just a preprocessor directive telling you preprocessor to include a external source file in your current source file. This file can be any file not just .h although usually it would be .h or a .hpp
You'll be better off my leaving the decision about when to load a library to you runtime environment or your linker, unless you know for sure that loading a library at a particular point of time is going to add some value to your code. The performance cost and exact method of doing this is platform dependent.
There are some libraries which only provide the source code or .dll - how to use such libraries? Do I have to recompile them every time I rebuild my project?
If you have source code you'll need to recompile it every time you make a change to it.
however if you have not changed the source of library in anyway there is no need to recompile it. The build tool like Make are intelligent enough to take this decision for you.
How do I create one big .exe? Is this called "static linking"?
Creating a static .exe is dependent on the build tool you are using.
with gcc this would usually mean that you have to you -static option
gcc -static -o my.exe my.c
How to include some random file into .exe? Say a program icon or start-up song?
Nothing in programming is random. If it were we would be in trouble. Again the way you can play a song or display an icon is dependent on the platform you are using on some platforms it may even be impossible to do so.
How do I split my huge .c into smaller ones? Do I need to create for every part a header file which then I include in the part with WinMain() or main()?
You'll need a header file with all your function prototypes and you can split you program into several .c files that contain one or more functions. You main files will include the header file. All source files need to be compiled individually and then linked into one executable. Typically you'll get a .o for every .c and then you link all the .o together to get a .exe
If there is a library which needs another library, is it possible to combine these two into one file? Say, python26.dll needs msvcr90.dll and Microsoft.VC90.CRT.manifest
Yes one library may require another library however its not advisable to package different libraries together, you may be violating the IPR and also for the fact that each library is usually a well define unit with a specific purpose and combining them into one usually doesn't make much sense.
What happens if I don't free previously allocated memory? Is this going to be cleaned up if the program (process) dies?
Again depends on the platform, usually on most OS the memory will be recovered after the program dies but on certain platforms like an embedded system it may be permanently lost.
It always a good idea to clean up the resources your program has used.
In all seriousness, the place to go to learn how to run your local environment is the documentation for your local environment. After all we on not even know exactly what your environment is, much less have it in front of us.
But here are some answers:
1. You need the headers, and a linkable object of some kind. Or you need the source so that you can build these.
3. It matters that the library is in a format that your linker understands. In c++ and perhaps other languages, it also needs to understand the name mangling that was used.
6. Forcing all the library code to be included in the executable is, indeed, called "static linking".
7. There is at least one StackOverflow question on "resource compilers".

Resources