Linker doesn't use a default runtime library when linking together libraries only (no objects) - static-libraries

I want the users to be able to re-link my Qt-using application to their own build of Qt, without being forced to rebuild all of the sources. This could be used for LGPL compliance, for example. To do this, I need to provide object files for all of my sources. To make it easy, using qmake, I've partitioned the project internally into:
A static library project that contains objects for all of the source files, including the file that has int main(int, char**).
An application project that links the static library above with Qt. Qt may be either a static library or dynamic. There are no source files for this project.
I then distribute the static library (.lib) and the application project file so that anyone can relink the application with their own version of Qt, in whichever fashion they prefer (either statically linked Qt or dynamically linked Qt), as long as they have the necessary version of MSVC.
I'm doing the build under both MSVC 2008 (Qt 4) and 2012 (Qt 5). The makefiles are generated by qmake.
The problem is that the linking fails when building the application project.
LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup
As soon as I add a dummy source file dummy.cpp to the application project, the linking succeeds. Is there a way of avoiding this workaround?
//dummy.cpp (this is the entire source)
int dummy;

It turns out that the linker isn't clever enough to figure out what default runtime library is needed for the executable if only static libraries are given to link, with no discrete object files. This can be corroborated by asking the linker to be verbose in the .pro file:
win32-msvc*: QMAKE_LFLAGS += /VERBOSE /VERBOSE:LIB /VERBOSE:REF
When the dummy file is present in the application project, the linker lists the following default libraries:
Processed /DEFAULTLIB:msvcprt
Processed /DEFAULTLIB:MSVCRT
Processed /DEFAULTLIB:OLDNAMES
Processed /DEFAULTLIB:uuid.lib
Without the dummy file, no default libraries are chosen by the linker at all. It is then unable to find the entry point, since the C runtime is not linked in.
Adding the relevant C runtime library is sufficient to link the application. In the application project file, one adds:
win32-msvc*:CONFIG(release, debug|release): QMAKE_LFLAGS += /DEFAULTLIB:msvcrt
win32-msvc*:CONFIG(debug, debug|release): QMAKE_LFLAGS += /DEFAULTLIB:msvcrtd

Related

How to statically link a library to another library with all symbols resolved

I have some XML parsing utility functions written inside C headers and source files based on expat library.
For this I have compiled my source files to a static library with expat statically linked to it.
I am able to use and the functions from the resulting xml utilities library with my applications only if I statically link both the utility library and expat with my application. I was of the view that I should be able to get my application built with only statically linking my utility library without requiring to statically link expat again with the application executable. Only linking my application with the utility library gives undefined symbol error for expat.
Can someone please guide me what am I missing ? I am using gcc compiler.
Thanks....
"I have compiled my source files to a static library with expat statically linked to it."
I'm fraid you haven't. A static library is not produced by the linker; no linkage is involved, so nothing can be linked to it.
A static library is nothing but a bag of object files in ar archive format.
When you are linking something that is produced by the linker - namely a program or a shared library -
you may offer such a bag to the linker. It will look in the bag and take out just the object files it needs to
carry on the linkage and link them into the target. The bag spares you the difficulty of
needing to know exactly which of the object files in it the linker will need, but the bag itself contributes nothing at all to the linkage.
Later
How can I get expat static library included in my utilities library, so that I only need to link my executable with a single static library. I don't want to extract the two archives and merge the object files together.
There is no other way of combining two ar archives.
Your resistance to linking libexpat is puzzling, without further context. It is available
through the package manager on any distro. You've made a library that depends on libexpat. Clients that link your
library will need also need to link libexpat. This is an utterly routine sort of dependency
that you should simply document and - if you are packaging your library - include
in the package dependencies. Almost invariably when we write new libraries we are augmenting the
libraries already available to our target users. If every library statically
incorporated all of its own dependencies then they would all be the size of an
operating system and of no practical use.

Go code building linker error. Can I link manually?

I am building Go code that uses CGo heavily and this code must be compiled into a shared or static library (static is highly preferred). (code for reference)
It all works just fine on Linux and Mac, but on Windows it fails on linker stage either saying that all 4 modes (c-shared, shared, c-archive, archive) are not available or if invoke go tool link -shared manually complains about missing windows specific instructions.
My understanding is that all I need to build usable lib.a is to compile everything I will use into object files (*.o) and then put it through ar to produce usable static library.
Now the question is whether I can completely skip Go's linker and based on prepared .o files create .a manually?
How would I go about doing that if that is even possible?
Looks like gcc on windows is unable to automatically discover necessary shared libraries. The problem was caused by GCC and not by Go.
Although for compiling Go I had to use self-compiled master tip as current release (1.6.2) does not support shared/static libraries on windows/amd64.
Manually feeding gcc with each shared library (ntdll, winmm etc) in default location (C:\Windows\SysWOW64) has fixed the problem.

Qt - linking an external static lib that uses WinBase

I'm trying to build a GUI using Qt 5.3.1 and having that link to a static lib (built with VisualStudio 2010 using /MD and /MDd). When linking in QtCreator IDE, I get 2 unresolved external linker errors generated from these two function calls from within the static lib.
Both of these (unresolved) functions are declared in WinBase.h.
::InitializeSecurityDescriptor
::SetSecurityDescriptorDacl
What is the easiest solution to get QtCreator to compile this lib? Ideally if possible, I'd like to also link whatever dependency in the static lib itself.
As the documentation of both functions specifies, you have to link against advapi32.lib. In general, all functions of the Windows SDK specify in a box at the end of the documentation the header where they are declared, the header that you should actually include and their import library.
As for the other dependencies, AFAIK there's no way to know - static libraries are just collections of object modules, that specify their dependencies only in terms of imported functions.

Visual C++: What is a dynamically linked .lib file?

I noticed the following about a library I use:
Library is compiled to .lib file.
My code needs to be compiled as Multi-threaded (Debug) DLL to link to this library.
I open the .sln (solution) file of the library (it is open source) and see the following in its Project properties:
Runtime Library option is set to Multi-threaded (Debug) DLL.
Configuration Type is set to Static Library (.lib)
My confusion is:
Isn't there a conflict in the library options above? (Static Library says one option, DLL says another)
What kind of an animal is a .lib that is dynamically linked? How is it different from a DLL?
Note that I am aware of the difference between static libraries and dynamic libraries in the Linux world.
The "RunTime Library" option isn't about YOUR library. It tells the compiler that you'll import your functions from MSVCRTxx.DLL at runtime.
The "configuration Type" option does refer to your library, and therefore is independent of the "RunTime Library" option.
A Windows DLL can be dynamically loaded with the LoadLibrary (or LoadLibraryEx) API, but then you have to find and bind each exported function to a function pointer using GetProcAddress or GetProcAddressEx. You'd better get the function signatures right, or Bad Things Will Happen, as usual.
A LIB file allows Windows to do all that for you when your EXE is started (including finding which DLL to use, and recursively loading dependent DLL's), linking the dynamic library statically at run time, while avoiding bloating your EXE file with the executable code, and allowing several processes to share the same DLL image in memory.
I don't know about the config mismatch, but a .LIB file when created with a .DLL library is an "export library" - it doesn't contain any code, but just the names of the callable functions and objects in the DLL. The linker uses this to satisfy references at link time which are finally resolved by dynamic loading at run-time.

Problem with static library in C++

I'm trying to use a static library created by me in Visual C++ 2005 (unmanaged C++). I declare one function "int myF(int a);" into a .h file, I implement it in a .cpp file, I compile it - the .lib file is produced.
I create a new project (a separate solution) in VC++ 2005 (also native C++), I add the paths for the include file and the lib file; when I invoke the function myF the linker reports an error: "error LNK2019: unresolved external symbol _myF referenced in function _main". if I create the client project in the same solution as the library project and then add a reference to the library projects, it works, but I'm not going to implement everything like this, but rather to add external libraries to my projects...
What is wrong?
Thank you.
You need to also include the actual .lib file in your 2nd project (not just the path to it).
There should be an option in the linker settings to do this.
It is not sufficient to list the folder in which MyStatic.lib can be found. You have to explicitly tell the linker that Dependant.vcproj is using MyStatic.lib.
In VS2005 you do this by project properties->Linker->Input->Additional Dependencies. You can also sprinkle some preprosessor stuff in the .h file to tell the compiler to tell the linker to use MyStatic.lib.
Edit:
The preprocessor magic goes like this
#pragma comment(lib, "MyStatic.lib")
(EDIT: This was a response to the question of getting the /NODEFAULTLIB error in link phase which has now been deleted... shrug)
You are mixing compiler settings if your are getting the defaultlib error. For example, if you build your library in debug and the build your main in release, you will get this error since they are built to use different versions of the CRTL. This can also happen if you use different settings for linking with the C Runtime as a object library or as a DLL. (See the C/C++ options, the "Code Generation" section, under the "Runtime Library" setting)
In many projects there isn't much you can do if you can't correct the settings of the library (for example, 3rd party libraries). In those cases you have to use the /NODEFAULTLIB switch which is a linker option in the "Input" section called "Ignore Specific Library".
But since you are in control of both the main and the library, build a debug and a release version of your LIB file or make sure your "C/C++;Code Generation;Runtime Library" settings match in both projects.
Try setting additional dependencies in the linker input for a project properties.

Resources