static library dependencies - static

I have a static library (.lib file) on Windows platform, I want to know the dependent version of CRT library when the lib is built. I have no source code of the .lib file, any ideas?
thanks in advance,
George

Static libraries don't have those kinds of dependencies. When the library is built it is not linked with the run-time in any way, all it knows about are function declarations in the implementation header files, which don't provide any version information.
However, assuming the library is in MS format, you should be able see what flags the library was built with by opening it in a text editor (make a backup before you do this). You are looking for a line like this:
cl.exe cmd -nologo -MTd -W3 -Gm -GX -ZI -DWIN32 -D_DEBUG (more stuff)
The -MTd flag tells you that the library was compiled with Multi-Threaded Debug support. .

Related

How can I use my C library as others like stdio

I recently made a small library in C, and I wanted to put it together with the standard libraries so I don't have to always copy the files for each new project.
Where do I have to put it so I can import it like the standard libraries?
Compiler : MinGW
OS: Windows
You need to create a library, but you don't necessarily need to put it in the same place as MinGW's standard libraries (in fact I think that's a bad idea).
It is better to put your own library/libraries in specific place and then use the -I compiler flag to tell the compiler where to find the header files (.h, .hpp, .hh) and the -L linker flag to tell the linker where to find the library archives (.a, .dll.a). If you have .dll files you should make sure they are in your PATH environment variable when you run your .exe or make sure the .dll files are copied in the same folder as your .exe.
If you use an IDE (e.g. Code::Blocks or Visual Studio Code) you can set these flags in the global IDE compiler/linker settings so you won't have to add the flags for each new project.
Then when building a project that uses your library you will need to add the -l flag with the library name to your linker flags, but without the lib prefix and without the extension (e.g. to use libmystuff.a/libmystuff.dll.a specify linker flag -lmystuff). The use of the -static flag will tell the linker to use the static library instead of the shared library if both are available.
I have created a minimal example library at https://github.com/brechtsanders/ci-test to illustrate on how to create a library that can be build both as static and shared (DLL) library on Windows, but the same code also compiles on
macOS and Linux.
If you don't use build tools like Make or CMake and want do the steps manually they would look like this for a static library:
gcc -c -o mystuff.o mystuff.c
ar cr libmystuff.a mystuff.c
To distribute the library in binary form you should distribute your header files (.h) and the library archive files (.a).

How to specify static linking for standard libraries in yocto-cmake?

I am new to cmake so, sorry if this question is very basic.
I want to build my project as statically linked with each standard library it uses.
Like, in gcc if we want to link the standard system libraries(libc, libgcc etc) as static, we specify '-static' option at the time of compilation.(Like gcc main.c -static -o main).
How we can achieve the same in cmake?
I have read multiple threads to define a how to define a library, how to build, link(as static & shared). But that is all for a custom library, I need information for standard system libraries.
[Edit]
In my project, I am using yocto at the top and the cmake is been used underneath it. running directly cmake works fine, as the generated executable has no dependencies on any shared library, all the used libraries are linked statically. But compiling from yocto causing the issue. the executable generated from the yocto build shows the dependencies on several standard shared libraries.
How we can specify static linking of standard libraries in yocto cmake?
Thanks in advance.

How can I create and use my own static library in C?

I want to my make own library and have it use the same syntax as the standard C libraries as in
#include<mylib.h>
So that it looks like #include and some of the libraries that are included with C.
Can I make the library static as opposed to linking so that I can compile it in GCC without additional arguments, as if I were using another library like stdio.h or string.h?
This seems simple enough.
Develop the library (create as many source files as you need).
Build the source files into a shared library (.so) using a tool like CMAKE (which i strongly recommend).
Copy that library to your library path (i.e. /usr/lib)
Later on, all you have to do is import your lib: (i) in the source using #include<mylib.h>; (ii) when building (also using CMAKE) or using the flag (-lmylib) in the GCC compiler: gcc -lmylib myfiles.c -o myoutput.
In addition to #include "mylib.h", you need to add -lmylib command line to the compiler (more specifically linker) when using the library. I assume that the your library archive created through ar command is named as libmylib.a.
Usually, we do not write 'manually' build instructions, but we rely on tool that generates build chains. There are quite a lot of them, the most know are probably autotools and cmake (under Linux).
I would suggest you to have a look to cmake examples and/or documentation to get your code built.
There are quite a lot of differences between static and dynamic libs, and you will also need to package somehow your lib if you really want to use it like 'standard' lib (like libxml2, openssl, etc.)
A lot to say about it, but you should first have a look to 'how to build' your lib, and then see how to make it easy to use, IMHO.

How to create a C-library (for Ubuntu) out of header- and source-files?

I am looking for a program to create a C-library (i.e. to link and compile the files into one file) based on .h-files and .c-files that have the following structure (it is a FEC-library: www.openfec.org ). I am using Ubuntu. I want it to do this without manually specifying each files. I tried WAF, but got the error 'ERROR:root: error: No module named cflags'.
Here is (part of the) the structure:
fec
lib_advanced
ldpc_from_file
of_code_profile.h
of_ldpc_ff.h
...
lib_common
linear_binary_codes_utils
binary_matrix
it_decoding
ml_decoding
statistics
of_cb.h
of_debug.h
of_mem.c
of_mem.h
of_openfec_api.c
of_openfec_api.h
of_openfec_profile.h
of_types.h
Thanks!!
You have to use gcc to compile the C-files to objects files.
Then you have to use ar r and then ranlib to pack the objects into one .a library file.
C libraries on *nix systems (including all linux distros) are created with standards tools, this tools being a) a C compiler b) a linker b) the ar utility c) the ranlib utility.
The C compiler 99.9% of the time the GNU C compiler, while the linker ld, and the utilities ar and ranlib are part of the binutils package on gnu systems (99.9% of linux systems).
ar and ranlib are used to created static libraries, putting already compiled object files ( *.o files) in an archive file libsomething.a with ar and indexing the archive with ranlib.
The linker can be called inside the gcc compiler to create dynamic libraries with position independent code, again the already compiled files are archived on a special, this file has the .so extension for shared object.
Static Libraries are used for speed and self-containment, they produce big executables which contain all their dependencies inside the final executable. If a single library of many changes, to update it you'll have to recompiled everything.
Dynamic libraries are compiled and linked separately of the executables, they can be used simultaneously by multiple executables, if one library is updated, you just need to recompile a single library and not every executable which depends on it.
The use of this tools are universal and standard procedure, they can vary by few details from *nix systems to *nix system, but on linux you essentially always use the GCC and Binutils packages. Extra build utilities on the form of make, cmake, autotools, etc exist to help on the process, but the basic tools are always used.
Generally on the most basic level you write a Makefile script which is interpreted by the make utility. And depending on your commands it can make one or both kinds of libraries, install the library and executables, uninstall them, clean up, etc
For more information :
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
http://www.dwheeler.com/program-library/Program-Library-HOWTO/

How do you actually use a C library?

I'm sure this question has been asked many times, but I can't figure this out. Bear with me.
So when you download a library, you get a bunch of .c and .h files, plus a lot of other stuff. Now say you want to write a program using this library.
I copy all the .h files into my project directory. It just doesn't compile.
Great, so then I get the library as a bunch of .dll's, and i copy the dlls into my project directory. Still doesn't compile.
How does this work?
What do you do, like right after creating the folder for your project? What parts of the library package do you copy/paste into the folder? How do you make it so that it can compile? Go through the steps with me please.
Where to put the .h files?
Where to put the .dll files?
How to compile?
Thanks.
(the library I'm trying to get working is libpng, I'm in windows with MinGW, and i'm looking to compile from command-line like usual.)
(from what i gather, you put the .h files in directory A and the .dll files in directory B and you can use -l and -L compiler options to tell the compiler where to find them, is this correct?)
Here's a brief guide to what happens when you compile and build a basic C project:
The first stage compiles all your source files - this takes the source files you've written and translates them into what are called object files. At this stage the compiler needs to know the declaration of all functions you use in your code, even in external libraries, so you need to use #include to include the header files of whatever libraries you use. This also means that you need to tell the compiler the location of those header files. With GCC you can use the -I command line to feed in directories to be searched for header files.
The next stage is to link all the object files together into one executable. At this stage the linker needs to resolve the calls to external libraries. This means you need the library in object form. Most libraries will give you instructions on how to generate this or might supply it ready built. Under Linux the library file is often a .a or .so file, though it might just be a .o. Again you can feed the location of the library's object file to GCC with the -L option.
Thus your command line would look like this:
gcc myProg.c -I/path/to/libpng/include -L/path/to/libpng/lib -lpng -o myProg.exe
(Note that when using the -l command line GCC automatically adds lib to the start of the library, so -lpng causes libpng.a to be linked in.)
Hope that helps.
Doing it under windows (supposing you user Visual Studio)
After unpacking add the library include directories to your projects' settings (Project -> Properties -> C/C++ -> Additional Include Directories)
Do the same thing for the Libraries Directory (Project -> Properties -> Linker -> Additional Library Directories)
Specify the name of the library in your Linker Input: Project -> Properties -> Linker -> Input -> Additional Dependencies
After this hopefully should compile.
I don't recommend adding the directories above to the Global settings in Visual Studio (Tools -> Options -> Project and Solutions) since it will create and environment where something compiles on your computer and does NOT compile on another one.
Now, the hard way, doing it for a Makefile based build system:
Unpack your stuff
Specify the include directory under the -I g++ flag
Specify the Library directory under the -L g++ flag
Specify the libraries to use like: -llibrary name (for example: -lxml2 for libxml2.so)
Specify the static libraries like: library name.a
at the end you should have a command which is ugly and looks like:
g++ -I/work/my_library/include -L/work/my_library/lib -lmylib my_static.a -o appname_exe MYFILE.CPP
(the line above is not really tested just a general idea)
I recommend go, grab a template makefile from somewhere and add in all your stuff.
You must link against a .lib or something equivalent i.e. add the ".lib" to the libraries read by the linker. At least that's how it works under Linux... haven't done Windows so a long while.
The ".lib" contains symbols to data/functions inside the .dll shared library.
It depends on the library. For examples, some libraries contain precompiled binaries (e.g. dlls) and others you need to compile them yourself. You'd better see the library's documentation.
Basically, to compile you should:
(1) have the library's include (.h) file location in the compiler's include path,
(2) have the library stubs (.lib) location in the linker's library path, and have the linker reference the relevant library file.
In order to run the program you need to have the shared libraries (dlls) where the loader can see them, for example in your system32 directory.
There are two kinds of libraries: static and dynamic (or shared.)
Static libraries come in an object format and you link them directly into your application.
Shared or dynamic libraries reside in a seperate file (.dll or .so) which must be present at the time your application is run. They also come with object files you must link against your application, but in this case they contain nothing more than stubs that find and call the runtime binary (the .dll or the .so).
In either case, you must have some header files containing the signatures (declarations) of the library functions, else your code won't compile.
Some 'libraries' are header-only and you need do nothing more than include them. Some consist of header and source files. In that case you should compile and link the sources against your application just as you would do with a source file you wrote.
When you compile, assuming you have the libs and the headers in the same folder as the sources you are compiling, you need to add to your compile line -L . -I . -lpng. -L tells the linker where to look for the library, -I tells the compiler where to look for the headers and -lpng tells the linker to link with the png library.
[Edit]
Normal projects would have some sort of hierarchy where the headers are in an /include folder and the 3rd party libs are in a /libs folder. In this case, you'd put -I ./include and -L ./libs instead of -I . and -L.
[Edit2] Most projects make use of makefile in order to compile from the command line. You can only compile manually for a small number of files, it gets quite hectic after that
Also,
you may want to look over Dynamic Loading support in various languages and on various
platforms.
This support is very handy in cases when you want to use a library optionally and you don't want your program to fail in case that library is not available.

Resources