Sharing C++ static libraries between multiple solutions causes unnecessary rebuild - c++

I have two solutions that both include and reference the same static library. And I'm including the library using the "Add reference..." feature, as opposed to specifying additional an linker input. It seems as though when I build one of the solutions, it causes the other solution to think it needs to rebuild the shared library, which then causes it to re-link the second solution. Thus, if I go back and forth between the two solutions building (without making any code changes) the solutions perform the link every time.
It doesn't appear that the shared static library is actually being re-compiled, but VS is performing the librarian step for it. I'm guessing this librarian step is happening because the .lastbuildstate file (which contains a path to the solution that last build the project) is determined to be outdated.
Anybody ever experienced this problem before? Is there a better way to go about this?

If the library is really shared and independent from both solutions, I'd suggest moving it to a separate solution... I understand that's not really what you intended, but it seems logical by the nature of dependencies itself.
Another consideration in favor of this is that the library may be later used for other projects. Hence, it'd be totally better to move it to a separate location (separate solution, separate folder in VCS) and treat it as any third-party library (i.e. openssl, boost, etc), specifying the dependency as linker input.
All of the above is just my thoughts on how I'd do it and is not a representation of any "best practices".

Related

C++ import library by source

I'm new to C++ and wonder if it is good practice to include a library by source code. If it is, what would be the best way to achieve this? Just copying in a subfolder and using include?
In my special case, I have written a small library and I'm going to use it on two different microprocessors. Compiling the library separately, copying all headers and using this "package" seems to be overkill for me.
Compiling the library separately is what should be done.
It's not that overkill either : you're just compiling the .o files for your library, then wrapping them in an archive and handling that archive around.
Normally libraries are used as libraries because it is much easier and comfortable that way. If you are using dynamic libraries (.dll or .so) things get even better because you can replace libraries on the fly and things should continue to work smoothly.
You decided to use code repositories instead of libraries which means probably more work for you. If you are happy this way that's OK, but just make sure you do not break any license, some lgpl packages (like Qt) clearly
require their libraries to be linked dynamically.
The best way to do this: hard to say but in your place I would probably use git and include the libraries as submodules.
Just #includeing source code is a bad idea since it means just to copy the code into your own, things can go wrong that way. For example if there is a static variable somewhere in the library code and the same named static variable in your code you will have a conflict.
Instead you should probably compile the library separately and link it, possibly the same way as you would do anyway (ie you build the library and then you link with that library). But the light weight alternative would be just to compile the additional C++ files and then link the object files together to an executable. Details on how you do that is compiler specific.
There's valid reasons for including the library source in this way, for example if your project needs to modify the library during development it would be easier to do so if the rebuilding of the library is done as a part of the build process of the project. With a well designed build process the library shouldn't have to be rebuilt unless there are actual changes to it.
The value of a library is in part that you link it more often than you compile it, leading to a net saving.
If you control all the source, then whatever build process works best for you is fine.
I agree with πάντα ῥεῖ but I'll also add that the reason it is bad practice is because the compiled library can be stored in your computer in a common location and used by tons of different programs, thereby reducing the amount of data your computer has to store, in memory as well as RAM(if more than one running program uses the same library). An example is openGL which is a library that many games use and is probably already in your system somewhere. If you use windows, software installers link up these libraries to their programs and add them if you don't have them. If you use linux, you will be notified if libraries are missing and prompted to install them. All of that aside, you can, technically use un-compiled libraries but that introduces a number of potential licensing problems as well as additional problems with THEIR dependencies.
By copying source code to other projects and "mixing" it with other source code will stop this library from being a "library". Later on you will be tempted to make a small change in one copy (for CPU) or fix a bug and forget to do the same in the other copy.
There might be additional consideration but you should try to keep the code in one place. Do not Repeat Yourself (DRY) is a very strong and fundamental principal of software engineering with many benefits.

C++ Linking static librarys to a dynamic library

It's a bit annoying.
I have a project that is entirely dynamically linked, but I want to use a library that seems to be only designed to be statically linked, using the /MT flags, Is it possible to build a separate dll to link to the static libs and then link to that In my project?
I apologise for the rushed explanation, I'm quite tired.
The library in question is the bullet physics library.
Edit:
Well, with more googling, it appears that there can be a /MD/MDd compiled version, though I'm not sure where It's located.
Edit(for anyone interested):
According to this page: http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=3846
"If your entire engine is compiled with the /MD flag then you would use the 'release DLL' version of bullet. You should not mix libraries compiled with /MD with ones compiled with /MT. That's the main difference. There is no "separate DLL (.dll)" files for bullet."
Edit: And If I build it using the MSVC Runtime library, then it fails.
In short, I have no idea what to do.
He's what I'm doing:
Building the whole library in cmake, using the Visual studio 12, 2013 compiler.
Then building the project built by cmake, to build all the required projects.
This is the supplied instructions. Here
Last Edit:Thank you all so much for you help! I managed to build it in the end
Sorry for any spelling mistakes, I was quite tired at the time :3
Short answer, yes.
Although you could just have the dynamic libraries link to it, there are scenarios where this may cause serious problems, depending on how the library was written (state information, etc.).
Although it's more work, a wrapper DLL is probably the safest course of action. However, this is offset by the fact that you only need to wrap the functions actually called from the various components of your application, not the entire API provided by the library. Also, you'll need to have some kind of slight rename to the functions you actually wrap, to prevent ambiguity.
On edit:
Just took a look at the bullet physics library, as I was not personally familiar with it and was curious about your options after I initially answered. If they're that explicit about not supporting dynamic builds for the library, I think wrapping whatever functions you actually use would definitely be safest. That sucks. I hope it's not too large of a cross-section.

C++ Linker issues, is there a generalized way to troubleshoot these?

I know next to nothing about the linking process, and it almost always gets in the way when I am trying to start a new project or add a new library. Whenever I search for fixes to these type of errors, I will find people with a similar problem but rarely any sort of fix.
Is there any generalized way of going about finding what the problem is, and fixing it?
I'm using visual studio 2010, and am statically linking my libraries into my program. My problems always seem to stem from conflicts with LIBCMT(D).lib, MSVCRT(D).lib, and a few other libraries doublely defining certain functions. If it matters at all, my intent is to avoid using "managed" C++.
If your error is related to LIBCMT(D).lib and the like, usually that depends from the fact that you are linking against a library that uses a different CRT version than yours. The only real fix is to either use the library compiled for the same version of the CRT you use (often there is the "debug" and "release" version also for this reason), either (if you are desperate) change the CRT version you use to match the one of the library.
What is happening behind the scenes is that both your program and your library need the CRT functions to work correctly, and each one already links against it. If they are linking against the same version of it nothing bad happens (the linker sees that it's the same and doesn't complain), otherwise there are multiple conflicting implementations of the same functions, so the linker doesn't know which are right for which object modules (and also, since they are probably not binary compatible, internal data structures of the two CRTs will be incompatible).
The specific link errors you mentioned (with LIBCMT(D).lib, MSVCRT(D).lib libraries) are related to conflicts in code generation options between modules/libraries in your program.
When you compile a module, the compiler automatically inserts in the resulting .obj some references to the runtime libraries (LIBCMT&MSVCRT). Now, there is one version of these libraries for each code generation mode (I'm referring to the option at Configuration properties -> C/C++ -> Code Generation -> Runtime Library). So if you have two modules compiled with a different mode, each of them will reference a different version of the library, the linker will try to include both, and of course there'll be duplicated symbols, since essentially all the symbols are the same in these libraries, only their implementations differ.
The solution comes in three parts. First, make sure all the modules in a project use the same mode. Second, if you have dependencies between projects, all of them have to use the same mode. Third, if you use third-party libraries, you have to either know which mode they use (and adopt it) or be able to recompile them with the desired mode.
The last one is the most difficult. Sometimes, libraries come pre-compiled, and not always the provider gives information about the mode used. Worse, if you're using more than one third-party library, they may have conflicting modes. In those cases, you have no better option than trial-and-error.
Also notice that each Visual Studio version has its own set of runtime libraries, so when using third-party libraries you have to use those compiled with the same version of Visual Studio you're using. If the provider doesn't offer it, your only choice is to recompile yourself.

Lib Files and Defines

I'm using a couple of external libraries and I'd rather not have to include all their source and header files in my main source directory or in my project file. One option would be to compile the libraries as lib files and link them like that. However I'm not sure the defines get evaluated before or after the lib file gets created (which one is it?). If it's before then obviously I can't just pack them because they might not work properly on different compilers or systems.
So if I can't pack the libraries as lib files, is there any way for me to link in the c or cpp source files? Probably not, since they would have to be compiled first, but maybe I'm wrong.
Edit: Here's a follow-up question, based on answers. Do you think it'd be too much of a hassle to have a makefile that creates the lib files? I'd still rather not add the sources to my project or in my source directory.
Library is a binary file, so all defines obviously already in.
Just to make order, defines are evaluated as 1st stage of compilation process - the step is called preprocess. At this stage, for each cpp files created one file containing all #include'ed in it files recursively and all macros are evaluated.
Any way 3rd party should not depend on your compilation flags with one exception - release/build lib. Only in this case you need 2 versions of 3rd lib.
As regarding to question if to compile 3rd party libs once or each time while compiling your code it depends. If you are doing it only for itself than do what looks an easies way for you, but if we're talking about development team and the project to be maintain for a long time, than more things are to be considered.
SO we're talking about some solid solution for a team and we want to compile library several times.
In this case I personally strive to compile 3rd part library once and use it many times. This reduces compilation times for each build for each developers, which means faster development.
Nice, but where you hold these libs. I like phisycal separation - 3rd party library and my code not in same tree. This can avoid some not intentional errors. A good build system, and most of time it's mandatory, should be re-buildable. This means that if you checkout your code after year, you can compile and receive exactly same binaries.
Once I used some external read only tree on my machine. This tree was managed only by me.
To make my sources re-buildable, each next version of 3rd party library put in direcoty containing it's version and my source tree was updated to point to this point. If you build on several machines, than the read only tree should be visible on all these machines.
Additioanal solution is to check if your SCM tool (I suppose you use one) gives you some ability to combine several sub-tries from repository in one checkhout. For each 3rd party library there's one sub-tree. This way 3rd party libraries are available on all machines your build. I currenly use these method on subversion - it's called svn:external. On CVS AFAIK it's called cvs modules. Additional advantage that the libraries are managed by source control system, so you can track all changes done to 3rd party libs.
defines get evaluated even before compiling. They are dealt with by the pre-processor, that prepares the code for the compiler to use. So yes, they are evaluated before the libraries are created.
You can't link against source code. You can only link with object files, static libraries, or dynamic libraries (shared object files/DLLs).
Using dynamic linking can be a good option, especially if the externals are large and/or you'll be using them in many executables.

Organizing library dependencies

I've noticed that there seem to be two approaches to linking: a flat and a hierarchical way.
Let me illustrate with two examples:
A Visual Studio solution can contain multiple projects with one of them being the main project. My usual approach is then to add all required libs to the main project and none to the other projects. I like this because that way I don't get "multiple definition"-linker errors. I don't know if this approach has an official name so I'll call it the flat way.
On the job our team works on a Linux-based traffic generation application. The build system uses Automake. When looking through the makefiles I noticed that each library specifies the libraries it requires (in the noinst_LIBRARIES variable). Each of these libraries can in turn specify their dependencies. This leads to a tree-like structure. So I call it the "hierarchical approach".
What are the best practices for this? It doesn't seem often discussed.
It usually comes down to static vs shared libraries.
If you use static libraries, then the main program must usually (always?) be linked against every library that it depends on, either directly or indirectly, hence a flat linking structure.
For shared libraries (or DLLs in Windows), each library bundles up its own dependencies, so the main program only needs to be linked against the libraries it depends on directly, leading to a graph structure.