[CMake] Fwd: Save stripped debugging information

Rolf Eike Beer eike at sf-mail.de
Sat Oct 1 07:35:22 EDT 2011


Am Samstag 01 Oktober 2011, 06:11:44 schrieb Michael Hertling:
> On 09/30/2011 08:39 AM, Rolf Eike Beer wrote:
> >> On 09/29/2011 06:15 AM, Yuri Timenkov wrote:
> >>> When I was investigating similar problem, I found alternative
> >>> approach
> >>> at
> >>> http://code.google.com/p/dynamorio/source/browse/trunk/CMakeLists.tx
> >>> t.
> >>> 
> >>> The thing is to change linker rules, to something like this:
> >>>     set(CMAKE_C_CREATE_SHARED_LIBRARY
> >>>     
> >>>         # standard rule
> >>>         "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS>
> >>> 
> >>> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS>
> >>> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS>
> >>> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> -o <TARGET>
> >>> <OBJECTS>
> >>> <LINK_LIBRARIES>"
> >>> 
> >>>         # now create a .debug copy
> >>>         "${CMAKE_OBJCOPY} --only-keep-debug <TARGET>
> >>>         <TARGET>.debug"
> >>>         # link original to point at .debug copy
> >>>         # directory components are removed, so "../lib/" is
> >>>         fine
> >>>         "${CMAKE_OBJCOPY} --add-gnu-debuglink=<TARGET>.debug
> >>>         <TARGET>"
> >>>         # Strip all information from target binary.
> >>>         "${CMAKE_STRIP} --strip-debug --discard-all
> >>>         --preserve-dates
> >>> 
> >>> <TARGET>"
> >>> 
> >>>     )
> >>> 
> >>> I don't exactly remember benefits from this approach but it kind of
> >>> works.
> >> 
> >> The benefits are that one needs to define these rule variables once as
> >> they're inherited by the subdirectories. The downside is that the rule
> >> variables are used by Makefile generators only, whereas the target-
> >> associated custom commands are a more generic approach.
> >> 
> >>> And I agree that functionality like installing debug symbols in
> >>> install()
> >>> rules out of box would be quite handy.
> >> 
> >> INSTALL() is essentially about copying files and directories, so it
> >> doesn't depend on the toolchain; in particular, you can use INSTALL()
> >> for projects which are configured with PROJECT(... NONE), i.e. without
> >> any toolchain. By contrast, extracting debug symbols does highly
> >> depend
> >> on the toolchain, e.g. the objcopy(1) utility isn't mentioned in
> >> POSIX,
> >> and even with the GNU tools, you have multiple possibilities to
> >> connect
> >> the stripped binary with the unstripped one, note --add-gnu-debuglink
> >> vs. build IDs. Windows and MacOSX will further enrich this entire zoo
> >> of utilities and command line switches, not to mention toolchains for
> >> specific platforms. So, opening and parameterizing INSTALL() - w.r.t.
> >> its interface and its implementation - in order to provide reasonable
> >> support for the extraction of debug symbols during installation is a
> >> major undertaking, IMO, besides the conceptional issue of toolchain-
> >> dependence.
> > 
> > The idea was not to generate those during install, but to be able to let
> > them being installed. For e.g. MSVC you don't have anything to do, the
> > linker will already generate the PDB file already. So all you would have
> > to do would be to copy the generated debug file to the proper place.
> > This
> > whish  comes from the fact that for multi-configuration generators you
> > don't know which configuration is active so you don't know where to
> > search the PDB file. And INSTALL() and ADD_CUSTOM_TARGET()/_COMMAND()
> > don't understand generator expressions.
> 
> INSTALL() doesn't, but ADD_CUSTOM_TARGET/COMMAND() are right the two
> commands which *do* understand generator expressions. As long as you
> know the location of the debug files relative to the location of the
> concerned target's binary, the $<TARGET_FILE_DIR:target> expressions
> should do the trick. So, the worst case you might suffer is that you
> must use a custom target/command to copy or move the debug files to
> a suitable location in order to apply INSTALL(FILES ...) on them in
> the end. IMO, that's bearable; does it not work for you? However,
> adding generator expressions to the INSTALL() command might be
> worth a thought.
> 
> > So my idea would be to generate the debug file during or after the link
> > step and save the position to this file somewhere internally, so
> > INSTALL(... DEBUG_SYMBOLS) would know which to take. Or to do just
> > nothing if we do not support external debug symbols on this platform.
> 
> What do you mean with "save the position to this file somewhere
> internally"? Saving by a user's action, i.e. declaring a file as a
> debug file? If you know the file's name and location, you can simply
> apply INSTALL(FILES ...) on it, perhaps with an intermediate step as
> suggested above. Saving by action of CMake, i.e. without specifying
> the debug file's name and/or location? For this to work, you would
> need to teach CMake to recognize a debug file by itself, and that's
> probably a comparably complicated undertaking as teaching CMake how
> to generate debug files.

I don't see how this is really complicated. You call objcopy with some 
options. The only things that change for each call are the name of the input 
and the one of the output file. The input file is obviously already known, the 
output file is something like inputfilename.debug in the simple case.

You need a toolchain-specific rules for CMake to
-know if the toolchain has support for this at all (or if it is implemented)
-know how to generate the debug symbols file
-know how to find the debug symbols file for any target

So for MSVC this would be { yes, do nothing as the linker already handles this 
for us, replace the extension of the output filename with ".pdb" }. For 
gcc/g++ this would then be { yes, objcopy ... outputfilename 
outputfilename.debug, append ".debug" to output filename }. With this you can 
do INSTALL(... DEBUG_SYMBOLS ...) without much work. You currently have to do 
something similar when you want to install a shared library with it's static 
link library for MSVC. So this can't be all that hard.

> E.g., with a typical *nix toolchain, CMake
> has no chance to know in advance *if* a debug file is generated,
> *where* it is written to and *what* is its name.

You are right, the thing we did was a bunch of INSTALL(... OPTIONAL) and just 
hope it to work right. 

Eike


More information about the CMake mailing list