Related
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.
I am learning C++ and, in order to do so, am writing a sample wxWidgets application.
However, none of the documentation I can find on the wxWidgets website tell me what library names to pass to the linker.
Now, apart from wxWidgets, is there a general rule of thumb or some other convention by which I should/would know, for any library, what the names of the object files are against which I am linking?
We have more of a "rule of ring finger", instead of a thumb
Generally, if you compile the library by hand, it will produce several library files (usually .a .lib or something similar, depending entirely on your compiler and your ./configure) these are produced (typically) because of a makefile's build script.
Now a makefile can be edited in any way the developer pleases, but there are some good conventions (there is, in fact, a standard) many follow- and there are tools to auto generate the make files for the library (see automake)
Makefiles are usually consistent
You can simply use the makefile to generate the files, and if it's compliant, the files will be placed in a particular folder (the lib folder I believe?) all queued up and ready to use!
Keep in mind, a library file is simply the implementation of your code in precompiled format, you could create a library yourself from your code quite easily using the ar tool. Because it is code, just like any other code, you don't necessarily want to include all of the library files for a given library. For instance with wxWidgets if you're not using rich text, you certainly don't want to waste the extra space in your end executable by including that library file. Later if you want to use it, you can add it to your project (just like adding a .cpp file)
Oh and also with wxWidgets, in their (fantastic) documentation, each module will say what header you need to include, and what library it is a part of.
Happiness
Libraries are amazing, magical, unicorns of happiness. Just try not to get too frustrated with them and they'll prance in the field of your imagination for the rest of your programming career!
After a bit more Googling, I found a page on the wxWidgets wiki which relates to the Code::Blocks IDE, but which also works for me. By adding the following to the linker options, it picks up all the necessary files to link:
`wx-config --libs`
(So that does not solve my "general rule" problem; for any library I am working with, I still have to find out what files to link against, but at least this solves the problem for wxWidgets).
The build instructions are different for each platform and so you need to refer to the platform-specific files such as docs/gtk/install.txt (which mentions wx-config) or docs/msw/install.txt to find them.
FWIW wxWidgets project would also definitely gratefully accept any patches to the main manual improving the organization of the docs.
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.
I'm trying to teach myself C++ programming. The C++ is the easy part. Some patience and good reference material goes a long way. Including and linking against libraries is the hard part. The instructions provided usually assume some knowledge which I don't have and don't know how to aquire without painfully slow trial and error.
The latest concrete example is http://cpp-netlib.org/
I've spent the whole afternoon trying to get it to work and I still don't even an idea why it's not working.
How can I learn this skill from the ground up?
Is it it normal to have such enormous difficulties learning how to do this?
Well, the principle is pretty much always the same for any C++ compiler (the option flags mentioned are quite standard but might differ for particular compilers):
Install a library you want to use in your system (this may include a step to compile this library with your particular compiler toolchain).
Setup the include paths to be used for this library using the -I option
Use the headers of the library API in your code (#include <libheader.h>)
Setup the library paths to be used for this library using the -L option, tell the linker which libraries to link using -l<extra>, where extra should refer to some file named lib<extra>.a or lib<extra>.lib
Things to note:
Third party libraries might depend on further libraries you'd also need to install (compile with the same toolchain as your target uses)
On Windows using the MS Visual Studio (Express) toolchain you'll need to take care choosing the right library versions that are compliant with the 'threading model' and in general 'debug' / 'non-debug' library versions.
An (appropriate and useful) IDE will usually let you choose the toolchain (MinGW GCC, MS VS compiler, LLVM, etc.) on project setup, and offer some properties dialog to set these options.
What's necessary to setup for the toolchain, 3rd party libraries, IDE and OS you're using is a bit different learning curve and depends on what you want to use in particular.
I have an annoying problem which I might be able to somehow circumvent, but on the other hand would much rather be on top of it and understand what exactly is going on, since it looks like this stuff is really here to stay.
Here's the story: I have a simple OpenGL app which works fine: never a major problem in compiling, linking, or running it. Now I decided to try to move some of the more intensive calculations into a worker thread, in order to possibly make the GUI even more responsive — using Boost.Thread, of course.
In short, if I add the following fragment in the beginning of my .cpp file:
#include <boost/thread/thread.hpp>
void dummyThreadFun() { while (1); }
boost::thread p(dummyThreadFun);
, then I start getting "This application has failed to start because MSVCP90.dll was not found" when trying to launch the Debug build. (Release mode works ok.)
Now looking at the executable using the Dependency Walker, who also does not find this DLL (which is expected I guess), I could see that we are looking for it in order to be able to call the following functions:
?max#?$numeric_limits#K#std##SAKXZ
?max#?$numeric_limits#_J#std##SA_JXZ
?min#?$numeric_limits#K#std##SAKXZ
?min#?$numeric_limits#_J#std##SA_JXZ
Next, I tried to convert every instance of min and max to use macros instead, but probably couldn't find all references to them, as this did not help. (I'm using some external libraries for which I don't have the source code available. But even if I could do this — I don't think it's the right way really.)
So, my questions — I guess — are:
Why do we look for a non-debug DLL even though working with the debug build?
What is the correct way to fix the problem? Or even a quick-and-dirty one?
I had this first in a pretty much vanilla installation of Visual Studio 2008. Then tried installing the Feature Pack and SP1, but they didn't help either. Of course also tried to Rebuild several times.
I am using prebuilt binaries for Boost (v1.36.0). This is not the first time I use Boost in this project, but it may be the first time that I use a part that is based on a separate source.
Disabling incremental linking doesn't help. The fact that the program is OpenGL doesn't seem to be relevant either — I got a similar issue when adding the same three lines of code into a simple console program (but there it was complaining about MSVCR90.dll and _mkdir, and when I replaced the latter with boost::create_directory, the problem went away!!). And it's really just removing or adding those three lines that makes the program run ok, or not run at all, respectively.
I can't say I understand Side-by-Side (don't even know if this is related but that's what I assume for now), and to be honest, I am not super-interested either — as long as I can just build, debug and deploy my app...
Edit 1: While trying to build a stripped-down example that anyway reproduces the problem, I have discovered that the issue has to do with the Spread Toolkit, the use of which is a factor common to all my programs having this problem. (However, I never had this before starting to link in the Boost stuff.)
I have now come up with a minimal program that lets me reproduce the issue. It consists of two compilation units, A.cpp and B.cpp.
A.cpp:
#include "sp.h"
int main(int argc, char* argv[])
{
mailbox mbox = -1;
SP_join(mbox, "foo");
return 0;
}
B.cpp:
#include <boost/filesystem.hpp>
Some observations:
If I comment out the line SP_join of A.cpp, the problem goes away.
If I comment out the single line of B.cpp, the problem goes away.
If I move or copy B.cpp's single line to the beginning or end of A.cpp, the problem goes away.
(In scenarios 2 and 3, the program crashes when calling SP_join, but that's just because the mailbox is not valid... this has nothing to do with the issue at hand.)
In addition, Spread's core library is linked in, and that's surely part of the answer to my question #1, since there's no debug build of that lib in my system.
Currently, I'm trying to come up with something that'd make it possible to reproduce the issue in another environment. (Even though I will be quite surprised if it actually can be repeated outside my premises...)
Edit 2: Ok, so here we now have a package using which I was able to reproduce the issue on an almost vanilla installation of WinXP32 + VS2008 + Boost 1.36.0 (still pre-built binaries from BoostPro Computing).
The culprit is surely the Spread lib, my build of which somehow requires a rather archaic version of STLPort for MSVC 6! Nevertheless, I still find the symptoms relatively amusing. Also, it would be nice to hear if you can actually reproduce the issue — including scenarios 1-3 above. The package is quite small, and it should contain all the necessary pieces.
As it turns out, the issue did not really have anything to do with Boost.Thread specifically, as this example now uses the Boost Filesystem library. Additionally, it now complains about MSVCR90.dll, not P as previously.
Boost.Thread has quite a few possible build combinations in order to try and cater for all the differences in linking scenarios possible with MSVC. Firstly, you can either link statically to Boost.Thread, or link to Boost.Thread in a separate DLL. You can then link to the DLL version of the MSVC runtime, or the static library runtime. Finally, you can link to the debug runtime or the release runtime.
The Boost.Thread headers try and auto-detect the build scenario using the predefined macros that the compiler generates. In order to link against the version that uses the debug runtime you need to have _DEBUG defined. This is automatically defined by the /MD and /MDd compiler switches, so it should be OK, but your problem description suggests otherwise.
Where did you get the pre-built binaries from? Are you explicitly selecting a library in your project settings, or are you letting the auto-link mechanism select the appropriate .lib file?
I believe I have had this same problem with Boost in the past. From my understanding it happens because the Boost headers use a preprocessor instruction to link against the proper lib. If your debug and release libraries are in the same folder and have different names the "auto-link" feature will not work properly.
What I have done is define BOOST_ALL_NO_LIB for my project(which prevents the headers from "auto linking") and then use the VC project settings to link against the correct libraries.
Looks like other people have answered the Boost side of the issue. Here's a bit of background info on the MSVC side of things, that may save further headache.
There are 4 versions of the C (and C++) runtimes possible:
/MT: libcmt.lib (C), libcpmt.lib (C++)
/MTd: libcmtd.lib, libcpmtd.lib
/MD: msvcrt.lib, msvcprt.lib
/MDd: msvcrtd.lib, msvcprtd.lib
The DLL versions still require linking to that static lib (which somehow does all of the setup to link to the DLL at runtime - I don't know the details). Notice in all cases debug version has the d suffix. The C runtime uses the c infix, and the C++ runtime uses the cp infix. See the pattern? In any application, you should only ever link to the libraries in one of those rows.
Sometimes (as in your case), you find yourself linking to someone else's static library that is configured to use the wrong version of the C or C++ runtimes (via the awfully annoying #pragma comment(lib)). You can detect this by turning your linker verbosity way up, but it's a real PITA to hunt for. The "kill a rodent with a bazooka" solution is to use the /nodefaultlib:... linker setting to rule out the 6 C and C++ libraries that you know you don't need. I've used this in the past without problem, but I'm not positive it'll always work... maybe someone will come out of the woodwork telling me how this "solution" may cause your program to eat babies on Tuesday afternoons.
This is a classic link error. It looks like you're linking to a Boost DLL that itself links to the wrong C++ runtime (there's also this page, do a text search for "threads"). It also looks like the boost::posix::time library links to the correct DLL.
Unfortunately, I'm not finding the page that discusses how to pick the correctly-built Boost DLL (although I did find a three-year-old email that seems to point to BOOST_THREAD_USE_DLL and BOOST_THREAD_USE_LIB).
Looking at your answer again, it appears you're using pre-built binaries. The DLL you're not able to link to is part of the TR1 feature pack (second question on that page). That feature pack is available on Microsoft's website. Or you'll need a different binary to link against. Apparently the boost::posix::time library links against the unpatched C++ runtime.
Since you've already applied the feature pack, I think the next step I would take would be to build Boost by hand. That's the path I've always taken, and it's very simple: download the BJam binary, and run the Boost Build script in the library source. That's it.
Now this got even a bit more interesting... If I just add this somewhere in the source:
boost::posix_time::ptime pt = boost::posix_time::microsec_clock::universal_time();
(together with the corresponding #include stuff), then it again works ok. So this is one quick and not even too dirty solution, but hey — what's going on here, really?
From memory various parts of the boost libraries need you to define some preprocessor flags in order to be able to compile correctly. Stuff like BOOST_THREAD_USE_DLL and so on.
The BOOST_THREAD_USE_DLL won't be what's causing this particular error, but it may be expecting you to define _DEBUG or something like that. I remember a few years ago in our boost C++ projects we had quite a few extra BOOST_XYZ preprocessor definitions declared in the visual studio compiler options (or makefile)
Check the config.hpp file in the boost thread directory. When you pull in the ptime stuff it's possibly including a different config.hpp file, which may then define those preprocessor things differently.