How to package C++ with dlls and libraries - c++

I'm wondering how to "package" a C++ project for release. It uses various libraries, and I don't want a user to have to go through the same setup I did, with putting the right files in the right place and such. I had difficulty researching this, because I'm not sure the technical term for this issue. If I'm using command line compiling on Linux, is there an easy way to do this?

Your approach to this will differ on Windows and Linux because each OS handles this a different way. I'm more familiar with Linux so I'll restrict my answer to just the Linux side of things.
When you link your executable with a library using -l flag the linker defaults to looking in the normal system library directories so there are four approaches here.
Require the user to properly install the libraries themselves. However, it sounds like you don't want to do that.
Have the user add the library location to LD_LIBRARY_PATH variable.
Your third option is force the linker to look in a certain path for the libraries using the -rpath flag. For example, to have the application look in its working directory for a shared library you can compile with: g++ -rpath ./ -l SomeLib -o MyApp myapp.cpp
One other option is to static link your code with their library that way you only have to distribute one executable. If a static library exists you can use g++ -static -l SomeLib -o MyApp myapp.cpp to tell gcc to link statically.

On windows I would recommand wix http://wix.sourceforge.net/ to create the .msi installer
I would like to point out, the lookup path for .dlls I recommand putting all .dll in the same folder as your .exe since this has the highest priority
However, the vc crt (the c/c++ runtime library) should be installed using the redistributional package from microsoft -> updates automatically http://www.microsoft.com/de-de/download/details.aspx?id=5555
Wix can include the redistributional package into the same .msi therefore you have only to deploy a single installer file.

You mean an installer?
On Windows the program that you run to install a new app which outs everything in the correct directory, creates the start menu and lets you un-install it?
There is an installer builder in Visual Studio (might not be in the free express version) which makes .msi installer files. It's fairly easy to use for simple tasks but becomes complicated to do anything more.
Alternatively, to create traditional setup.exe type installs I use the excellent free Innosetup
On linux you would generally create a package using whatever format your distribution uses (.deb / .rpm ). There are lots of instructions on the specifics of each one and the tools to do so will probably already be installed in your Linux system

Related

Build Environment C++ using Mingw?

I haven't programmed for a while and am trying to set up my build environment on a new laptop. I've just forgotten how and think that I did allot of things wrong last time!
What I'm trying to do is have that common Include Directory and common Lib directory so when I build projects or other dependencies, etc... my compiler is able to find all the include and lib files it needs. I'm not formally trained so some obvious things to you guys are learning points for me.
I'm going to use a Mingw compiler and MSYS. Off memory I put the Include directory and the lib directory in the Mingw directory but I could be wrong there.
I'm just trying to set up an effective and simple build environment on Windows 7.
Where should all my directories go? Thanks
If you aren't already, MSYS2 is generally preferred over MSYS. I'm going to answer this assuming MSYS2. I use the 64 bit version, so that is what I'll show, but it should be simple enough to change.
I will also assume you put the msys64 directory in the base directory, if not replace C:/msys64/ with C:/wherever/you/put/it/msys64/.
When using the msys shell, /c/msys64/usr/ is the same as C:/msys64/usr/ which is the same as /usr/ since it tries to blend Linux file organization with windows, and it can sometimes be slightly unintuitive. When you install msys libraries, usually the include files are in C:/msys64/usr/include/ and the libraries are in C:/msys64/usr/lib/. The exception to this is when you have a 64-bit version and a 32-bit version of a program, in which case the headers are in C:/msys64/mingw64/include/ and the libs in C:/msys64/mingw64/lib/ for 64-bit (mingw32 for 32 bit).
In order to build using these, you will need to add the appropriate include paths and library paths. So, to make all 64-bit programs available, you would add the following flags
-IC:/msys64/usr/include -IC:/msys64/mingw64/include -LC:/msys64/usr/lib -LC:/msys64/mingw64/lib
When you compile your own programs from source, you put them wherever you'd like. It is best not to put them in the same directory as the package manager to avoid collisions. Running make install sometimes won't run as seamlessly on msys as it would on linux. In these cases, creating a folder such as C:/msys64/custom/include/ is a safer alternative. See https://unix.stackexchange.com/questions/30/where-should-i-put-software-i-compile-myself for some more insight on this.

How to install protobuf on windows? (Win7x64/MinGW)

C++-Protobuf does not compile in VS2012. Now I want to use MinGW to compile it on windows. Can someone please give me some brief headwords on how to compile protobuf on Win7 x64. I already installed MinGW with the GUI installer. Google writes as MinGW setup notice that I should refer to the Unix installation notes. But I cant figure out how to use the auto tools on windows.
Edit
Okay this is what I've done until now:
$ mount C:/ WinDir
$ cd ./[...]/protobuf.2.4.1
$ ./configure
$ minGW32-make.exe
$ minGW32-make.exe check
minGW32-make.exe runs without errors, but no tests are running and I cant find libprotobuf.lib. There are some libprotobuf.dll but I need the lib, dont I?.
You should have an MSys console together with your MinGW instalation. This console provides an linux-like environment in which you should be able to use autotools normally.
If MSys is not installed, you can grab it from the MinGW site too.
cd to your directory with sources and try the usual:
$ ./configure
$ make
Some libraries cause problems on Windows but most compile well with MinGW and MSys. Come back and add more info to your question if you run into specific problems.
Edit:
minGW32-make.exe runs without errors, but no tests are running and I cant find libprotobuf.lib. There are some libprotobuf.dll but I need the lib, dont I?.
Usually for a dynamic library you'd get protobuf.dll (the dynamic library) and libprotobuf.a (the static wrapper library).
When linking, just pass -lprotobuf to the linker - it will look for both libprotobuf.a and protobuf.lib.
(.lib is another static library format, which is partially handled by MinGW but not native here.)
You will not work with a .lib file when using the MinGW toolchain. Instead, you are able to link against the dll directly. The MinGW Wiki explains this.
I could get dll and lib both. This is when you do not want static lib file and want to use dll and lib file.
You need to make following changes in Protobuf code:
Open the project in VS. Or any other editor. I use VS2015.
In libProtoBuf project settings, in C/C++ Preprocessor add following flags.
PROTOBUF_USE_DLLS; LIBPROTOBUF_EXPORTS;
Those flags will export information from profobuf using dllexport
in ur client code where you are using Protobuf, define: PROTOBUF_USE_DLLS. Which will make protobuf includes to use dllimport.
Once you do step 2, you will see both dll and lib in your output folder. Otherwise, you will always see just dll and not lib file.
Hope this helps. If not, please write a message here and I can help you getting this sorted out.

Using libcurl without installing it

How can I use libcurl with my project without actually installing it or curl on the system?
I want to make my source-code portable, so that any developer can copy the folder with all sources and other files, run make and compile the program without the need for system level installations.
I am looking for (probably separate) solutions for Linux and for Windows (dll?). If it is possible, provide some standard/official solution and not hack (I'd like to be educated about linking third party libraries)
I've used it on Windows using Visual Studio, all you need to do under Windows:
Download the source
Using CMake generate the project files (when using Visual Studio).
Build the libraries, 3 files will be built: libcurl.lib, libcurl_imp.lib and libcurl.dll
Include curl.h in your project and add the paths to your .lib files
Build your program, put libcurl.dll in the executable folder and it will work.
On Linux it should be a similar process, build the libraries and include them with your source.
You probably want to build a static library out of libcurl and link agains it. Should be pretty straightforward and the process is almost identical on every OS.

Something like .dll on Linux - how to get them?

I have program using gtkmm, gtkglextmm and exiv2.
I want to include these libraries with the executable, because the app will not work if user doesn't has them on his/her system. On Windows .dll files solved the matter (I put them in the same directory as output file).
How to attached similar libraries on Linux? Is there any tool helping with that? I cannot force user to install dependencies.
Standard practice on Linux is not to redistribute your dependencies. Doing so just creates large amounts of duplication. You should instead specify the dependencies in your installation package and let the package manager resolve them.
Better yet, use the package system of the distribution[s] you want to target, e.g. .deb packaging on Debian/Ubuntu/Mint (with aptitude or apt-get, themselves using dpkg), Yum/Rpm on Redhat/Fedora, etc etc.
DLL-s are called shared libraries (files named *.so) on Linux (in ELF format, use objdump, nm ... to explore them, and gcc -fPIC -shared to build them). They can be programmatically loaded with dlopen & dlsym. Beware that there are important differences between windows DLL-s & Linux *.so (dynamic linking don't have the same meaning on Windows & Linux)
You can write simple sh script to start your program:
#!/bin/sh
LD_LIBRARY_PATH=/path/to/intall/directory
path/to/your/exe
and put so libraries to /path/to/intall/directory

How can I find libraries to load them dynamically with dlopen

In the project I am working on, we provide the possibility to dynamically load additional features. For that we use dlopen.
To find this libraries we have something we call module path. There we have a default path, where the shared libraries are (a lot of them are shipped).
At the moment we have two default paths: we first look in the build directory for the shared library and afterwards in the install directory. This is because it should also be possible to run the application without installing it (so in that case it needs to look first in the build directory).
Now the problem ist, if a user builds the application from source and installs it with make install, the libraries in her build directory are loaded by default. This will result in a crash. So it only works if the user afterwards removes or renames the build directory.
No the question: is there a trick (either by C++ or by the build system) to know whether the application is installed or not. The problem is, that the functionality is implemented in a shared library and the implemented way to search for modules has to work also for other applications that link against our library (so we can not rely on the path of the executable). We use CMake as a build system.
To make the situation even harder, the solution has to work on Windows, Linux and Mac OS X.
EDIT:
I further investigated and the problem is more complicated. This is the situation:
There is a small executable a
Furthermore there is a "main" library main.so
then there is a dynamically loaded library lib.so
lib.so links against main.so
The problem is, that lib.so has the absolute path to main.so in the build directory in its rpath. Thanks to the tip of #MSalters I now was able to make a hack to make sure to load the correct version of lib.so (the one in the install directory) but since it has the build path in the rpath it loads the wrong main.so (so in fact there are two copies of main.so in the memory - this messes things up).
Is there a way to remove this reference to the build path from the library? I tried all options of cmake related to rpath without success
Can't you check where the executable itself is? If it's in the build directories, use build libraries -- if it's in the install, use install?
getcwd() has equivalents on all of those platforms, but it might not be what you want -- it depends on how you run the executable.
To get the process's location is system specific, I think, but it shouldn't be too hard to wrap that.
The installed version should not have the build directory in the rpath.
You might want to do the linking twice (once for the build version and once for the installed version). Usually, on *nix systems, the installed binary has some static path where it tries to find plugins. You might define some environment variable (or command-line argument) to overload it for the build execution (and use a wrapper script to set it in the build environment).
Check how it is solved by some projects (Firefox for example).
I don't know much about windows system but I think the standard way of doing this is to search plugins in the same directory as the executable.