diff --git a/Mk/Features/debuginfo.mk b/Mk/Features/debuginfo.mk new file mode 100644 --- /dev/null +++ b/Mk/Features/debuginfo.mk @@ -0,0 +1,33 @@ +# DEBUGINFO Support +# +# Add WITH_DEBUGINFO=yes into make.conf: +# - If set, the port will be compiled in the release mode but with debugging +# info generated. The debugging info is then extract from binaries and put +# into a separate subpackage called debuginfo. +# - If used in conjunction with WITH_DEBUG the port will be compiled in the +# debug mode. + +.if !defined(_DEBUGINFO_MK_INCLUDED) +_DEBUGINFO_MK_INCLUDED= yes +DEBUGINFO_Include_MAINTAINER= portmgr@FreeBSD.org + +# We need to do everything that Features/debug.mk does, but without setting +# WITH_DEBUG to prevent build systems from building in the complete debug mode. +# instead let them detect WITH_DEBUGINFO and build what meson calls "debugoptimized" +# and CMake calls "RelWithDebInfo". +. if !defined(WITH_DEBUG) +. include "debug.mk" +. endif + +SUBPACKAGES+= debuginfo +DESCR.debuginfo= ${WRKDIR}/descr.debuginfo +DEBUGINFO_EXTRACT_ENV+= PREFIX=${PREFIX} STAGEDIR=${STAGEDIR} TMPPLIST=${TMPPLIST} + +_FEATURES_stage= 751:debuginfo-extract + +debuginfo-extract: + @${ECHO_CMD} "Debugging symbols for the ${PKGNAME} package > ${DESCR.debuginfo} + @${ECHO_CMD} "====> Extracting debugging symbols from binaries" + @${SETENV} ${DEBUGINFO_EXTRACT_ENV} ${SH} ${SCRIPTSDIR}/debuginfo-extract.sh + +.endif diff --git a/Mk/Scripts/debuginfo-extract.sh b/Mk/Scripts/debuginfo-extract.sh new file mode 100644 --- /dev/null +++ b/Mk/Scripts/debuginfo-extract.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# +# MAINTAINER: portmgr@FreeBSD.org + +set -o pipefail + +if [ -z "${PREFIX}" -o -z "${STAGEDIR}" -o -z "${TMPPLIST}" ]; then + echo "PREFIX, STAGEDIR and TMPPLIST are required in environment." >&2 + exit 1 +fi + +[ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_DEBUGINFO_EXTRACT}" ] && set -x + +cd "${STAGEDIR}" || exit 1 + +find . -type f | while read -r f; do + brandelf "${f}" > /dev/null 2>&1 || continue + + debug_dir=$(dirname "${f}")/.debug + f_basename=$(basename "${f}") + debug_f="${debug_dir}/${f_basename}.debug" + + mkdir -p "$debug_dir" + objcopy --only-keep-debug "${f}" ${debug_f} + strip --strip-debug --strip-unneeded "${f}" + echo "@@debuginfo@@${debug_f}" | sed -e "s|@@.${PREFIX}/|@@|" -e "s|@@.${PREFIX}|@@|" -e "s|@@./|@@/|" >> ${TMPPLIST} + objcopy --add-gnu-debuglink="${debug_f}" "${f}" +done diff --git a/Mk/Scripts/qa.sh b/Mk/Scripts/qa.sh --- a/Mk/Scripts/qa.sh +++ b/Mk/Scripts/qa.sh @@ -732,6 +732,8 @@ [ -z "${f}" ] && continue # Ignore symlinks [ -f "${f}" -a ! -L "${f}" ] || continue + # Ignore .debug files + [ "${f}" == "${f%.debug}" ] || continue if ! readelf -d ${f} | grep SONAME > /dev/null; then warn "${f} doesn't have a SONAME." warn "pkg(8) will not register it as being provided by the port." diff --git a/Mk/Uses/cmake.mk b/Mk/Uses/cmake.mk --- a/Mk/Uses/cmake.mk +++ b/Mk/Uses/cmake.mk @@ -70,13 +70,15 @@ . if defined(WITH_DEBUG) CMAKE_BUILD_TYPE?= Debug +. elif defined(WITH_DEBUGINFO) +CMAKE_BUILD_TYPE?= RelWithDebInfo . else CMAKE_BUILD_TYPE?= Release . endif #defined(WITH_DEBUG) PLIST_SUB+= CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:tl}" -. if defined(STRIP) && ${STRIP} != "" && !defined(WITH_DEBUG) +. if defined(STRIP) && ${STRIP} != "" && !defined(WITH_DEBUG) && !defined(WITH_DEBUGINFO) INSTALL_TARGET?= install/strip . endif diff --git a/Mk/Uses/meson.mk b/Mk/Uses/meson.mk --- a/Mk/Uses/meson.mk +++ b/Mk/Uses/meson.mk @@ -53,6 +53,8 @@ # should we have strip separate from WITH_DEBUG? . if defined(WITH_DEBUG) CONFIGURE_ARGS+= --buildtype debug +. elif defined(WITH_DEBUGINFO) +CONFIGURE_ARGS+= --buildtype debugoptimized . else CONFIGURE_ARGS+= --buildtype release \ --optimization plain \ diff --git a/Mk/bsd.port.mk b/Mk/bsd.port.mk --- a/Mk/bsd.port.mk +++ b/Mk/bsd.port.mk @@ -1016,7 +1016,7 @@ # These need to be absolute since we don't know how deep in the ports # tree we are and thus can't go relative. They can, of course, be overridden # by individual Makefiles or local system make configuration. -_LIST_OF_WITH_FEATURES= bind_now debug lto pie relro sanitize ssp +_LIST_OF_WITH_FEATURES= bind_now debug debuginfo lto pie relro sanitize ssp _DEFAULT_WITH_FEATURES= ssp PORTSDIR?= /usr/ports LOCALBASE?= /usr/local @@ -2654,7 +2654,7 @@ ${v}.${sp}?= ${$v}.${sp} . endfor _PKGMESSAGES.${sp}= ${PKGMESSAGE}.${sp} -. if !exists(${DESCR.${sp}}) +. if !exists(${DESCR.${sp}}) && ${sp} != debuginfo DESCR.${sp}= ${DESCR} DEV_WARNING+= "DESCR.${sp} needs to point to an existing file." . endif @@ -5480,7 +5480,7 @@ 900:add-plist-info 910:add-plist-docs 920:add-plist-examples \ 930:add-plist-data 940:add-plist-post ${POST_PLIST:C/^/990:/} \ ${_OPTIONS_install} ${_USES_install} \ - ${_OPTIONS_stage} ${_USES_stage} + ${_OPTIONS_stage} ${_USES_stage} ${_FEATURES_stage} . if defined(DEVELOPER) _STAGE_SEQ+= 995:stage-qa . else