We are compiling a library with CMAKE under Linux which is then installed per default under /opt/mylib and its sources are placed in this folder as well.
When users try to debug with GDB the library sources are not found by GDB automatically.
How can we compile the library that GDB finds sources without specifying anything?
For example the C++ standard library works like that. I can debug an application and I do not have to tell GDB where to find the sources.
Note: This question is not about how to make GDB find the sources (I know how to do this) but how to adapt the CMakeLists.txt and the compile process that it is not necessary to manually specify the source directory in GDB.
You are likely looking for the -fdebug-prefix-map=old=new GCC flag.
From the manual:
When compiling files residing in directory old, record debugging information describing them as if the files resided in directory new instead. This can be used to replace a build-time path with an install-time path in the debug info. It can also be used to change an absolute path to a relative path by using . for new. This can give more reproducible builds, which are location independent, but may require an extra command to tell GDB where to find the source files. See also -ffile-prefix-map.
The "may require an extra command" part applies if you want to debug as-built binaries without installing them. Debugging installed binaries will just work (TM).
Related
I am building the Poco libraries from source code using cmake, following the instructions from the official website, on OSX High Sierra.
From that I get a bunch of files representing the dynamic libraries with extension *.dylib for example libPocoJSON.23.dylib.
However an external application is looking (in the same path locations), apart from the files created with the build, for other files of the library with a similar name such as to the created ones (they are different only for a d appended to the first part of the name). One example of such file is:
libPocoJSONd.23.dylib
I have found that these files are created with the debug build (while the release build creates only the files without the d extension).
How to perform the build of the debug? Should I look for a flag to active in any of the cmake file or it is a complete different source code?
How to perform the build of the debug?
Use cmake -DCMAKE_BUILD_TYPE=Debug
See CMAKE_BUILD_TYPE for details.
I am using a library installed via cmake in Xcode, and I'd like to allow my debugger to step through that library's code while debugging my application.
After building and installing the dependency cmake project, the cmake project that depends on it would then include that one. When it is run I'd like to step through the code of the dependency library with the Xcode debugger.
Is there a way to tell Xcode for my main application where the headers, source and debug built binaries (if necessary) of the library are so I can step through?
I've found a few relevant questions, but none provides straightforward instructions for configuring your library's source to be found in Xcode with support from the GUI.
LLDB equivalent of gdb “directory” command for specifying source search path?
In Xcode, how to debug with external libraries that you have the source for?
Xcode equivalent of Visual Studio's “Find Source”
Here is an example homebrew formula which installs a cmake project and enables the debug symbols. I can come up with an example that uses the library if needed as well.
If you are linking to the debug version of the library into your application, and you haven't moved or deleted the .o files you used to build it or the source files for those .o files, then you shouldn't have to do anything. lldb will pick up from the loader the location of the library's binary, and that will have a "debug map" that points to the .o files (where, on OS X, the actual debug information is stored) which lldb will then read, and the debug information will contain the path to the source files.
So some part of this chain must have gotten broken if you aren't seeing source in Xcode when you stop in some code in your library.
First make sure you really are building the debug version of the library (the compile lines that build the .o files should have -g in them.)
Next, if your make process is deleting the .o files or stripping the library before installing it, then lldb won't be able to trace from the binary to the debug info. The easiest way to fix this is to make a dSYM as part of the build process, using the dsymutil utility, and install the dSYM somewhere lldb can find (next to the library, or in any location Spotlight searches) or add it explicitly with lldb's add-dsym command. Note if the library is getting stripped you need to make the dSYM before it gets stripped.
Finally, if you are moving the source files from where they are when built, then you can use the source-map as described in the first of your links.
I'm having my first fling with the Boost libraries, and I've picked a pretty girl named Regex.
I've installed the libraries (which build automatically?) on my machine, but I'm getting the above error (cannot find -lboost_regex). I'm using Code::Blocks with MinGW, and a C++0X compiler flag.
I have
Pointed the "search directories" to the installation directory
Added the -lboost_regex flag to the linker
but no luck. Can someone help me get this working?
Update
Got things running now. I've added some further notes in an answer below, for newcomers to this problem.
(Also, changed the title of the question since it turned out to be a broader issue than when I started out.)
Here's some links and tips that can help a newcomer, from my first build experience. I built the libraries directly from the zip file. I built on MinGW and I used CodeBlocks for the IDE.
Download Boost zip, unzip somewhere (I'll call that place $boostdir)
Pretty large when unzipped, > 300MB
Add MinGW bin to PATH var
When Boost builds, it will need access to MinGW executables
Build b2.exe and bjam.exe
The documentation for Windows blithely assumes MSVC compiler is available.
If it is, you can apparently use the bootstrap.bat like the docs say.
If it's not (like mine), you'll have to build the exe files yourself, in steps 4 and 5.
In CMD, navigate to $boostdir/tools/build/v2/engine
Run build.bat mingw (will build b2.exe and bjam.exe)
Some aging basic documentation on that
Now you've got b2 and bjam custom-built according to your system spec. Navigate back up to $boostdir and get ready to start building the libraries.
Boost will make a new bin.v2 directory in the current directory.
All the libs will go in bin.v2.
This is an "intermediate" directory, for some reason
Nothing to do in this step, just some extra info :)
Run b2 toolset=gcc --build-type=complete
This takes a long time, in the neighborhood of 1 - 2 hours.
You'll know if it's working. If you think something's wrong, it's not working.
The build can use various flags
Now you're all built. Time to set up CodeBlocks.
Point your compiler to the header files
Right click your project -> Build Options -> Search Directories tab -> Compiler tab -> add $boostdir address
Boost has built a DLL for the library you want according to your current system spec. Look in the stage\lib\ directory of $boostdir
This DLL will be used later in the linker, so don't close its explorer window yet
Mine was in C:\Program Files\Boost_1_52\stage\lib\libboost_regex-mgw44-1_52.dll
I think the documentation had a smart way to do this but I haven't tried it yet
The "intermediate" directory from step #6 can be deleted now that the build is finished
Point your linker to the directory of that DLL
Right click your project -> Build Options -> Search Directories tab -> Linker tab -> add
that directory address (blah\blah\blah\stage\lib\)
Add that DLL flag to your linker settings
Mine was -lboost_regex-mgw44-1_52
Deep breath, prayers to your god, and fire up a test.
Further docs that may either help or confuse:
The Code::Blocks website has a version of this that I didn't find until I neared the end of my search. It was fairly helpful but had a few weird things. This post also is helpful.
Good luck!
I'm not sure what you mean by which build automatically. Most of the Boost libraries are header-only, but a few, such as regex, need to be compiled to a shared / static library. The compilation step is not automatic, you need to invoke the Boost build system (bjam) to do this. Of course, there are sources (BoostPro for instance) that distribute pre-built Boost binaries for various platforms.
Once that's done, you need to add the path where the libraries are present to the linker's search path. For MinGW, this option is -L"path/to/library". Boost does have directives to allow auto-linking of the required libraries, and this seems to work pretty well with MSVC, but I've never gotten it to work with MinGW. So you must also list the libraries to be linked explicitly. The Boost libraries include target and version information in the file name by default, so a typical linker command line option will look like -lboost_regex-mgw47-mt-1_51 for MinGW gcc 4.7 and Boost 1.51
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.
My development shop has put together a fairly useful Python-based test suite, and we'd like to test some Linux-based C++ code with it. We've gotten the test project they ship with Boost to compile (type 'bjam' in the directory and it works), but we're having issues with our actual project.
Building the boost libraries and bjam from source (v1.35.0), when I run bjam I get a .so in the bin/gcc-4.1.2/debug directory. I run python and "import " and I get:
ImportError: libboost_python-gcc41-d-1_35.so.1.35.0: cannot open shared object file: No such file or directory
Looking in the library directory, I have the following:
libboost_python-gcc41-mt-1_35.so libboost_python-gcc41-mt-1_35.so.1.35.0 libboost_python-gcc41-mt.so
Obviously I need the -d instead of the -mt libraries, or to point at the -mt libraries instead of -d, but I can't figure out how to make my Jamroot file do that.
When I install Debian Etch's versions of the libraries, I get "No Jamfile in /usr/include" - and there's a debian bug that says they left out the system-level jamfile.
I'm more hopeful about getting it working from source, so if anyone has any suggestions to resolve the library issues, I'd like to hear them.
Response to answer 1: Thanks for the tip. So, do you know how I'd go about getting it to use the MT libraries instead? It appears to be more of a problem with bjam or the Jamfile I am using thinking I am in debug mode, even though I can't find any flags for that. While I know how to include specific libraries in a call to GCC, I don't see a way to configure that from the Boost end.
If you want to build the debug variants of the boost libraries as well, you have to invoke bjam with the option --build-type=complete.
On Debian, you get the debug Python interpreter in the python2.x-dbg packages. Debug builds of the Boost libraries are in libboost1.xy-dbg, if you want to use the system Boost.
Found the solution! Boost builds a debug build by default. Typing "bjam release" builds the release configuration. (This isn't listed in any documentation anywhere, as far as I can tell.) Note that this is not the same as changing your build-type to release, as that doesn't build a release configuration. Doing a 'complete' build as Torsten suggests also does not stop it from building only a debug version.
It's also worth noting that the -d libraries were in <boost-version>/bin.v2/libs/python/build/<gcc version>/debug/ and the release libraries were in <gcc-version>/release, and not installed into the top-level 'libs' directory.
Thanks for the other suggestions!
One important Point: -d means debug of course, and should only be linked to a debug build of your project and can only be used with a debug build of python (OR NOT, SEE BELOW). If you try to link a debug lib to a non-debug build, or you try to import a debug pyd into a non-debug python, bad things will happen.
mt means multi-threaded and is orthogonal to d. You probably want to use a mt non-d for your project.
I am afraid I don't know how to tell gcc what to link against (I have been using Visual Studio). One thing to try:
man gcc
Somewhere that should tell you how to force specific libs on the linker.
EDIT: Actually you can import a debug version of you project into a non-debug build of python. Wherever you included python.h, include boost/python/detail/wrap_python.hpp instead.