VC: How to split big .lib into small .lib files - c

Environment: VC, Windows.
I have a big .lib file, aaa.lib, created by third party. I have no source code. I need to build myselves static library bbb.lib, which use few functions from aaa.lib. Because of some business issue, I have to hide aaa.lib to my customer. So I use this command to 'merge' aaa.lib into bbb.lib.
LIB /OUT:bbb.lib mycode.lib aaa.lib
It works, except bbb.lib is too big. How could I specify part of aaa.lib when I do the 'merge'? Thanks. I know there is another post about .lib split, but it's not for windows.
I tried these commands to extract a function, but don't work. Take WSAStartup() in ws2_32.lib as example:
LIB ws2_32.lib /extract:__imp__WSAStartup#8
LINK : warning LNK4014: cannot find member object _imp_WSAStartup#8
LIB ws2_32.lib /extract:WSAStartup
LINK : warning LNK4014: cannot find member object WSAStartup

If you use really FEW functions from particular objects you can extract object files with
LIB library /EXTRACT:member /OUT:objectfile
Look here for details.
For list of all objects in the library you can use:
LIB library /LIST

Related

How to add .h and .o files to gcc

I'm trying to figure out how to add header and object files to the standard library so that I can use my custom files as easy as the standard library.
Currently I have to type the path to the header file in the .c file and then link the object file path when compiling.
I would like to just be able to add:
#include <mystdlib.h>
and not worry about linking the object file like I do when I reference the stdio.h header file.
I have searched around, but I fear I'm not using the proper terminology as I don't seem to find the results I need. Am I the first to want to do this, or it is just impossible, and therefore people don't even try?
gcc uses environment variables C_INCLUDE_PATH and LIBRARY_PATH to look for header and library files. Setting them somewhere (eg., your bash_profile) should achieve what you describe:
export C_INCLUDE_PATH="$HOME/include"
export LIBRARY_PATH="$HOME/lib"
Alternatively, the -I and -L flags add directories to the list of directories to be searched for header files and library files, respectively.
edit: As noted by #ChrisStratton below, the library name or object file needs to be explicitly specified. AFAIK, there is no way to make gcc always link against a library (like with libc).
sources:
https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html

Using DLLs in C

This seems like a noob question, but all my searches return stuff about C++ or C# so I'm going to ask it here.
I have a DLL, SDL.dll, in the directory with my .c file. I want to import it to use.
using is not supported, #import doesn't work.
No directive in the source will help you, you can either
link to the DLL, use a so-called lib file for this. (This is a statically dynamic linking)
use LoadLibrary/FreeLibrary and GetProcAddress to map the addresses of functions to function pointers (true dynamic linking)
In the first case you also need an appropriate header file which matches the platform and version of the DLL used.
The second solution will work if you drop-in a newer version of the DLL as long as the prototypes of the functions used match.
This assumes you are under Windows, which is probably the case if you have a *.dll and not an *.so (shared object) file. (For Linux systems, you can include dlfcn.h and use dlopen/dlclose/dlsym instead of LoadLibrary/FreeLibrary/GetProcAddress with a slightly different syntax, check the doc)
this is quite possible assuming your DLL is in the correct form (the same standards as Windows API DLLs for example)
you need to declare you functions - perhaps in a header file, like this:
typedef void (CALLBACK *functionnameptr)(char *, int),
Then you use LoadLibrary to load the DLL, and provide a Handle to it:
handle = LoadLibrary("SDL.DLL");
Then you use GetProcAddress(handle,"real function name in DLL")
like this:
functionnameptr lptrfunction;
lptrfunction = GetProcAddress(handle,"real function name in DLL");
Now you can use the lptrfunction as you would normally use a function in C
Assuming you're using Visual Studio.
1.) Download http://www.libsdl.org/release/SDL-1.2.15.zip
2.) unzip and install to for example C:\SDL-1.2.15
3.) In Visual Studio open the properties of the project goto C++ general and add C:\SDL-1.2.15\include to "Additional include directories".
4.) Goto the "Linker" tab and add C:\SDL-1.2.15\lib\x86 to "Additional library directories".
5.) Now go to "Input" under the Linker tab and add SDL.lib; SDLmain.lib to "Additional dependencies"
6.) Go to the "Build Events" tab and "Post build event" and add copy /y C:\SDL-1.2.15\lib\x86\SDL.dll "$(OutDir)
That should do get your SDL working for Visual Studio in 32bit
On Linux if SDL is already installed just type "g++ -02 -o foo foo.cpp -lSDL"

How to find out functions missing from a library, but which are present in the exposed header file released along with the library?

We have a legacy library implementation and associated exposed header files. Recently we found that, some of the functions in the exposed header file, don't have corresponding definitions in the library implementation.
We want to check if there could be some more such functions. Is there any easier way of doing this rather than sifting through each and every API present in header and then checking if there is a definition for it?
You can generate C source from the header (Perl is a way to go!) that calls all the functions and try to compile it. Linker will complain about missing functions.
Try to create the ABI dump file by the abi-compliance-checker tool:
abi-compliance-checker -lib NAME -dump DESC.xml
DESC.xml file is the following:
<version>
1.0
</version>
<headers>
/path(s)/to/headers
</headers>
<libs>
/path(s)/to/libraries
</libs>
The resulting ABI dump file will contain the information you need about symbols declared in header files (SymbolInfo) and symbols exported by shared libraries (Symbols).
You can also generate ABI dump in the xml format by adding --xml option.
If this is C, you can do something like:
printf("", /* insert all functions here */);
That should pass them all as function pointers to printf. The ones that do not exist should show up as linker errors.
(In C++, you would have to list overloads explicitly, which makes it a bit more difficult.)
I'd be inclined to use ctags to generate a list of identifiers from the header file then use ar, emfar or elfdump in Unix or lib.exe or dumpbin.exe in Windows (see discussion here) to dump a list of identifiers from the library and then sort and diff the two lists.

How to resolve conflicting linker dependencies?

If I have two libraries, A.lib and B.lib, both of which export foo and bar, how do I tell the linker to use the symbol foo from A.lib and the symbol bar from B.lib?
You cannot. For your example you can have definitions from foo.lib or bar.lib but not both (especially if you cannot recompile the libraries and set symbol visibility so that only the symbols you want are exported). The order you link them against your application will depend on which library's definitions are used (you'll have to use the scientific method, I think the first one linked wins). Niklas Hansson's answer is a great way to do this dynamically but it seems you don't want to modify the original application, either, to dynamically pick/choose what symbols to take out of the libraries.
If you really wanted to you could mangle the symbol tables with a hex editor so that the symbols you don't want exported have different names (hacky, but it would work). I know on Linux there is a tool called objcopy that would let you do this (not sure about Windows).
You can use LIB.EXE /EXTRACT ... to extract only the object files you want to use, and link those files into your own application.
Or you may use LIB to create one new library containing the elements you need:
First, use /REMOVE on A.LIB to remove bar.obj:
LIB.EXE /OUT:ANOBAR.LIB /REMOVE:bar.obj A.LIB
Then combine A.LIB and B.LIB, and make sure to use ANOBAR.LIB as the last on the command line to ensure its foo.obj is used instead of B.LIB's:
LIB.EXE /OUT:COMBINED.LIB B.LIB ANOBAR.LIB
Details are found here: Managing a library, especially the paragraph:
You can use LIB [...] To replace a library member with a new object, specify the library containing the member object to be replaced and the file name for the new object (or the library that contains it). When an object that has the same name exists in more than one input file, LIB puts the last object specified in the LIB command into the output library. When you replace a library member, be sure to specify the new object or library after the library that contains the old object.
I didn't test the command lines given, but I've used similar ones extensively in the past.
If you are using dynamic libraries, you could use dynamic loading and pick foo from A and bar from B when loading.

How do I locate a C library header file from a Makefile.PL?

How can I locate a C library header file from a Makefile.PL?
There is ExtUtils::Liblist to find libraries, but I can't see the equivalent for header files.
Devel::CheckLib is what most authors seem to be use for that. It checks both for the existance of libraries as well as header files, as those libraries are probably useless without them.
Why not write a small lib to do this (and let it live in inc/lib/FindHeaders.pm or some such under the top level of your package dir). Just use Config (see incpath) along with File::Find and glob and you should be able to have a small library which can walk your default include path and map a hash of header files on your system, returning it to a call from Makefile.PL. It would be trivial to extend this to include non-standard include paths as well with a constructor argument to your lib. Easy peasy.

Resources