# Split debug symbols for pkgsrc builds In this diary it will be discussed the Google Summer of Code 2016 experience in splitting the debug symbols for pkgsrc builds. You can read the original proposal of the GSoC at the following URL: ## A quick introduction to ELF and how debug information are stored/stripped off In order to become familiar with ELF format a good starting point are `Object file' and `Executable and Linkable Format' pages from Wikipedia, the free encyclopedia, respectively available at the following URLs: Trying to describe ELF format is not easy in short terms so, for the most curious readers it is strongly suggested to read the nice article series written by Eric Youngdale for Linux Journal: `The ELF Object File Format: Introduction', available here: and `The ELF Object File Format by Dissection', available here: After reading the above resources we have just learned that every programs and libraries in NetBSD (and several other Unix-like operating systems) uses the ELF format. There are four types of ELF object files: * executable * relocatable * shared * core For more information regarding them please give a look to elf(5). We are interested to understand what happens when we compile the programs/libraries with debugging options (basically the `-g' option). NetBSD already supports everything out of the box and so we can quickly start looking at it just writing a simple Makefile and a program that will print the lyrics of the famous `Ten Green Bottles' song! To avoid all the hassle of providing (multiple times!) the right flags to the compiler and manually invoke the right tool we can just write a very simple Makefile that will do everything for us: $ cat green-bottles/Makefile # $NetBSD$ NOMAN= # defined PROG= green-bottles .include Now that we have the Makefile we can start writing the green-bottles PROGram (please note that all the green bottles accidentally fall were properly recycled during the writing of this article): $ cat green-bottles/green-bottles.c #include void sing_green_bottles(int n) { const char *numbers[] = { "no more", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; if ((1 <= n) && (n <= 10)) { printf("%s green bottle%s hanging on the wall\n", numbers[n], n > 1 ? "s" : ""); printf("%s green bottle%s hanging on the wall\n", numbers[n], n > 1 ? "s" : ""); printf("and if %s green bottle should accidentally fall,\n", n > 2 ? "one" : "that"); printf("there'll be %s green bottles hanging on the wall.\n", numbers[n - 1]); } return; } /* * Sing the famous `Ten Green Bottles' song. */ int main(void) { int i; for (i = 10; i > 0; i--) { sing_green_bottles(i); } return 0; } OK! Now everything is ready and if we just invoke make(1) we'll build the program. However, we would like to inspect what's happening behind the scenes, so we'll look at each steps. Please note that right now it is not important that you'll understand everything because we'll look at what make(1) magic do in more details later. First, we compile the C program to generate the `relocatable' object file, i.e. `green-bottles.o': $ cd green-bottles/ $ make green-bottles.o # compile green-bottles/green-bottles.o gcc -O2 -fPIE -std=gnu99 -Werror -c green-bottles.c ctfconvert -g -L VERSION green-bottles.o Let's see what file(1) says regarding it: $ file green-bottles.o green-bottles.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped In order to get more information we can use readelf(1) tool provided by the binutils (GNU binary utilities), e.g. via `readelf -h' (the `-h' option is used to just print the file headers, if you would like to get more information you can use the `-a' option instead): $ readelf -h green-bottles.o ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 2816 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 17 Section header string table index: 13 We can see the 17 sections always via readelf (`-S' option). Now let's recompile it but via the debugging options turned on: $ make green-bottles.o MKDEBUG=yes # compile green-bottles/green-bottles.o gcc -O2 -fPIE -g -std=gnu99 -Werror -c green-bottles.c ctfconvert -g -L VERSION -g green-bottles.o If we are careful we can see that unlike the previous make incantation now the `-g' option is passed to the compiler... Let's see if we can inspect that via readelf: $ readelf -h green-bottles.o ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 6424 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 64 (bytes) Number of section headers: 29 Section header string table index: 25 We can note several differences compared to the previous relocatable file compiled without `MKDEBUG': * Start of section headers (previously 2816, now 6424) * Number of section headers (previously 17, now 29) * Section header string table index (previously 13, now 25) If we compare the sections between the two relocatable files (tips: using: readelf -WS green-bottles.o | sed -nEe 's/^ \[ *([0-9]+)\] ([^ ]*) .*/\2/p' is a possible way to do it) we can observe the following new ELF sections: * .debug_info: contains main DWARF DIEs (Debugging Information Entry) * .debug_abbrev: contains abbreviations used in `.debug_info' section * .debug_loc: contains location expressions * .debug_aranges: contains a table for lookup by addresses of program entities (i.e. data objects, types, functions) * .debug_ranges: contains address ranges referenced by DIEs * .debug_line: contains line number program * .debug_str: contains all strings referenced by `.debug_info' * other .rela.debug_* It's time to finally build the program: $ make green-bottles rm -f .gdbinit touch .gdbinit # link green-bottles/green-bottles gcc -pie -shared-libgcc -o green-bottles green-bottles.o -Wl,-rpath-link,/lib -L=/lib ctfmerge -t -g -L VERSION -o green-bottles green-bottles.o We can observe: $ readelf -h green-bottles ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x730 Start of program headers: 64 (bytes into file) Start of section headers: 6448 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 7 Size of section headers: 64 (bytes) Number of section headers: 31 Section header string table index: 27 ...and for its counterpart compiled via `MKDEBUG=yes': $ readelf -h green-bottles ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x730 Start of program headers: 64 (bytes into file) Start of section headers: 8304 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 7 Size of section headers: 64 (bytes) Number of section headers: 38 Section header string table index: 34 Not so surprisingly the number of the 7 extra sections are exactly the `.debug_*' ones! Now that it's clear the difference between the program compiled with/without `-g' option let's see what happen when the debug symbols are stripped off the program: $ make green-bottles.debug MKDEBUG=yes # create green-bottles/green-bottles.debug ( objcopy --only-keep-debug green-bottles green-bottles.debug && objcopy --strip-debug -p -R .gnu_debuglink --add-gnu-debuglink=green-bottles.debug green-bottles ) || (rm -f green-bottles.debug; false) Let's quickly look them via file(1): $ file green-bottles green-bottles.debug green-bottles: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /usr/libexec/ld.elf_so, for NetBSD 7.99.29, not stripped green-bottles.debug: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter *empty*, for NetBSD 7.99.29, not stripped Using readelf we can note that now green-bottles has 32 sections and green-bottles.debug has 38 sections. green-bottles has one extra section that was added by the objcopy incantation, let's see it: $ readelf -x '.gnu_debuglink' green-bottles Hex dump of section '.gnu_debuglink': 0x00000000 67726565 6e2d626f 74746c65 732e6465 green-bottles.de 0x00000010 62756700 90b06f1c bug...o. The `.gnu_debuglink' section contain the basename(3) of the `.debug' file and its CRC32. The `.gnu_debuglink' section is used to properly pick the correct `.debug' file from the DEBUGDIR directory (we'll see how it will work later when we will invoke the GNU debugger). Regarding the sections in the `.debug' all of them are preserved but several have no data, we can check that by invoking: $ readelf `seq -f '-x %g' 0 37` green-bottles.debug $ readelf `seq -f '-x %g' 0 31` green-bottles ...and comparing their respective output. Now that everything should be clearer we can just try to invoke it through gdb and see what happens: $ gdb ./green-bottles GNU gdb (GDB) 7.10.1 Copyright (C) 2015 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64--netbsd". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./green-bottles...Reading symbols from /tmp/green-bottles/green-bottles.debug...done. done. (gdb) b main Breakpoint 1 at 0xac0: file green-bottles.c, line 29. (gdb) b sing_green_bottles Breakpoint 2 at 0x940: file green-bottles.c, line 5. (gdb) run Starting program: /tmp/green-bottles/green-bottles Breakpoint 1, main () at green-bottles.c:29 29 { (gdb) n 32 for (i = 10; i > 0; i--) { (gdb) n 33 sing_green_bottles(i); (gdb) print i $1 = 10 (gdb) cont Continuing. Breakpoint 2, sing_green_bottles (n=10) at green-bottles.c:5 5 { (gdb) bt #0 sing_green_bottles (n=10) at green-bottles.c:5 #1 0x00000000b7802ad7 in main () at green-bottles.c:33 [... we can now looks and debug it as we wish! ...] So we can see that the `green-bottles.debug' file is loaded from the same directory where green-bottles program was present (in our case `/tmp/green-bottles/' but if a corresponding file `.debug' is not found gdb look for it in the DEBUGDIR, i.e. `/usr/libdata/debug'; e.g. for /usr/bin/yes it will look for debug symbols in `/usr/libdata/debug//usr/bin/yes.debug'). This is the same for all other programs and libraries. ## MKDEBUG and MKDEBUGLIB NetBSD already provide MKDEBUG and MKDEBUGLIB mk.conf variables to achieve the separation of the debug symbols. They respectively split symbols from programs and libraries. The implementation to do that is in src/share/mk/bsd.prog.mk (for programs) and src/share/mk/bsd.lib.mk (for libraries). Several global variables used are defined in src/share/mk/bsd.own.mk. ### bsd.prog.mk In bsd.prog.mk:58 if MKDEBUG is defined and not "no" [sic] the `-g' flag is added to CFLAGS. In bsd.prog.mk:310 the internal `__progdebuginstall' make target is defined to install the `.debug' files for the respective program. It is then called from bsd.prog.mk:589 and bsd.prog.mk:604 (respectively for MKUPDATE == "no" and MKUPDATE != "no", please note the dependency operators "!" vs ":" for the two cases). In bsd.prog.mk:437 _PROGDEBUG.${_P} is defined as ${PROGNAME.${_P}}.debug, inside a for loop. ${_P} is just an element of the ${PROGS} and ${PROGS_CXX} lists. E.g.: for src/bin/echo `echo' is the PROG value. bsd.prog.mk turns single-program PROG and PROG_CXX variable into the multi-word PROGS and PROGS_CXX variables. In bsd.prog.mk:545 there is the most important part. After checking if _PROGDEBUG.${_P} is defined a ${_PROGDEBUG.${_P}} target is defined and ${OBJCOPY} is invoked two times. In the first incantation the ${_PROGDEBUG.${_P}} file (containing the strip debug symbols) is generated for ${_P}. The second incantation is needed to get rid of (now no more needed) debug symbols from ${_P} and `--add-gnu-debuglink' add a `.gnu_debuglink' section to ${_P} containing the filename of the ${_PROGDEBUG.${_P}}; e.g. for `echo' it will be `echo.debug' (plus the CRC32 of `echo.debug' - padded as needed). Regarding other options used by ${OBJCOPY} we should note the `-p' option needed to preserve dates and `-R' is added in order to be sure to update the `.gnu_debuglink' section. For a gentler introduction and to understand why these steps are needed please read `(gdb.info)Separate Debug Files'. ### bsd.lib.mk The logic and objcopy(1) incantation are similar to the ones used in bsd.prog.mk. The most interesting part is in bsd.lib.mk:622. Apart the `*.debug' files if MKDEBUGLIB is defined and not "no" [sic] also `*_g.a' archives are created for the respective libraries archives (although they are stored directly in the several `lib/' directories not in `/usr/libdata/debug/'). ### bsd.own.mk In bsd.own.mk various DEBUG* variables are defined: * DEBUGDIR: where `*.debug' files are stored. Please notice that this is also the place where debugging symbols are looked (for more information please give a look to objcopy(1)) * DEBUGGRP: the `-g' option passed to install(1) for installing debug symbols * DEBUGOWN: the `-o' option passed to install(1) for installing debug symbols * DEBUGMODE: the `-m' option passed to install(1) for installing debug symbols ## Related works ### dpkg The `Debian Developer's Reference' written by the `Developer's Reference Team' has a `Best practices for debug packages' (section 6.7.9, available here: ). The logic used is more or less the same of the one used by src/share/mk in NetBSD and described above. After a quick inspection of `dh_strip' (part of `debhelper', available here: ) some interesting ideas to look further is: * the file(1) logic used in testfile() subroutine * handling of non-C/C++ programming languages: OCaml native code shared libraries (`*.cmxs') and nodejs binaries (`*.node') ### RPM The `Fedora Project Wiki' contains some interesting tips, in particular regarding most common issues that happens in stripping debugging symbols. The `Packaging:Debuginfo' page is available here: . Some of the logic is handled in `find-debuginfo.sh' (available here: ). Another interesting resource is the `Releases/FeatureBuildId' page, available here: The page discusses what Red Hat have done regarding using the `.note.gnu.build-id' section and why have done them. (Yet another) interesting idea adopted by Fedora developers is the `Features/MiniDebugInfo', available here: More information regarding MiniDebugInfo are also present in `(gdb.info)MiniDebugInfo'. Please note that this is not completely related to stripping debugging symbols (indeed the `MiniDebugInfo' is directly stored in program/library!) but can be considered in order to provide better `.core' (both in the pkgsrc and NetBSD cases). Mark J. Wielaard presented in FOSDEM 2016 a talk that summarizes many of the thematics discussed in this diary. Abstract, video recording and more resources are available in the FOSDEM website: Apart his talk a very interesting reading is his blog post regarding the talk: In the blog post there are a lot of interesting information, all worth to be taken in consideration for the pkgsrc case. ## Possible issues In this section we will discuss possible well-known issues that may (or not) worth to be addressed. ### Limitations of `.gnu_debuglink' and hard-coded DEBUGDIR `.gnu_debuglink' section only stores the filename of the `.debug' file (despite how objcopy(1) is invoked; `--add-gnu-debuglink' just needs that the `.debug' file passed as a parameter should exists, the complete path is just ignored and not stored in the `.gnu_debuglink' section). Apart that DEBUGDIR is currently hard-coded in several places and so debug symbols are only looked in `/usr/libdata/debug/' (at least for NetBSD, this can be different for other platforms supported by pkgsrc, so more tricky!). A possible work-around to this problem is to just store the `.debug' files in the ${PREFIX}. E.g. for a `foo' package that just install a program in `${PREFIX}/bin/foo' store its stripped debug symbols in `${PREFIX}/bin/foo.debug'. This will work out of the box without any modifications. However, it would be much better to have a `${PREFIX}/libdata/debug/' hierarchy similar to the one used by NetBSD. While at run-time - inside gdb - the user can set the `debug-file-directory' option using a PATH-like `:' separated paths, e.g.: (gdb) set debug-file-directory /usr/libdata/debug:/usr/pkg/libdata/debug will work. Probably a better way to really fix this behaviour is to add the ability to honor paths in `.gnu_debuglink' ELF section. ### Use of non-standard WRKOBJDIR If non-standard WRKOBJDIR is used should we use `-fdebug-prefix-map='? ## Digging in the pkgsrc/mk source code pkgsrc is a pretty complex system and exploring how things works can reveal to be a difficult task. `The pkgsrc Guide' documents pretty well it but in some cases, for a deeper inspection it isn't enough. In this section we'll try to illustrate some methods to better figure out what's happen under the hood. ### pkgsrc phases and targets To better understand what's happening when we `make build' or `make install' a package we should remember what we do as a MAINTAINERs when we write a Makefile for a pkgsrc package: `.include "../../mk/bsd.pkg.mk"'! mk/bsd.pkg.mk is probably the most important makefile present in pkgsrc/mk. _ALL_PHASES variable in bsd.makevars.mk contain the most important phases. Other interesting variables are _*_TARGETS defined in the several `.mk' files. A possible way to see what's going on is to invoke make(1) `-d m', e.g.: $ make -d m update ## MULTI_PACKAGES/sub-packages ### Related works #### OpenBSD ports OpenBSD ports is documented in bsd.port.mk(5) man page (also available here: ) and in `OpenBSD Porter's Handbook' (available here: ). In OpenBSD ports every multi-package start with a "-", e.g. for the `frobnitz' package there can be `-foo', `-bar', `-baz' (and so `frobnitz-foo', `frobnitz-bar' and `frobnitz-baz' sub-packages). These are specified via MULTI_PACKAGES variable (please not confuse that with FLAVORs, that are more similar to pkgsrc's PKG_OPTIONS!). Several variables can/should/must be defined also for the several sub-packages, i.e.: $ cat Makefile [...] COMMENT-foo= fooish (core) frobnitz COMMENT-bar= barish frobnitz COMMENT-baz= bazish frobnitz V= 1.2.3 DISTNAME= frobnitz-$V CATEGORIES= local PKGNAME-foo= frobnitz-foo-$V PKGNAME-bar= frobnitz-bar-$V PKGNAME-baz= frobnitz-baz-$V [...] MULTI_PACKAGES= -foo -bar -baz [...] The same applies to PLIST and DESCR (e.g. there will be PLIST-foo, PLIST-bar, PLIST-baz and DESCR-foo, DESCR-bar, DESCR-baz). PSEUDO_FLAVORS is used if the user would prefer to *not* build/install particular subpackages, e.g.: PSEUDO_FLAVORS= no_bar no_baz (foo is essential and core part of frobnitz). #### RPM Some information regarding RPM subpackages is available in `RPM Guide' (available here: ) ### Sketch of a possible pkgsrc implementation (MAINTAINERs POV) First we need a bit of nomenclature for the multi-packages functionality. In several ways, from users and MAINTAINERs POV this can be similar to PKG_OPTIONS. With SUBPACKAGES we can define all the possible subpackages permitted/generated from the pkgbase, e.g.: SUBPACKAGES= foo bar baz All PKG_SUBPACKAGES will then be built. To (optionally) selectively build only a subset of PKG_SUBPACKAGES PKG_OPTIONS can be reused, (e.g. imaginary options.mk fragment): PKG_OPTIONS_VAR= PKG_OPTIONS.frobozz PKG_SUPPORTED_OPTIONS= bar baz PKG_SUGGESTED_OPTIONS= bar baz .include "../../mk/bsd.options.mk" # # bar support # .if !empty(PKG_OPTIONS:Mbar) CONFIGURE_ARGS+= --enable-bar BUILDLINK_DEPENDS.bar+= bar . include "../../local/bar/buildlink3.mk" .else CONFIGURE_ARGS+= --disable-bar .endif # # baz support # .if !empty(PKG_OPTIONS:Mbaz) CONFIGURE_ARGS+= --enable-baz BUILDLINK_DEPENDS.baz+= baz . include "../../local/baz/buildlink3.mk" .else CONFIGURE_ARGS+= --disable-baz .endif The above Makefile fragment will probably need further brainstorming, see later. To properly include bl3 proposed a `BUILDLINK_DEPENDS.' syntax with the following semantic: * BUILDLINK_DEPENDS. undefined means: will just have the same DEPENDS/BUILD_DEPENDS of the package (its "parent"). * BUILDLINK_DEPENDS. defined means: only include the BUILDLINK_TREEs defined (can also be empty if the subpackage does not need any of them) To accomplish that BUILDLINK_TREE will need to be properly expanded per subpackage. proposed `LIMIT_DEPENDS. = ' syntax. Under the hoods probably it will be similar to the syntax proposed by so it will need some thought to which one we need to stick when one of these twos will be implemented. After discussing with and probably the `-debug' packages will need to DEPENDS also to other `-debug' dependencies of their non-debug packages. According a cursory research both RPM and dpkg do not seem to add `-debug' dependencies to other `-debug' packages. Probably both delegate that to other external tools; e.g. kindly pointed out to the following one for RPM: #### per-subpackage VARIABLES/files Here an incomplete list of per-subpackage VARIABLES and files. ##### per-subpackage VARIABLES o PKGNAME o DEPENDS o COMMENT o CATEGORIES o BROKEN_EXCEPT_ON_PLATFORM o ONLY_FOR_PLATFORM o BROKEN_ON_PLATFORM o NOT_FOR_PLATFORM o INSTALL_FILE o DEINSTALL_FILE o MAKE_DIRS o OWN_DIRS o MAKE_DIRS_PERMS o OWN_DIRS_PERMS o CONF_FILES o REQD_FILES o CONF_FILES_PERMS o REQD_FILES_PERMS o PKG_SYSCONF* [XXX: maybe?] o RCD_SCRIPTS [XXX: maybe?] o PKG_USERS o PKG_GROUPS o USERGROUP_PHASE o INSTALLATION_DIRS o BROKEN In order to find all files that will need to be changed/adjusted or at least inspected the following textproc/the_silver_searcher incantation can be useful (in `mk'): $ ag -ls 'PKGNAME|DEPENDS|COMMENT|CATEGORIES|BROKEN_EXCEPT_ON_PLATFORM|ONLY_FOR_PLATFORM|BROKEN_ON_PLATFORM|NOT_FOR_PLATFORM|INSTALL_FILE|DEINSTALL_FILE|MAKE_DIRS|OWN_DIRS|MAKE_DIRS_PERMS|OWN_DIRS_PERMS|CONF_FILES|REQD_FILES|CONF_FILES_PERMS|REQD_FILES_PERMS|PKG_SYSCONF.*|RCD_SCRIPTS|PKG_USERS|PKG_GROUPS|USERGROUP_PHASE|INSTALLATION_DIRS|BROKEN' ##### per-subpackage files o DESCR o PLIST o INSTALL o DEINSTALL o MESSAGE o ALTERNATIVES [XXX: maybe?] ### How to proceed for implementing SUBPACKAGES support (pkgsrc infrastructure POV) The most important part that will need to be adjusted for SUBPACKAGES support is `mk/pkgformat/${PKG_FORMAT}/*' hirerchy. To find places where _pkgformat targets (outside pkgformat/!) are used (in `mk'): $ ag --ignore pkgformat '_pkgformat-' ...can be pretty useful and will give an idea how binary packages are handled. #### Exploring mk/pkgformat/${PKG_FORMAT}/* hirerchy A good way to dig in mk/pkgformat/${PKG_FORMAT}/* hirerchy is to start reading pkgformat.mk and then proceeds to the relevant files included by it. ##### depends.mk Probably we will need per-subpackages _{,R,RR}DEPENDS_FILEs, plus per-SUBPACKAGES BUILD_DEPENDS, TOOL_DEPENDS and DEPENDS (probably also other pieces left?). ##### check.mk check.mk defines _pkgformat-check-vulnerable target. Lines 22-23 will need to be adopted for the SUBPACKAGES case. ##### metadata.mk metadata.mk generate all meta-data needed for ${PKG_FORMAT} binary package. All _METADATA_TARGETS need to be per-subpackages and so they will need a major adjustment for the SUBPACKAGES case. ##### install.mk Probably no changes will be needed here. ##### deinstall.mk Probably no changes will be needed here. ##### replace.mk _REPLACE_{NEW,OLD}NAME_FILE and several targets will be needed to be per-subpackages. ##### package.mk Variables and targets need carefull inspection and need to be adopted for subpackages support. TODO: continue to write down all the pkgsrc-digging-stream-of-consciousness! TODO: (note to myself: probably writing down "things" help a lot!) ## References ### ELF, DWARF, debugging and related tools; NetBSD's MKDEBUG{,LIB} and related works * The ELF Object File Format: Introduction, Eric Youngdale * The ELF Object File Format by Dissection, Eric Youngdale * Tool Interface Standard (TIS) Executable and Linking Format (ELF) Specification Version 1.2, TIS Committee * DWARF Debugging Information Format Version 4, DWARF Debugging Information Format Committee * Introduction to the DWARF Debugging Format, Michael Eager * Debugging with GDB Tenth Edition for GDB Version 7.10.1, Free Software Foundation, Inc. * Using GNU's GDB Debugger, Peter Jay Salzman * Debian Developer's Reference, Developer's Reference Team * Where are your Symbols, Debuginfo and Sources?, Mark J. Wielaard * make(1) * elf(5) * file(1) * gcc(1) * readelf(1) * objdump(1) * objcopy(1) * gdb(1) * src/share/bsd.README, 1.353 * src/share/bsd.prog.mk, 1.299 * src/share/bsd.lib.mk, 1.367 * src/share/bsd.own.mk, 1.927 ### MULTI_PACKAGES/sub-packages * bsd.port.mk(5), OpenBSD man pages * OpenBSD Porter's Handbook, OpenBSD * RPM Guide, Fedora Projects Contributors