VS2010 static linking issue - c++

my company has recently upgraded from VS2005 to VS2010. We have a huge project which uses a lot of modules which are being linked statically into the exe. But there seem to be some issues with linking in VS2010.
To explain our problem, we've built a minimal example project which is composed as shown on this graphic:
There is an application using one function from library A. Library A calls one function of each library B and library C. Those two libraries call a function provided by library D.
For Exe 1 under Framework and References we set everything to false except for Link Library Dependencies which is set to true. The only reference added is linking to library A. For each of the libraries all the settings are set to false. Library A gets references to only B and C, as well as those two getting references to D only. Library D has no references.
When building the application it works without problems. The application notices that library A is using library B and C which are using library D, so it knows it has to link those libraries, too. The libs are linked into the exe without problems.
Now we change something in, let's say, library D. Just a little difference, only one letter. Now we try to build the application again, it notices the change and re-compiles library D, but: It doesn't link to it anymore. The result are linking errors in library B and C, because they use library D. We have to run Rebuild first, in order to force the complete building and then everything is linked again.
This happens for both the minimal example as well as for our main project. Of course, we can add each of the libraries as additional dependency for the exe but it would be nice if it would work just like it does when building the project for the first time and continue to work after changes in the code. We noticed that when setting Use Library Dependency Inputs to true, that it works again, but then it doesn't link the *.lib files but the *.obj files which is not what we want of course.
Has anyone made similar experiences or has anyone a solution for this issue? Is this a buggy behavior of VS2010?
TIA.
p.s.: All libraries and executables are native C++.
Edit: (Workaround taken from this site)
In the file %ProgramsFile%\MSBuild\Microsoft.cpp\v4.0\Microsoft.CPPBuild.Targets there is a line
<Target Name="GetResolvedLinkLibs" Returns="#(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets)">
If you change that line to
<Target Name="GetResolvedLinkLibs" Returns="#(LibFullPath)" DependsOnTargets="$(CommonBuildOnlyTargets);ResolvedLinkLib">
the linking works properly and all needed libs are linked to implicitly. The linker output not only shows lib_a.lib but also all other chained libs, lib_b, lib_c, lib_d without having them added manually as dependencies to the exe.
This seems to be more a workaround then a solution, maybe there is a proper way to achieve implicit linking.

Have a look at following links:
Visual Studio 2010 not autolinking static libraries from projects that are dependencies as it should be supposed to
Behavior of Link Library Dependencies in 2010
Unresolved Externals When Build a VC++ Project with Chained Static Lib Dependencies
Flexible Project-to-Project References

I only know that I had such similar situations because of wrong using of Libraries with same name but with different architecture. lets say, I have an Dll (lets call it mydll.dll) for x86 and will import it into my project it will work. If I will do the same with x64 dll (same name mydll.dll) it will work.
But if I want to include both libraries it is not allowed to only rename it into mydllx86.dll / mydllx64.dll. I CAN include now both libraries into Visual Studio. But when compiling it or restarting visual studio, one of both libraries will be unaccessable anymore.
In this case I perhaps it helps to have a look into library architecture and used namespaces / Api names.
Regards

You are pretty lost in that dialog if you are tinkering with Framework and References, those are settings that only apply to managed code. The term "reference" only applies to .NET assemblies. The linker doesn't support storing compiled managed code in a .lib. I'll work from the assumption that you actually are changing linker settings. If you make a change in library D then you also have to change its header file. Which in itself will be enough to get B and C rebuilt since one or more of their source code files should #include that header.
The only thing that Link Library Dependencies does is automatically make a .lib a dependency, same thing as Linker + Input, Additional Dependency setting. That however requires you to explicitly set the project dependencies. Right-click the B project, click Project Dependencies and tick D. Repeat for C. Repeat for A and tick B and C. Repeat for EXE and tick A.
This is rarely what you want, it makes the D library embedded into the B and C libraries. And B and C get embedded in A. The EXE now only has a dependency on A. It works, but it makes the .lib files unnecessarily beefy. And you have the problem you describe if you don't set the project dependencies properly, a rebuild of D doesn't cause it B and C to be relinked.
What you should do is not set dependencies between the .libs, they don't have any. Each can be built without the other .libs being present. A .lib is nothing but a bag of .obj files. All that's required is that you make all 4 .lib projects dependencies of the EXE project. That makes sure that they are built before the linker tries to link the EXE.

We starting seeing this issue again after moving to Visual Studio 2015 (and also in VS2017). The problem only seems to exist in the following configuration:
Project (EXE)
--> Static Library A (Reference)
--> Static Library B (Specified in Linker->Additional Dependencies)
--> Static Library C (Not in solution, specified in Linker->Additional Dependencies)
There are several other projects in the solution that use A and B. When something in project B or C changes, many of these projects give LNK4099 warnings.
In our case, the solution is to use the following:
Code Generation > Output Files > Program Database File Name: $(TargetDir)$(TargetName).pdb
Librarian > General > Output File: $(TargetDir)$(TargetName)$(TargetExt)
$(TargetDir) uses an absolute path versus the default $(OutDir) which in our case was relative. It seems that the correct path gets lost with multiple levels of indirection.
One interesting thing is if you switch the number of compile threads to 1, it doesn't appear to happen (maybe some kind of race condition within Visual Studio?).

Related

Reducing my boost lib folder

Even having already dug through loads of info on the net about this, I am still having some trouble understanding the boost lib files. I have Boost 1.51 installed and the lib folder is 1.7GBs which is just too much. I need to reduce it.
Just to show an example:
http://i.imgur.com/6nXfVEr.png
That is all the regex lib folders. There are 10 of them! I want to delete most of these, but I struggle to understand, which folders I need.
I assume 'libboost' is the static lib (which doesn't require a DLL) and the others are dynamic which do. Does it mean if I use the dynamic libraries I need boost DLLs in my project?
I can also see some are debug and others aren't. Is it necessary to keep both? or can I just always use the non-debug versions for my projects?
Finally, am I right in thinking, to make Visual Studio choose specific libs I go to the:
C/C++ project settings -> Code Generation -> Runtime Library, and change between /MT, /MD, etc?
If I use Multi-threaded (/MT), does that mean I can remove all the debug libs and dlls because this option only uses the static libs?
Thanks for any advice.
I assume 'libboost' is the static lib (which doesn't require a DLL) and the others are dynamic which do.
Yes.
Does it mean if I use the dynamic libraries I need boost DLLs in my project?
Yes.
Finally, am I right in thinking, to make Visual Studio choose specific libs I go to the: C/C++ project settings -> Code Generation -> Runtime Library, and change between /MT, /MD, etc?
Not quite so. Setting /MT or any other similar option will only make your application use the corresponding versions of runtime libraries (e.g. CRT). It does not mean you can only link statically after this, neither does it "select" anything for your own project-specific dependencies.
Whether you link to boost as a static library or DLL depends on which .lib file (libboostXXX or boostXXX) you specify in: Linker -> Input -> Additional Dependencies. Also, you may need to visit Linker -> General -> Additional Library Directories and add a path to your boost/libs folder (and possibly its subfolders) so that you don't have to specify full path for each library you are adding to dependencies.
However, you should always (especially when using static libraries) link to libraries built with the same runtime which you have selected in your main project. If you try to mix different runtimes, you will most likely get pretty cryptic linker errors about double-defined symbols (in system libraries) and such. In the worst case (usually due to a mismatch in some less obvious settings, like preprocessor definitions that change STL options) it will not lead to a linker failure, but to mysterious runtime crashes. Visual Studio 2010 and later, however, does pretty good job of detecting such mismatches (compared to previous VS versions).
Another issue might be that some of the boost headers are using #pragma comment to force linking necessary libraries by a specific name. If you find this a problem and want to specify your dependencies manually (or if it selects something you don't really need to link to), you can add a global preprocessor define BOOST_ALL_NO_LIB to C/C++ -> Preprocessor -> Preprocessor Definitions.
Also, do you really need all of the boost libraries in your project? There's a lot of them, and most are for very special things. In my experience, people usually only need a small subset of boost for their project-specific goals. To create such a subset, containing headers only for the libraries which you really use, and their dependencies, you can use the BCP utility. This would probably reduce your boost/boost folder dramatically. And, of course, you can also delete binaries for the libraries you are not going to use. Also note that most of the general-purpose libraries in boost are header-only and thus don't require linking to any libraries at all.

g++ linking .so libraries that may not be compiled yet

Im helping on a c++ application. The application is very large and is spread out between different sub directories. It uses a script to auto generate qt .pro files for each project directory and uses qmake to then generate make files. Currently the libraries are being compiled in alphabetical order.. which is obviously causing linking errors when a library its trying to link isn't built yet.. Is there some kind of g++ flag i can set so it wont error out if a library its trying to link hasn't been built yet? or a way to make it build dependencies first through the qt .pro file?
NOTE:
This script works fine on ubuntu 10.10 because the statements to build the shared libraries didnt require that i use -l(libraryname) to link to my other libraries but ubuntu 11.10 does so it was giving me undefined reference errors when compiling on 11.10.
Have you looked into using Qt Creator as a build environment and IDE? I've personally never used it for development on Ubuntu, but I have used it on Windows with g++, and it works great there. And it appears its already available as a package in the repository.
Some of the advantages you get by using it are:
Qt Creator will (generally) manage the .pro files for you. (If you're like me, you can still add lots of extra stuff here, but it will automatically add .cpp, .h, and .ui files as they are added to the project.)
You can set up inter-project dependencies that will build projects in whatever order they need to link.
You can use its integration with gdb to step through and debug code, as well as jump to the code.
You get autocomplete on Qt signals and slots, as well as inline syntax highlighting and some error checking.
If you're doing GUIs, you can use the integrated designer to visually layout and design your forms.
Referring back to your actual question, I don't think it's possible for a flag to tell gcc to not error when a link fails simply because there is no way for the linker to lazily link libraries. If its linking to static libraries (.a), then it needs to be able to actually copy the implementation of that code into the executable/library. If its dynamically linking (.so), it still needs to verify that the required functions actually exist in the library. If it can't link it during the linkage step, when can it link?
As a bit of an afterthought, if there are cyclic dependencies in your compile process (A depends on B, B on C, and C on A), then you might need to have a fake version of a library get built first, which only has empty stubs for the implementation of each function, and the full definition for each class or object. Then, build everything else while linking to that, and at the end, build the real version of the fake library, and link it to all the other versions that were already linked. I think this would only work on dynamic linking, though.
You could use a subdirs project to have control over the build order (no matter whether the other dev wants it or not :) ).
E.g.
build_all.pro
TEMPLATE=subdirs
CONFIG+=ordered
SUBDIRS=lib2/lib2.pro lib1/lib1.pro app/app.pro
The lib1.pro, lib2.pro, ... are your generated pro files.
Then run qmake once for the build_all.pro and also run make in that directory. This will build lib2 before lib1 and then app.

Building library without dependencies

I've got a huge application here called HugeApp, it needs different libraries (which I've coded) and some of these libraries might need dependencies (other libs coming from the internet or ad hoc lib developped here).
I was wondering, if it was feasible and/or a good idea to hide some of these dependencies from HugeApp.
Let's say that you make a library in charge of doing the encrypted communication on a system, does the top application care and/or needs to know that there is some encryption libraries that are needed for this part (comms) of the system? It might be implementation specific... or not...
Thank you
There's no need for it to know, if you build those libraries as external DLL's then the external libraries are the only thing that care about the dependency. If you add a reference to the pre-built DLL then HugeApp doesn't need to know about the dependencies of the library (as long as they are either present in the library or the appropriate DLL or lib file is present so that your dll can make use of it). If anything your library can be another project altogether and you can include a reference to that in which case the project of your HugeApp only cares about that main reference and the other project will handle everything else.
If you enable /OPT:REF in linker optimizations it you will list which (if any) libraries that have no functions or data used by the project during link time. You can then remove them from the dependency list and link line in project settings. This will reduce the chance of removing a static library that is a dependency of another static library if any are present/used in your VS solution.

MSVC - boost::python static linking to .dll (.pyd)

I got a VS10 project. I want to build some C++ code so I can use it in python. I followed the boost tutorial and got it working. However VS keeps to link boost-python-vc100-mt-gd-1_44.lib but it's just a wrapper which calls boost-python-vc100-mt-gd-1_44.dll. That's why I need to copy the .dll with my .dll(.pyd) file. So I want to link boost:python statically to that .dll(.pyd) file. But I just can't find any configuration option in VS or in the compiler and linker manual. The weirdest thing is I've got one older project using boost::filesystem with the very same config but that project links against libboost-filesystem-*.lib which is static lib so it's ok. I've been googling for couple of hours without any success and it drivers me crazy.
Thanks for any help or suggestion.
You probably don't want to do that. Statically linked Boost python has a number of problems and quirks when there are more then one boost python based library imported. "But I only have one" you say. Can you guarantee that your users won't have another? That you might want to use another in the future? Stick with the DLL. Distributing another DLL is really not that big a deal. Just put it side-by-side in the same directory.
What libraries are linked depends on the settings of your project. There are two possibilities: You can build against
statically
dynamically
linked versions of the c-runtime libs. Depending on which option is selected, the boost sends a proper #pragma to the linker. These options need to be set consistently in all projects which constitute your program. So go to "properties -> c++ -> code generation" (or similar, I am just guessing, don't have VS up and running right now) and be sure that the right option is set (consistently). Of course, you must have compiled boost libraries in required format before...

Linking static libraries in visual studio with composite dependencies

Suppose you have two static libraries A and B such that A references methods from B. Is it possible to statically link an executable to A and B such that there are not unresolved symbols in B referenced by A?
Here is my situation:
When I try to link everything up that way in Visual Studio 2010, there are unresolved symbols between A and B.. but not between the application and A. The symbols it complains about have the __imp prefix (which do not, and should not, exist in B's DUMPBIN). Why is it looking for symbols with the __imp prefix even though none of the libs are built as DLL's and I have included all of the required "Additional Library Dependencies/Directories" in all of the projects? Also, everything is built with the exact same compiler.
EDIT: It may be helpful to know that if library B is built as a DLL with an import library instead of a static library, everything will link up correctly.
EDIT: I am almost certain it is not a preprocessor condition causing a declspec() or something, because there are no linker errors when the App uses B.. just when A uses B.
ANSWER: Both Edwin and JimR are correct, there was actually a macro being used in a header causing a declspec, but I was too stubborn to notice it when they first mentioned that possibility. Thanks guys for your patience.
the dependecies should not matter ! they may even be circular ,like A refs B and B refs A. It sounds to me (since you get linker errors) that either you don't have headerfiles for those libs (do you declare funcs from A in B by hand or funcs from B in A) or the headerfiles compile differently in your program and in your libs (due to some #define or compiler option). Do you use the same calling conventions in both prog and libs ?
I do not have MSVS 2010 to look at, so take this with a grain of salt.
If the symbols have imp in the name, that means either there's a declspec(dllimport) floating around somewhere, a (possibly embedded in the code) compiler switch forcing A to see B as a DLL or you're linking old stuff and not what's currently being produced by the build process.
Was the project you're using imported from an older version of MSVS? I had a similar problem with a poorly managed project that was imported into MSVS 2008 a few years ago...
Either way, check A's build environment carefully and make sure you look for pragmas that embed compiler/linker switches.
Since your used lib B as a DLL before is it possible that when you build lib A your lib B was still a DLL and when you changed lib to library you forgot to rebuild A.