choosing options before building libraries - c++

I'm preparing to build crypto++ libraries on debian system, although debian repositories provide them via apt-get I want to to do it from source to make sure that the compiled libraries are the latest one and to build with certain options only.
The default makefile is configured to build a static library, release build, and I want to modify makefile for my needs and to add some other stuff there.
Basically I'll use these libraries only for learning, no release programs of any kind, so my question is whether I need release build or debug for learning, also I'm not sure if it's better to build shared or static libraries for learning purposes?
I suppose this question sounds funny but I'm unsure why would I need debug libraries, to debug simple programs? or to debug libraries it self?

Difference between a debug and a release lib is that the debug usually have more internal checks to ensure that you are using the lib correctly, the counterpart is that the lib is also heavier and slower. That's why release build are done with the release lib.
Static linking(Copy): one large exe file, more comfy for development. You move the parts of the librairy you use into your binary.
Dynamic linking(Reference): a small exe file plus one or more .so/.dll files. Your executable use reference to the librairy, so X programs using the same lib only refer to the same instance of the lib. It doesn't duplicate code as static linking does.

Related

Wxwidgets issue running binary on another computer

Hello when I build my wxWidgets GUI application on Linux the build goes fine. I can even run it and it works as expected. When I copy the binary to another Ubuntu computer and try to run it I get this error:
./app2: error while loading shared libraries: libwx_baseu_unofficial-3.1.so.0: cannot open shared object file: No such file or directory
Even when copying the lib across I still get an issue. Why is it dependent on external libraries and how can I solve this problem as I don't want other computers to require this library to be installed? I suppose I could try to statically link it but others recommend you do not do this.
You need to install the entire wxWidgets runtime/shared library on any machine you copy your binary onto. This is the whole point of using aptitude -- each binary package has a list of dependencies that get installed along with it.
To overcome this you need to statically link your binary. You are currently using shared linking, which relies on, as you note, external libraries. ".so" means Shared Object. You'll have to link against static archive libraries, often ending in ".a". Typically development packages provided by aptitude do not provide these, so you will probably have to compile wxWidgets yourself to provide these. Just make sure to also statically link and compile all of wxWidgets downstream dependencies as well. This is the major downside of static linking.
You can also look into something like Holy Build Box.

How to package c++ dependencies on linux

I'm developing a c++ program on Ubuntu 16.04 using cmake, compiling with g++5 and clang++-3.8.
Now I'd like to make this Program availabile for 14.04, too, but as I'm using a lot of c++14 features I can't just recompile it on that system. Instead, I wanted to ask if/how it is possible to package all dependencies (in particular the c++ standard library) in a way that I can just unpack a folder on the target system and run the app.
Ideally I'm looking for some automated/scripted solution that I can add to my cmake build.
Bonus Question:
For now, this is just a simple command line program for which I can easily recompile all 3rd party dependencies (and in fact I do). In the long run however, I'd also like to port a QT application. Ideally the solution would also work for that scenario.
The worst part of your contitions is an incompatible standard library.
You have to link it statically anyway (see comments to your answer).
A number of options:
Completely static linking:
I think it's easiest way for you, but it requires that you can build (or get by any way) all third-party libs as static. If you can't for some reason it's not your option.
You just build your app as usual and then link it with all libs you need statically (see documentation for your compiler). Thus you get completely dependencies-free executable, it will work on any ABI-compatible system (you may need to check if x86 executable works on x86_64).
Partially static linking
You link statically everything you can and dynamically other. So you distribute all dynamic libs (*.so) along with you app (in path/to/app/lib or path/to/app/ folder), so you don't depend on system libraries. Create your deb package which brings all files into /opt or $HOME/appname folder. You have to load all dynamic libs either "by hand" or ask compiler to do it on linking stage (see documentation).
Docker container
I don't know much about it but I know exactly it requires that docker be installed on target system (not your option).
Useful links:
g++ link options
static linking manual
Finding Dynamic or Shared Libraries
There are similar docs for clang, google it.

Can a statically linked application also link to some dynamic libraries?

I'm building an application using Qt 5.8 and setting up for static builds (since this seems to be the best way to get OpenSSL working when deploying the application to other computers). However, we also have a dependency on WebEngine which cannot be built statically.
Is it possible to build the application using a statically built Qt5.8 but still dynamically link the WebEngine libraries when compiling?
I can get the application working with a fully dynamic build - so will it simply dynamically link any libraries that weren't built into the static compiler? Obviously, I will still need to provide the dynamic library with the executable when deploying.
Yes you can. Almost all build systems used in Qt (qmake, cmake, qbs) provide easy options for linking both static and dynamic libraries.
What build system are you using?
Yes, you can do it. I had to build Net-SNMP which gave me a ./configure file in which I mentioned the shared and static library, wherein the system libraries were dynamically linked and OpenSSL was statically linked.
You can go through ./configure file post downloading Net-SNMP and go through the file which does the same task and tweak the values according to your usage and environment.
Additionally, go through link 1 and link 2 which will give you a brief idea about how to create a shared and dynamic library.

How to use separate CMake targets for host application and any of the used libraries?

When I'm using CMake and library which also uses CMake, I add the library directory in my CMake project to allow building the library alongside my project. For example:
# add SFML library dependencies
add_subdirectory("third_party/lib/SFML")
include_directories("third_party/lib/SFML/include")
target_link_libraries(${CMAKE_PROJECT_NAME} sfml-system sfml-window sfml-graphics)
Then CMake automatically matches project Debug builds to use library Debug build, and project Release builds to use library Release build. In some cases it is useful build targets to be controlled separately for the main project and every one of the libraries used by it. For example, if I'm not interested in debugging inside the library code I will want to build in Debug mode only my code and to link it against Release version of the library, because I don't want to sacrifice additional performance. In other cases maybe I want to debug only inside one of the used libraries, if I have suspicious for bug inside it, but again for performance reasons I want to link release versions for all other libraries. Is it possible and what is the best way to achieve this behavior?
With both imported targets and dependent targets from the same build tree, you will always get the behavior you described, that each configuration uses its own matching build of the library. Messing with this means fiddling with CMake's internals, so I'd advise against it.
If you want to link against a specific version of the library, the most robust way is to use find_library. Note that this will only work if the library dependency is already available in its binary form at configure time. That is, you can no longer build the dependency as part of the dependent project.
If that is not an option, consider using ExternalProject_Add to build the dependency and specify the location of the dependency binary manually.
All in all, your current approach is the most convenient one, so only change this if performance of the dependency's debug build is a real problem. Also note that while mixing debug and release builds is mostly fine for C libraries, it can easily break for C++ libraries, especially if you have standard library types on the interfaces.

C++ Linking release built library with my debug build

I've downloaded a 3rd party library, and built the .lib file in 'release' mode.
After adding the lib to my project, if i run my project in release mode, it's fine. But if i run my project in debug mode, i get an error:
_iterator_debug_level value '0' doesn't match value '2;
I could rebuild the library in debug mode, but I don't think I'll need to be debugging the library itself? And I've downloaded prebuilt 3rd party libraries before which only come with a release build (i assume?) that link fine whether my project is in debug or release. I'm wondering how that is done.
If you want to distribute a release library that others can use in either release or debug mode, you need to do two things:
Build a DLL, so that you get your own copy of the C runtime library
Not share CRT resources, such as the heap, across the library boundary. The biggest thing for C code is that dynamically allocated memory has to be deallocated on the same side of the boundary. For C++ code, you can use the std namespace inside your DLL, but not pass those objects across the boundary.
That's what the pre-built third-party libraries have most likely done. You can do the same thing with your library only if the external interface doesn't share CRT objects. Or you can build separate release and debug versions as static libraries.
Looks like your debug binary and the library you downloaded use incompatible iterator debug modes. Iterator debugging is usually controlled by macros. Depending on macro values the sizes of interators and many other objects can change. You are lucky that your program emitted useful error message instead of simply crushing.
Check the library documentation and make sure that your project uses the same iterator debug mode. You may also try recompiling the library in release mode. If that doesn't help, you would have to recompile the library in debug mode, even if you don't intend to debug the library itself.