I have a C++ project that uses libtools. When libtool builds a program, it places the binary in a subdirectory (.libs), and places a wrapper script with the same name in the build directory, like this:
project/
+- libtool
+- build/
+- a.out <<< this is a script, not a binary
+- .libs/
+- a.out
+- lt-a.out
In order to debug a libtool program from the command line, you need to invoke:
../libtool --mode=execute gdb a.out
However, it is impossible to debug build/a.out directly, because it is not a binary. I found that I can debug the program inside vscode, if I point the launch configuration to the .libs/a.out file, like so:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [ {
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/.libs/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/build",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
Is there a way to invoke the binary through the libtool wrapper?
Is there any advantage to doing so?
To debug a libtool program with vscode, you need a wrapper script that shuffles the command line used to launch the debugger, and make a few changes to the launch.json configuration.
Here is a wrapper script I use (
vscode-lt-launch.sh):The script should be copied into the project's root directory. The LD_LIBRARY_PATH setting should not be necessary, is a hack I don't know how to eliminate. Without it, the executable run by gdb is linked against the system libraries, rather than the staged libraries. If you know how to remove it, I'd appreciate a comment below.
The vscode
launch.jsonwill need a configuration similar to the following, as documented in the wrapper script:If libtool is needed to build and test your app before installation, it's needed to run the app in its uninstalled state.
Is there an advantage to using the libtool wrapper? This question is a bit like asking if there is an advantage to using a compiler to build your app, or a debugger to debug it.
Sometimes people don't know what function libtool has, and add it to the project "just in case", but without using its functions, so it's not uncommon for a project built with libtool to link and execute just fine by calling the binary directly (src/.lib/myprogram or such), especially for small projects without dependencies.
If the program depends on other libraries which are installed in a staging area, libtool will ensure that it runs against the staging area libs, even if libs with the same name are installed on the system. Eg. if you are testing changes to a common system library like libc or libresolv or such, you'd be staging your built libc/libresolv, then build/test the application against the staged lib, instead of the system-installed lib. You'd only install your improved libc once you're done testing it in isolation. Until then, the wrapper that libtool generates (eg, "src/myprogram") contains the right linking info so it can execute against the staged libraries.
libtool is essential to running the debugged app in the staging environment it was built against, but if the program is simple and only depends on libraries which are already installed on the system, libtool may not be needed in the project to begin with.