I am trying to make my autotools project in C++ link against library, that originates as C library (libsomelib.so), but also has bindings to c++ (libsomelib++.so). I ma trying to use PKG_CHECK_MODULES to check if this package is installed, and use autotools to link against it. However both libs come in one package (c++ version requires configure flag), and have only one .pc file, in which independently of configuration settings there is only line
Libs: -L${libdir} -lsomelib
without any mentioning of ++ version. There is also no separate ++.pc file that i noticed at other programs. Therefore automatic linking against ++ version is impossible. I thought about manually adding -lsomelib++ to linking flags, but that's rather ugly (and it will not work if somebody compiled it without --with-cxx flag). I could also test for it's existence by AC_SEARCH_LIBS, but since it's C++ library it's not so straightforward.
Is missing ++.pc file mistake of package distributor or is it some deeper idea, and i don't know how to use it?
If somebody is really qurious i will say that package in question is ossp-uuid.
Yes, the missing ++.pc usually hints towards an omission on behalf of the packager.
BTW: If simple (DCE) UUIDs are sufficient, you could consider e2fsprogs/util-linux's libuuid (in case you run this OS).
Related
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.
I'm totally spinning my wheels with getting a couple of 3rd party libraries to work with my c++ programs. I'm looking for some general advice (40,000 foot level) about the general steps that one needs to take when implementing libraries.
First, some specifics: I am using code::blocks in Windows as my IDE. I like this IDE and really don't want to switch to anything else if I don't have to (I've tried visual c++ and also some things in linux). The libraries that I am trying to use are GMP and crypto++.
OK. What I think I know is this: After downloading the library, I unzip the file to a folder. I've been unzipping directly to C:\ with each zip file extracted to its own folder (e.g. c:\cryptopp and c:\gmp). I think that the next step is to build the library, but this is where I get totally stuck. How is this done? There are no executable files among those extracted. From what I can tell, I believe that I do this in code::blocks, but I have no idea how?
Finally, assuming that I can get this done, which I believe creates the .lib files, the last step before actually using the library in my code, is to link into the library. This part, I believe that I understand.
So, my question is broad: do I understand this process overall? And if so, how do I go about building these libraries, if in fact that it the thing that I am missing.
Thanks very much for indulging my ignorance. I'm totally rudderless right now and despite hours and hours on google, I'm making no progress. Also, feel free to correct anything that I have stated as fact that is not correct. Thanks a lot!
Usually libraries have a special file called makefile in them, and are built with a utility called Make (or one of it's variations, whatever works uder windows).
Usually all you have to do is to run Make in the directory where you have unpacked the source files, and it will do the rest itself.
If those libraries you mention (GMP and crypto++; disclaimer: I'm not familiar with either of them) don't have project files for code::blocks then you may still be able to compile them under Windows with MinGW.
If you have installed MinGW you use the MinGW shell to navigate to the appropriate directories which would be /c/cryptopp/ and /c/gmp in your examples - The MinGW shell works like a Unix shell, and has different naming conventions.
Then you need to compile the libraries. Check whether there's a Makefile in those directories, if there isn't you can check whether there's a configure script, which will generate the Makefile. If you have the Makefile you can type make which will compile the libraries with MinGW's port of the GCC compiler.
When the compilation is complete you should have a library in the form of a .a file (say libcryptopp.a) that you can link to your project. In code::blocks you would set the linker path (the -L command line option in GCC) to C:\cryptopp\bin or wherever the library has been compiled, and then add libcryptopp.a to the list of libraries you want to link (this is associated with the -l option in GCC). The convention is to leave out the lib prefix and the .a extension, so you would just add cryptopp to your library list. In the end your linker options should look like -LC:\cryptopp\bin -lcryptopp along with the
Also, to be able to use the libraries you need to add the path to the headers directory to the include path of your project. This is associated to the -I command line option in GCC, so your compiler's command line options would have something like -IC:\cryptopp\include somewhere.
Of course, all of the above assumes that you use code::blocks with GCC. If you're using it with VisualC++ then the principles are the same, but the specific steps differ.
I have just downloaded the boost libraries from the boost website and extracted them to my desktop. I was hoping to just have a quick look at them and have them installed on my machine and perhaps use them in the future when I am more accustomed to C++.
When I extracted it, I was confused with all of the extracted files. There is all of the headers in the boost directory but tutorials mention running bootstrap.bat (I'm using Windows).
So I am asking this: do I simply extract the headers to my compilers include directory like normal to get boost up and running or do I need to do something else?
As I understand it from searching about, apparently "most" of boost is just templates and can be used simply by including the headers, but what about the rest?
Am I totally barking up the wrong tree?
Thanks for any help
Since you mentioned you run Windows, take a look at this automated installer:
► http://www.boostpro.com/download/
Also, some general advice:
do I simply extract the headers to my compilers include directory
No! Do not pollute your compiler's includes with third-party includes; make a separate directory specifically for a particular library. You'll then need to tell your specific IDE in what directory it can find the library headers.
I usually use boostpro's installer, it is less work. I vaguely remember having to set up the BOOST_ROOT environment variable on one of my systems to use it.
The libraries that contained compiled source should be included in the installer.
If you don't use the installer (or don't set up your build correctly), and try to use the libraries that need it you will likely get some linker errors when you try and compile your program. Usually if you take those linker errors and plop them in google it tells you pretty quick which libraries you need to include in your build system. I use CMake for that and have been very happy..
Just add the root boost directory to include paths of your compiler/IDE (so if you have Boost extracted to C:\Boost, the compiler will use that path, not C:\Boost\boost).
Don't do any copying of the boost folder to your compiler's include directory, because it may make upgrading Boost harder in the future.
Also if you plan to use any of boost's compiled libraries, add Boost's lib directory to compiler's library search paths. Configuring the compiling step is a matter of putting the right toolset parameter to boost's build tool. If you have your command line environment configured properly, bootstrap should run and compile the builder without any problems, and the Boost builder should properly detect your toolset, so no parameters will be necessary.
As you do such configuration only once every time you do a clean install of your favorite compiler, it's not as hard or daunting as it seems.
I made a program on Mac OS X using OpenGL and dynamically linking libpng. I'm now trying to port it to Windows. Whenever I try to compile and link my ported program in Borland it gives me this error and about 10 more that are the same, but with a different '_png_create_read_struct':
Error: Unresolved external '_png_create_read_struct' reference from C:\PROGRAMMING\PNGTEST.OBJ
I assume it's because I have not properly set up libpng with Borland C++ 5.5.1 for Win32. I've put png.h and pngconf.h into the include folder into C:\Borland\BCC55\Include, and I have put libpng12.dll.a, libpng13.a, libpng13.dll.a, libpng.a, libpng.dll.a, libpng12.def, libpng.def, libpng12.la, and libpng.la into C:\Borland\BCC55\Lib (there is probably no need for them all, but as a noob I have no idea which ones are needed and not).
Do I need to put a libpng.obj file in there too? And if so how would I make/get one? I have tried using makefile.bc32 to set up libpng, yet that gives me a missing separator error.
Here are my command-line options:
bcc32 -tW pngtest.cpp -lpng
I include png.h in my code. What am I doing wrong or is there an even better way to load images with alpha that doesn't need libpng, or even a better compiler to get for Windows?
You're probably better off with the MinGW compiler than Borland. Borland is not well supported any longer.
You could also download DevC++ and see if it has a libpng package in its addon mechanism.
DevC++ is an IDE that uses the MinGW C/C++ compiler.
That said, if you feel you must use BCC, you'll either have to
a) Build libpng with Borland. This is the best solution if you're going to use borland.
b) Use, I think, Impdef to create an import library from libpng.dll. You'll find impdef.exe or imp(something).exe in the borland bin directory.
Note that some libraries will not work with impdef as there is static code linked to the dll that causes it to fail without the proper runtime.
First of all, I would not have "polluted" the BC55 installation with third-party libraries; it will make moving the project to other build environments much more difficult. It would have been better to place them in a folder within your project.
Secondly do you know that the export library you are attempting to link is built for BC55? The .a extension suggests a GNU library (Borland libraries conventionally use .lib extension), in which case it would not link with BC55 which uses a different object file format. If this is the case you will need to rebuild the library as you attempted to do, so I suggest that you should really be asking a question about the problem you had with doing just that. I wonder whether the makefile is written for Borland make or GNU make, since they have differing syntax?
The command line option -lpng might be correct for GCC (where it will link libpng.a), but is meaningless to BCC. The -l option merely passes the text that follows to the linker. The linker command line, requires that the complete name be passed, and if no extension is provided, .lib is added implicitly.
You should probably just use coff2omf to convert the library. The DLL files are almost certainly in "Microsoft" COFF format.
See COFF2OMF.EXE, the Import Library Conversion Tool.
I have started an C++ SFML project for linux. I was wondering where the .so's should go.
Should they go inside the project folder so a user can simply run the program after they get it? Or should the user have the SFML library installed on there linux machine before they run my program?
Even if you did include the .so files, you have no guarantee that the user will be able to run it (different architecture, libraries linked against different libc, ...). Either link statically, or better yet, just let them provide the supporting libraries themselves.
#Joel J. Adamson's answer to use autoconf is a good idea. SFML doesn't come with a pkg-config file, so you will check for SFML as follows:
dnl Checking for a C++ compiler
AC_PROG_CXX
dnl Checking C++ features. This tells configure to use the C++ compiler for checks.
AC_LANG_PUSH([C++])
dnl Check for a SFML header.
AC_CHECK_HEADER([SFML/Config.hpp], [], [AC_MSG_ERROR([SFML headers not found.])])
AC_LANG_POP([C++])
Checking for the libraries is a bit more difficult because of name mangling and so on. Tyler McHenry wrote a good article on this part, if you want to be thorough.
At the distribution level SFML will be a dependency, i.e. a user will have to install it (or their package manager will have to install it) before compiling your program. If a user wants to compile it, they will also need the header files (often there's a separate "devel" package to install). You shouldn't have to distribute the .so files, and it's probably better (for everybody) if you don't.
You will need to check if the user has it, e.g. using autoconf you need to check for the relevant headers in your configure.ac for the application project. For example, to check for the math library, because I'm using the exp() function, I'll use
AC_CHECK_LIB([m], [exp])
to create a check during the configure step. Luckily autoscan can check this for you and create a skeleton configure.ac file called configure.scan. See also Cmake.
HTH.
You should make your program depend on the specific library (and version) that it needs. If you're planning to package it into an rpm/deb file you should add the dependency there too so that it can be checked and applied by package managers (e.g. apt can install all the dependency packages of a given package)