Statically linked libraries not running code inside to setup static variables - c++

In a c++ project I am working on, I have a simple c++ file that needs to run some code at the beginning of the program execution. This file is linked into a static library, which is then linked into the main program.
I have similar code in other files running fine, that looks something like:
bool ____nonexistent_value = executeAction();
However, it does not work inside this file unless I make use of a function implemented in this file. It does work if the library is compiled as a shared library. I'd prefer to link this statically as the library is only a convenience as the file is in a different directory.
Update (Solution):
For now creating shared instead of static libraries makes everything work. Later I will look into getting everything linking with static libraries. Thanks for everyone's help!

If no symbol is referenced in that particular file then the file will not be included by the linker. You have two options:
Remove the file from library and include it (object or source file) directly in the command line for compilation/linking. Then the file should be included in executable.
Have a symbol in a file which you reference from from other files (for example the one with main() definition), this should "pull" the file during linking.

I'm not sure if there's a way to guarantee such static allocation in a static library, but you can always make it explicit. Provide an init function for your library that will be called from main to setup everything you need. This way you don't have to worry about linkers omitting code that's apparently unused, etc.

There's no guaranteed order for static initialization. You want to be very careful with this!

Related

C++ linker order issue - Linking my own main with a subset of object files in a large C++ project

I have a large C++ project with around 250 cpp files.
I didn't write this code, I'm just trying to write a test for fuzzing(testing) purpose. Therefore:
I wrote my own main cpp file, called wrapper.cpp, containing the int main()
I included in this file some header files needed
I compiled after removing the inital main from the Makefile and adding my wrapper.cpp
It works, it produces a functionnal executable. However, the binary size is quiet important. I'm pretty sure I can reduce the size as a lot of object files are linked but not used. Therefore, I built all the object files and now I'm thinking about how to link the needed ones with the executables. But after many tries, it seems impossible:
The executable is linked against the object files, some static libraries and some dynamic lib
The order matters for the static libs (interdependencies between them and some *.o files)
There a several definitions for some symbols and this is allowed by the zmuldefs linker option
Thus, I first tried to create a bug static libs with all the object files and to link the executable against it assuming only the right .o files would be picked by the linker. I didn't think about the order problem ... Some of these object files need symbols contained in other static lib and vice versa (interdependencies). No matter where I place the static lib I created, there will be issues. So I can't go this way, it is too complex.
Then, I tried to add the -Wl,--start-group/-Wl,--end-group linker option. It allows my to compile but the binary will segfault. I guess this is because of the zmuldefs option that allows multiple definitons, so the order is really important.
So I was wondering if there was a way to this, maybe an obvious way that I'm missing ? Cause it seems to be a pretty common use case to me(imagine if you want to test a single function), but I cannot cannot find anything online.
Thank you in advance for your precious help

How to compile a static library with Codelite 11.0.0?

I would like to compile a static library out of all the functions I have written for a C++ project. I am using CodeLite 11.0.0 on Ubuntu 16.04, configured to use GCC as compiler.
I have followed the instructions in CodeLite's tutorial, according to which this should be possible, and changed the project type from Executable to Static Library.
After running the project (CTRL+F5 command), I expected to find a .a file in the /Debug folder, either along with, or in place of the executable file. All I could find, though, was the executable and a number of .o and .o.d files. The same I was finding when the project was set to Executable.
I tried to close and reopen CodeLite, but it did not help. I can't find any official/unofficial example of how to build a static library with CodeLite.
Does anyone know how to set-up CodeLite to produce a .a static library file?
As you've probably discovered, CodeLite allows you to change the type of a
project in the drop-down menu from Settings -> General -> Project type.
Doing so, however, does not change the name of the project target. So, if
you started off your project as an executable myprog - from which, say, the
Debug build generated ./Debug/myprog under the project folder - then
you change the project type to static library and rebuild it, the Debug
build will still generate ./Debug/myprog, but that file will now in fact
be a static library, lacking the customary lib-prefix and .a extension.
To give the output file a conventional static library name -
libmyprog.a - you need to go back into Settings -> General and
change Output File from:
$(IntermediateDirectory)/$(ProjectName)
to:
$(IntermediateDirectory)/lib$(ProjectName).a
Then rebuild the project and it will output a target that is a static
library and looks like one.
Of course, you must make the same changes to the project settings in both
the Debug and Release configurations if you want them both to produce
targets with the same file type and file name.
However...
If this way of converting a program project to a static library project does not
seem very slick, that could be because it is a conversion of very little use.
The static library produced after the conversion will contain exactly the same object
files that the program was built from, including the object file that defines
the main function of the original program. Let's suppose that object file
is main.o, and that it defines 0 or more other functions that the linker can see.
Any other program, newprog, that is linked with the static library must provide
its own main function in a different object file, so in any such linkage one of
two things must happen:-
The linkage of newprog does not need any function defined in libmyprog.a(main.o),
so libmyprog.a(main.o) is not linked and might as well not exist.
The linkage of newprog does need some function, foo, defined in libmyprog.a(main.o),
so libmyprog.a(main.o) is linked; then as well as the definition of foo, the
program links duplicate definitions of main - its own definition plus the
one in libmyprog.a(main.o). Duplicate definitions are an error, so the linkage fails.
Putting a definition of some program's main function into a member of a static
library is pointless, because if that member is ever needed in the linkage of another
program then its linkage will fail.
So converting your program project to a static library project calls for some
refactoring prior to the conversion:-
If any function that you want in the static library is defined in the same source
file as main, then you need to take it out of that source file and define it
is a different one.
After that, remove the source file that defines main from the project.
Lastly, convert and rebuild the project.
You have to do that refactoring to extract from your original program source code
a bunch of source files that are suitable for building into a static library.
Assuming you've done that, the straightforward way to create a static library with
CodeLite is to create a project for that purpose and in the New Project Wizard
choose Library -> Static Library as the project type instead of some kind
of executable.
Then just add either new or existing source files to the static library project
until it contains definitions of all the functions you want the library to
provide. Build, test, debug, edit... until done.

utilizing a static library to create an import library

I am interested in using my static lib to create a dll (implicitly linking). which means I need to (in vs2008)
create a dll project that should generate the following:
header file (which have export function declarations. These are simple wrappers to actual functions in the static lib using __declspec(dllexport) which are in the .cpp )
import lib which will be made as a result of creating the dll
the actual dll which is created.
I have made a test program that will utilize the above dll(including the import lib/header files) to test it.
in this I have included all the three items. now the exe compiles/links without issue.
however in the main.cpp when i call the exported functions (with the associated __declspec(dllimport) call it never seems to execute. I am uncertain why this is?
Its almost like the even though the exe can see the exported function in in the dll...the dll cannot call on the code that is in the static lib?
i just cannot answer why my exe can't see the code in the static lib? do i need an archiver/librarian for vs2008 to include all those obj files as part of the import lib?
I am at a loss and am not sure how to test this?
other than just making my static lib directly into a dll. I wanted to try this method. I know i am missing something...i have read all over the place and i am just stuck. There were some threads here that had some people posting something similar but i can't seem to get it. please be as detailed as possible as I am new to this. thanks again.
update 1:
ok so currently i added the extern line to the function prototype and now it sees the exported function from the dll. however, now the only issue left is that:
i can't invoke the function that this exported function (aka wrapper) is trying to call. which happens to be in the static library. how should my exe get visibility to that static library function. I know it can be done because I think there was one other person on this board who was able to make this work.
update 2: my setup is exactly like this questioner...
How to force inclusion of an object file in a static library when linking into executable?
but i am not using explicit linking. i am using implicit linking. my real issue is how to call a static lib function in my dll wrapper which is exported to the exe?
If the app and DLLs are MFC app/dlls, then make sure that the application and all dlls are either "Debug" versions or "release" versions and not a mix.

why do I need to link a lib file to my project?

I am creating a project that uses a DLL. To build my project, I need to include a header file, and a lib file. Why do I need to include the respective lib file? shouldn't the header file declare all the needed information and then at runtime load any needed library/dll?
Thanks
In many other languages, the equivalent of the header file is all you need. But the common C linkers on Windows have always used import libraries, C++ linkers followed suit, and it's probably too late to change.
As a thought experiment, one could imagine syntax like this:
__declspec(dllimport, "kernel32") void __stdcall Sleep(DWORD dwMilliseconds);
Armed with that information the compiler/linker tool chain could do the rest.
As a further example, in Delphi one would import this function, using implicit linking, like so:
procedure Sleep(dwMilliseconds: DWORD); stdcall; external 'kernel32';
which just goes to show that import libraries are not, a priori, essential for linking to DLLs.
That is a so-called "import library" that contains minimal wiring that will later (at load time) ask the operating system to load the DLL.
DLLs are a Windows (MS/Intel) thing. The (generated) lib contains the code needed to call into the DLL and it exposes 'normal' functions to the rest of your App.
No, the header file isn't necassarily enough. The header file can contain just the declarations of the functions and classes and other things you need, not their implementations.
There is a world of difference between this code:
void Multiply(int x, int y);
and this code:
void Multiply(int x, int y)
{
return x * y;
}
The first is a declaration, and the second is a definition or implementation. Usually the first example is put in header files, and the second one is put in .CPP files (If you are creating libraries). If you included a header with the first and didn't link in anything, how is your application supposed to know how to implement Multiply?
Now if you are using header files that contain code that is ALL inlined, then you do not need to link anything. But if even one method is NOT inlined, but has its implementation in a .CPP file that is compiled to a .lib file, than you need to link in the .lib file.
[EDIT]
With your use of Import Libraries, you are telling the linker to NOT include the implementation details of the imported code into your binary. Instead the OS will then load the import DLL at run-time into your process. This will make your application smaller, but you have to ship another DLL with it. If the implementation of the library changes, you can just reship another DLL to your customers, and not have to reship the entire application.
There is another option where you can just link in a library and you don't need to ship another DLL. That option is where the Linker will include the implementation into your application, making it bigger in size. If you have to change the implementation details in the imported library, then you have to recompile and relink your entire application, and reship the entire thing to your customers.
There are two relevant phases in the building process here:
compilation: from the source code to an object file. During the compilation, the compiler needs to know what external things are available, for that one needs a declaration. Declarations designed to be used in several compilation units are grouped in header. So you need the headers for the library.
linking: For static libraries, you need the compiled version of the library. For dynamic libraries, in Unix you need the library, in windows, you need the "import library".
You could think that a library could also embed the declarations or the header could include the library which needs to be linked. The first is often done in other languages. The second is sometimes available through pragmas in C and C++, but there is no standard way to do this and would be in conflict with common usage (such as choosing a library among several which provide code variant for the same declarations, for instance debug/release single thread/multithreads). And neither choice correspond well with the simple compilation model of C and C++ which has its roots in the 60's.
The header file is consumed by the compiler. It contains all the forward declarations of functions, classes and global variables that will be used. It may also contain some inline function definitions as well.
These are used by the compiler to give it the bare minimum information that it needs to compile your code. It will not contain the implementation details.
However you still need to link in all the function, and variable definitions that you have told the compiler about. Failure to do so will result in a linker error. Often this is contains in other object files which may be joined into a single static library.
In the case of DLLs (or .so files), we still need to tell the linker where in the DLL or shared object the missing symbols are. On windows, this information is contained in a .lib file. This will generate the code to load and link the code at runtime.
On unix the the dll and lib files are combined into a single .so file which you must link against to about linker errors.
You can still use a dll without a .lib file but you will then have to load and link in all the symbols manually using operating system APIs.
from 1000 ft, the lib contains the list of the functions that dll exports and addresses that are needed for the call.

LNK4221 and LNK4006 Warnings

I am making a static library of my own. I have taken my code which works and now put it into a static library for another program to use. In my library I am using another static library which I don't want the people who will be using my API to know. Since, I want to hide that information from them I can't tell them to install the other static library.
Anyway, I used the command line Lib.exe to extract and create a smaller lib file of just the obj's I used. However, I get a bunch of LNK4006 :second definition ignored linker warnings for each obj I use followed by LNK4221 no public symbols found;archive member will be inaccessible.
I am doing this work in vs2008 and I am not sure what I am doing wrong.
I am using the #pragma comment line in my .cpp file
I have also modified the librarian to add my smaller .lib along with its location.
my code simply makes calls to a couple functions which it should be able to get from those Obj file in the smaller lib.
All my functions are implemented in .cpp file and my header just have the includes of the third party header files and come standard c++ header files. nothing fancy. I have actually no function definitions in there atm. I was going to put the API definition in there and implement that in the .cpp for this static lib that i was going to make. However, I just wanted to build my code before I added more to it.
I did read http://support.microsoft.com/default.aspx?scid=kb;EN-US;815773 but it did not provide a solution.
Even if you extract all objects from the other library and put them in your own library, your users will still be able to see what's in your library and thus see all the object names. In many cases the names of the objects will reveal what's actually the other library you are using.
Instead of distributing your library as a static library, consider distributing it as a DLL. In the DLL you can easily hide all the underlying things and only make public what you want to make public.