[CMake] Fwd: Save stripped debugging information

Michael Hertling mhertling at online.de
Sun Oct 2 08:52:01 EDT 2011


On 10/01/2011 01:35 PM, Rolf Eike Beer wrote:
> 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.

With the GNU tools, e.g., there are two approaches to generate debug
files: With objcopy's --only-keep-debug/--add-gnu-debuglink switches
and with build IDs. For the latter, you need to pass the --build-id
switch along with a suitable ID string to the linker, so the debug
files' generation is no pure add-on step anymore. How do you think
that one should parameterize this in order to let the user choose
the objcopy approach or the build-ID approach or both - which is
explicitly permitted - and possibly for each individual target?

In general, one must be prepared that generating debug files

- is an operation of the linker only (Visual approach)
- is a linker-independent operation (objcopy approach)
- is a combination of both (GNU/ELF build-ID approach)

and in the most general case, it could be further influenced by
parameters the user might want to set for each target individually,
i.e. assuming that input/output filenames are the only variable things
appears to be a trifle too short to me. For these reasons, I think that
teaching CMake how to generate debug files - or to recognize them - via
a generator/toolchain-independent interface will prove to be complicated.

Regards,

Michael

>> 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