[gnome-ostree] build: Split debuginfo
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree] build: Split debuginfo
- Date: Tue, 2 Apr 2013 19:02:55 +0000 (UTC)
commit baaeef3242d74dcf46245f2516662dcdfc9ea678
Author: Colin Walters <walters verbum org>
Date: Wed Mar 27 09:30:01 2013 -0400
build: Split debuginfo
This is similar to the Debian/debhelper code, except it hard-requires
objects to contain Build ID.
https://bugzilla.gnome.org/show_bug.cgi?id=695816
src/js/procutil.js | 30 +++++++++++---
src/js/tasks/task-build.js | 92 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 100 insertions(+), 22 deletions(-)
---
diff --git a/src/js/procutil.js b/src/js/procutil.js
index 3c30ab3..12a7519 100644
--- a/src/js/procutil.js
+++ b/src/js/procutil.js
@@ -72,7 +72,9 @@ function runSync(argv, cancellable, params) {
_wait_sync_check_internal(proc, cancellable);
}
-function _runSyncGetOutputInternal(argv, cancellable, params, splitLines) {
+function _runSyncGetOutputInternal(argv, cancellable, params, subParams) {
+ subParams = Params.parse(subParams, { splitLines: false,
+ grep: null });
let [context, pparams] = _newContext(argv, params);
context.set_stdout_disposition(GSystem.SubprocessStreamDisposition.PIPE);
context.set_stderr_disposition(GSystem.SubprocessStreamDisposition.INHERIT);
@@ -83,8 +85,19 @@ function _runSyncGetOutputInternal(argv, cancellable, params, splitLines) {
let input = proc.get_stdout_pipe();
let dataIn = Gio.DataInputStream.new(input);
- let result;
- if (splitLines) {
+ let result = null;
+ if (subParams.grep) {
+ let grep = subParams.grep;
+ while (true) {
+ let [line, len] = dataIn.read_line_utf8(cancellable);
+ if (line == null)
+ break;
+ result = grep.exec(line);
+ if (result != null) {
+ break;
+ }
+ }
+ } else if (subParams.splitLines) {
result = StreamUtil.dataInputStreamReadLines(dataIn, cancellable);
} else {
result = '';
@@ -95,20 +108,21 @@ function _runSyncGetOutputInternal(argv, cancellable, params, splitLines) {
result += (line + '\n');
}
}
+ dataIn.close(cancellable);
_wait_sync_check_internal(proc, cancellable);
return result;
}
function runSyncGetOutputLines(args, cancellable, params) {
- return _runSyncGetOutputInternal(args, cancellable, params, true);
+ return _runSyncGetOutputInternal(args, cancellable, params, { splitLines: true });
}
function runSyncGetOutputUTF8(args, cancellable, params) {
- return _runSyncGetOutputInternal(args, cancellable, params, false);
+ return _runSyncGetOutputInternal(args, cancellable, params);
}
function runSyncGetOutputUTF8Stripped(args, cancellable, params) {
- return _runSyncGetOutputInternal(args, cancellable, params, false).replace(/[ \n]+$/, '');
+ return _runSyncGetOutputInternal(args, cancellable, params).replace(/[ \n]+$/, '');
}
function runSyncGetOutputUTF8StrippedOrNull(args, cancellable, params) {
@@ -124,6 +138,10 @@ function runSyncGetOutputUTF8StrippedOrNull(args, cancellable, params) {
}
}
+function runSyncGetOutputGrep(args, pattern, cancellable, params) {
+ return _runSyncGetOutputInternal(args, cancellable, params, { grep: pattern });
+}
+
function getExitStatusAndString(ecode) {
try {
GLib.spawn_check_exit_status(ecode);
diff --git a/src/js/tasks/task-build.js b/src/js/tasks/task-build.js
index 8740798..a7b6a11 100644
--- a/src/js/tasks/task-build.js
+++ b/src/js/tasks/task-build.js
@@ -299,14 +299,6 @@ const TaskBuild = new Lang.Class({
GSystem.file_ensure_directory(destFile.get_parent(), true, cancellable);
- if (srcInfo.get_file_type() != Gio.FileType.SYMBOLIC_LINK) {
- let minimalMode = 436; // u+rw,g+rw,o+r
- if (srcInfo.get_file_type() == Gio.FileType.DIRECTORY)
- minimalMode |= 64; // u+x
- let mode = srcInfo.get_attribute_uint32('unix::mode');
- GSystem.file_chmod(srcFile, mode | minimalMode, cancellable);
- }
-
if (srcInfo.get_file_type() == Gio.FileType.DIRECTORY) {
GSystem.file_ensure_directory(destFile, true, cancellable);
let e = srcFile.enumerate_children('standard::*,unix::mode',
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, cancellable);
@@ -327,6 +319,50 @@ const TaskBuild = new Lang.Class({
let srcInfo = srcFile.query_info('standard::*,unix::mode', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable);
this._installAndUnlinkRecurse(buildResultDir, srcFile, srcInfo, finalResultDir, cancellable);
},
+
+ _processBuildResultSplitDebuginfo: function(buildResultDir, debugPath, path, cancellable) {
+ let name = path.get_basename();
+ // Only process files ending in .so.* or executables
+ let soRegex = /\.so\./;
+ if (!soRegex.exec(name)) {
+ let finfo = path.query_info('unix::mode', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ cancellable);
+ let mode = finfo.get_attribute_uint32('unix::mode');
+ if (!(mode & 73))
+ return;
+ }
+ let elfSharedRe = /ELF.*shared/;
+ let elfExecRe = /ELF.*executable/;
+ let ftype = ProcUtil.runSyncGetOutputUTF8StrippedOrNull(['file', path.get_path()], cancellable);
+ if (ftype == null)
+ return;
+
+ let isShared = elfSharedRe.test(ftype);
+ let isExec = elfExecRe.test(ftype);
+
+ if (!(isShared || isExec))
+ return;
+
+ let buildIdPattern = /\s+Build ID: ([0-9a-f]+)/;
+ let match = ProcUtil.runSyncGetOutputGrep(['eu-readelf', '-n', path.get_path()], buildIdPattern,
cancellable);
+ if (match == null) {
+ print("WARNING: no build-id for ELF object " + path.get_path());
+ return;
+ }
+ let buildId = match[1];
+ print("ELF object " + path.get_path() + " buildid=" + buildId);
+ let dbgName = buildId[0] + buildId[1] + '/' + buildId.substr(2) + '.debug';
+ let objdebugPath = debugPath.resolve_relative_path('usr/lib/debug/.build-id/' + dbgName);
+ GSystem.file_ensure_directory(objdebugPath.get_parent(), true, cancellable);
+ ProcUtil.runSync(['objcopy', '--only-keep-debug', path.get_path(), objdebugPath.get_path()],
cancellable);
+
+ let stripArgs = ['strip', '--remove-section=.comment', '--remove-section=.note'];
+ if (isShared) {
+ stripArgs.push('--strip-unneeded');
+ }
+ stripArgs.push(path.get_path());
+ ProcUtil.runSync(stripArgs, cancellable);
+ },
_processBuildResults: function(component, buildResultDir, finalResultDir, cancellable) {
let runtimePath = finalResultDir.get_child('runtime');
@@ -335,8 +371,23 @@ const TaskBuild = new Lang.Class({
GSystem.file_ensure_directory(develPath, true, cancellable);
let docPath = finalResultDir.get_child('doc');
GSystem.file_ensure_directory(docPath, true, cancellable);
+ let debugPath = finalResultDir.get_child('debug');
+ GSystem.file_ensure_directory(debugPath, true, cancellable);
+
+ // Change file modes first; some components install files that
+ // are read-only even by the user, which we don't want.
+ FileUtil.walkDir(buildResultDir, {}, Lang.bind(this, function(path, cancellable) {
+ let info = path.query_info("standard::type,unix::mode", Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
cancellable);
+ if (info.get_file_type() != Gio.FileType.SYMBOLIC_LINK) {
+ let minimalMode = 436; // u+rw,g+rw,o+r
+ if (info.get_file_type() == Gio.FileType.DIRECTORY)
+ minimalMode |= 64; // u+x
+ let mode = info.get_attribute_uint32('unix::mode');
+ GSystem.file_chmod(path, mode | minimalMode, cancellable);
+ }
+ }), cancellable);
- // First, remove /var from the install - components are required to
+ // Remove /var from the install - components are required to
// auto-create these directories on demand.
let varPath = buildResultDir.get_child('var');
GSystem.shutil_rm_rf(varPath, cancellable);
@@ -374,6 +425,11 @@ const TaskBuild = new Lang.Class({
}), cancellable);
}
+ FileUtil.walkDir(buildResultDir, { fileType: Gio.FileType.REGULAR },
+ Lang.bind(this, function(filePath, cancellable) {
+ this._processBuildResultSplitDebuginfo(buildResultDir, debugPath, filePath,
cancellable);
+ }), cancellable);
+
for (let i = 0; i < DEVEL_DIRS.length; i++) {
let path = DEVEL_DIRS[i];
let oneDevelDir = buildResultDir.resolve_relative_path(path);
@@ -924,7 +980,7 @@ const TaskBuild = new Lang.Class({
}
let targetsList = [];
- let componentTypes = ['runtime', 'devel'];
+ let componentTypes = ['runtime', 'runtime-debug', 'devel', 'devel-debug'];
for (let i = 0; i < componentTypes.length; i++) {
let targetComponentType = componentTypes[i];
for (let i = 0; i < architectures.length; i++) {
@@ -933,20 +989,20 @@ const TaskBuild = new Lang.Class({
targetsList.push(target);
target['name'] = 'buildmaster/' + architecture + '-' + targetComponentType;
- let runtimeRef = baseName + '/' + architecture + '-runtime';
+ let baseRuntimeRef = baseName + '/' + architecture + '-runtime';
let buildrootRef = baseName + '/' + architecture + '-devel';
let baseRef;
if (targetComponentType == 'runtime') {
- baseRef = runtimeRef;
+ baseRef = baseRuntimeRef;
} else {
baseRef = buildrootRef;
}
target['base'] = {'name': baseRef,
- 'runtime': runtimeRef,
+ 'runtime': baseRuntimeRef,
'devel': buildrootRef};
let targetComponents;
- if (targetComponentType == 'runtime') {
+ if (targetComponentType.indexOf('runtime-') == 0) {
targetComponents = runtimeComponents;
} else {
targetComponents = develComponents;
@@ -966,8 +1022,12 @@ const TaskBuild = new Lang.Class({
let componentRef = {'name': binaryName};
if (targetComponentType == 'runtime') {
componentRef['trees'] = ['/runtime'];
- } else {
+ } else if (targetComponentType == 'runtime-debug') {
+ componentRef['trees'] = ['/runtime', '/debug'];
+ } else if (targetComponentType == 'devel') {
componentRef['trees'] = ['/runtime', '/devel', '/doc']
+ } else if (targetComponentType == 'devel-debug') {
+ componentRef['trees'] = ['/runtime', '/devel', '/doc', '/debug'];
}
contents.push(componentRef);
}
@@ -1001,7 +1061,7 @@ const TaskBuild = new Lang.Class({
// Now loop over the other targets per architecture, reusing
// the initramfs cached from -devel generation.
- let nonDevelTargets = ['runtime'];
+ let nonDevelTargets = ['runtime', 'runtime-debug', 'devel-debug'];
for (let i = 0; i < nonDevelTargets.length; i++) {
let target = nonDevelTargets[i];
for (let j = 0; j < architectures.length; j++) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]