[gnome-ostree] build: Move more of build-compile-one into JS code
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-ostree] build: Move more of build-compile-one into JS code
- Date: Wed, 13 Feb 2013 01:10:26 +0000 (UTC)
commit ba6098a9e4cbd716088b02026429d3654914bd4c
Author: Colin Walters <walters verbum org>
Date: Fri Jan 18 18:23:28 2013 -0500
build: Move more of build-compile-one into JS code
Longer term we want to analysis here, etc.
Makefile-ostbuild.am | 1 +
src/ostbuild/js/fileutil.js | 62 +++++++++++++++++
src/ostbuild/js/tasks/task-build.js | 111 ++++++++++++++++++++++++++++++-
src/ostbuild/ostree-build-compile-one | 117 +--------------------------------
4 files changed, 173 insertions(+), 118 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index 24c73ce..ed921e5 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -43,6 +43,7 @@ jsostbuild_DATA= \
src/ostbuild/js/buildutil.js \
src/ostbuild/js/builtin.js \
src/ostbuild/js/config.js \
+ src/ostbuild/js/fileutil.js \
src/ostbuild/js/task.js \
src/ostbuild/js/jsondb.js \
src/ostbuild/js/jsonutil.js \
diff --git a/src/ostbuild/js/fileutil.js b/src/ostbuild/js/fileutil.js
new file mode 100644
index 0000000..fee9ecc
--- /dev/null
+++ b/src/ostbuild/js/fileutil.js
@@ -0,0 +1,62 @@
+// Copyright (C) 2012,2013 Colin Walters <walters verbum org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the
+// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+const GLib = imports.gi.GLib;
+const Gio = imports.gi.Gio;
+
+const Params = imports.params;
+
+function walkDirInternal(dir, matchParams, callback, cancellable, queryStr) {
+ let denum = dir.enumerate_children(queryStr, Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
+ cancellable);
+ let info;
+ let subdirs = [];
+ while ((info = denum.next_file(cancellable)) != null) {
+ let name = info.get_name();
+ let child = dir.get_child(name);
+ let ftype = info.get_file_type();
+
+ if (ftype == Gio.FileType.DIRECTORY) {
+ subdirs.push(child);
+ continue;
+ }
+
+ if (matchParams.nameRegex && matchParams.nameRegex.exec(name) === null)
+ continue;
+ if (matchParams.fileType !== null && matchParams.fileType != info.get_file_type())
+ continue;
+ if (matchParams.contentType != null && matchParams.contentType != info.get_content_type())
+ continue;
+ callback(child, cancellable);
+ }
+
+ denum.close(cancellable);
+
+ for (let i = 0; i < subdirs.length; i++) {
+ walkDirInternal(subdirs[i], matchParams, callback, cancellable, queryStr);
+ }
+}
+
+function walkDir(dir, matchParams, callback, cancellable) {
+ matchParams = Params.parse(matchParams, { nameRegex: null,
+ fileType: null,
+ contentType: null });
+ let queryStr = 'standard::name,standard::type,unix::mode';
+ if (matchParams.contentType)
+ queryStr += ',standard::fast-content-type';
+ walkDirInternal(dir, matchParams, callback, cancellable, queryStr);
+}
diff --git a/src/ostbuild/js/tasks/task-build.js b/src/ostbuild/js/tasks/task-build.js
index c03fd96..8b8706a 100644
--- a/src/ostbuild/js/tasks/task-build.js
+++ b/src/ostbuild/js/tasks/task-build.js
@@ -25,6 +25,7 @@ const GSystem = imports.gi.GSystem;
const Builtin = imports.builtin;
const Task = imports.task;
const JsonDB = imports.jsondb;
+const FileUtil = imports.fileutil;
const ProcUtil = imports.procutil;
const StreamUtil = imports.streamutil;
const JsonUtil = imports.jsonutil;
@@ -37,6 +38,11 @@ const ArgParse = imports.argparse;
const OPT_COMMON_CFLAGS = {'i686': '-O2 -g -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables',
'x86_64': '-O2 -g -m64 -mtune=generic'};
+const DEVEL_DIRS = ['usr/include', 'usr/share/aclocal',
+ 'usr/share/pkgconfig', 'usr/lib/pkgconfig'];
+const DOC_DIRS = ['usr/share/doc', 'usr/share/gtk-doc',
+ 'usr/share/man', 'usr/share/info'];
+
const TaskBuild = new Lang.Class({
Name: "TaskBuild",
Extends: Task.TaskDef,
@@ -281,6 +287,100 @@ const TaskBuild = new Lang.Class({
return cachedata['ostree'];
},
+ _installAndUnlinkRecurse: function(buildResultDir, srcFile, srcInfo, finalResultDir, cancellable) {
+ let relpath = buildResultDir.get_relative_path(srcFile);
+ let destFile;
+ if (relpath === null)
+ destFile = finalResultDir;
+ else
+ destFile = finalResultDir.resolve_relative_path(relpath);
+
+ 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
+ GSystem.file_chmod(srcFile, 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);
+ let info;
+ while ((info = e.next_file(cancellable)) !== null) {
+ let child = e.get_child(info);
+ this._installAndUnlinkRecurse(buildResultDir, child, info, finalResultDir, cancellable);
+ }
+ e.close(cancellable);
+ srcFile.delete(cancellable);
+ } else {
+ GSystem.file_linkcopy(srcFile, destFile, 0, cancellable);
+ GSystem.file_unlink(srcFile, cancellable);
+ }
+ },
+
+ _installAndUnlink: function(buildResultDir, srcFile, finalResultDir, cancellable) {
+ let srcInfo = srcFile.query_info('standard::*,unix::mode', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, cancellable);
+ this._installAndUnlinkRecurse(buildResultDir, srcFile, srcInfo, finalResultDir, cancellable);
+ },
+
+ _processBuildResults: function(component, buildResultDir, finalResultDir, cancellable) {
+ let runtimePath = finalResultDir.get_child('runtime');
+ GSystem.file_ensure_directory(runtimePath, true, cancellable);
+ let develPath = finalResultDir.get_child('devel');
+ GSystem.file_ensure_directory(develPath, true, cancellable);
+ let docPath = finalResultDir.get_child('doc');
+ GSystem.file_ensure_directory(docPath, true, cancellable);
+
+ // First, 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);
+
+ // Python .co files contain timestamps
+ // .la files are generally evil
+ let DELETE_PATTERNS = [{ nameRegex: /\.(py[co])|(la)$/ },
+ { nameRegex: /\.la$/,
+ fileType: Gio.FileType.REGULAR }];
+
+ for (let i = 0; i < DELETE_PATTERNS.length; i++) {
+ let pattern = DELETE_PATTERNS[i];
+ FileUtil.walkDir(buildResultDir, pattern,
+ Lang.bind(this, function(filePath, cancellable) {
+ GSystem.file_unlink(filePath, cancellable);
+ }), cancellable);
+ }
+
+ // Move symbolic links for shared libraries to devel
+ let libdir = buildResultDir.resolve_relative_path('usr/lib');
+ FileUtil.walkDir(libdir, { nameRegex: /\.so$/,
+ fileType: Gio.FileType.SYMBOLIC_LINK },
+ Lang.bind(this, function(filePath, cancellable) {
+ this._installAndUnlink(buildResultDir, filePath, develPath, cancellable);
+ }), cancellable);
+
+ for (let i = 0; i < DEVEL_DIRS.length; i++) {
+ let path = DEVEL_DIRS[i];
+ let oneDevelDir = buildResultDir.resolve_relative_path(path);
+
+ if (oneDevelDir.query_exists(null)) {
+ this._installAndUnlink(buildResultDir, oneDevelDir, develPath, cancellable);
+ }
+ }
+
+ for (let i = 0; i < DOC_DIRS.length; i++) {
+ let path = DOC_DIRS[i];
+ let oneDocDir = buildResultDir.resolve_relative_path(path);
+
+ if (oneDocDir.query_exists(null)) {
+ this._installAndUnlink(buildResultDir, oneDocDir, docPath, cancellable);
+ }
+ }
+
+ this._installAndUnlink(buildResultDir, buildResultDir, runtimePath, cancellable);
+ },
+
_onBuildComplete: function(taskset, success, msg, loop) {
this._currentBuildSucceded = success;
this._currentBuildSuccessMsg = msg;
@@ -290,6 +390,7 @@ const TaskBuild = new Lang.Class({
_buildOneComponent: function(component, architecture, cancellable) {
let basename = component['name'];
+
let prefix = this._snapshot.data['prefix'];
let buildname = Format.vprintf('%s/%s/%s', [prefix, basename, architecture]);
let unixBuildname = buildname.replace(/\//g, '_');
@@ -428,7 +529,13 @@ const TaskBuild = new Lang.Class({
print("Started child process " + context.argv.map(GLib.shell_quote).join(' '));
proc.wait_sync_check(cancellable);
- let recordedMetaPath = componentResultdir.get_child('_ostbuild-meta.json');
+ let finalBuildResultDir = buildWorkdir.get_child('post-results');
+ GSystem.shutil_rm_rf(finalBuildResultDir, cancellable);
+ GSystem.file_ensure_directory(finalBuildResultDir, true, cancellable);
+
+ this._processBuildResults(component, componentResultdir, finalBuildResultDir, cancellable);
+
+ let recordedMetaPath = finalBuildResultDir.get_child('_ostbuild-meta.json');
JsonUtil.writeJsonFileAtomic(recordedMetaPath, expandedComponent, cancellable);
let commitArgs = ['ostree', '--repo=' + this.repo.get_path(),
@@ -450,7 +557,7 @@ const TaskBuild = new Lang.Class({
commitArgs.push('--statoverride=' + statoverridePath.get_path());
}
- ProcUtil.runSync(commitArgs, cancellable, {cwd: componentResultdir,
+ ProcUtil.runSync(commitArgs, cancellable, {cwd: finalBuildResultDir,
logInitiation: true});
if (statoverridePath != null)
GSystem.file_unlink(statoverridePath, cancellable);
diff --git a/src/ostbuild/ostree-build-compile-one b/src/ostbuild/ostree-build-compile-one
index 7651171..08aaf9b 100755
--- a/src/ostbuild/ostree-build-compile-one
+++ b/src/ostbuild/ostree-build-compile-one
@@ -88,8 +88,6 @@ _DEVEL_DIRS = ['usr/include',
'usr/share/pkgconfig',
'usr/lib/pkgconfig']
-tempfiles = []
-
def _has_buildapi_configure_variable(name):
var = '#buildapi-variable-%s' % (name, )
for line in open('configure'):
@@ -218,125 +216,12 @@ def main(args):
run_sync(args, cwd=builddir)
- tempdir = tempfile.mkdtemp(prefix='ostbuild-destdir-%s' % (metadata['name'].replace('/', '_'), ))
- tempfiles.append(tempdir)
- args = ['make', 'install', 'DESTDIR=' + tempdir]
+ args = ['make', 'install', 'DESTDIR=' + ostbuild_resultdir]
run_sync(args, cwd=builddir)
- runtime_path = os.path.join(ostbuild_resultdir, 'runtime')
- devel_path = os.path.join(ostbuild_resultdir, 'devel')
- doc_path = os.path.join(ostbuild_resultdir, 'doc')
- for artifact_type in ['runtime', 'devel', 'doc']:
- resultdir = os.path.join(ostbuild_resultdir, artifact_type)
- if os.path.isdir(resultdir):
- shutil.rmtree(resultdir)
- os.makedirs(resultdir)
-
- # Remove /var from the install - components are required to
- # auto-create these directories on demand.
- varpath = os.path.join(tempdir, 'var')
- if os.path.isdir(varpath):
- shutil.rmtree(varpath)
-
- # Delete all .la files. See:
- # https://bugzilla.gnome.org/show_bug.cgi?id=654013
- libdir = os.path.join(tempdir, 'usr/lib')
- for dirpath, subdirs, files in os.walk(libdir):
- for filename in files:
- path = os.path.join(dirpath, filename)
- if filename.endswith('.la'):
- os.unlink(path)
-
- # Move symbolic links for shared libraries as well
- # as static libraries into /devel.
- if os.path.exists(libdir):
- for filename in os.listdir(libdir):
- path = os.path.join(libdir, filename)
- stbuf = os.lstat(path)
- if not ((filename.endswith('.so')
- and stat.S_ISLNK(stbuf.st_mode))
- or filename.endswith('.a')):
- continue
- dest = os.path.join(devel_path, 'usr/lib', filename)
- _install_and_unlink(path, dest)
-
- for dirname in _DEVEL_DIRS:
- dirpath = os.path.join(tempdir, dirname)
- if os.path.isdir(dirpath):
- dest = os.path.join(devel_path, dirname)
- _install_and_unlink(dirpath, dest)
-
- for dirname in _DOC_DIRS:
- dirpath = os.path.join(tempdir, dirname)
- if os.path.isdir(dirpath):
- dest = os.path.join(doc_path, dirname)
- _install_and_unlink(dirpath, dest)
-
- for filename in os.listdir(tempdir):
- src_path = os.path.join(tempdir, filename)
- dest_path = os.path.join(runtime_path, filename)
- _install_and_unlink(src_path, dest_path)
-
- for tmpname in tempfiles:
- assert os.path.isabs(tmpname)
- if os.path.isdir(tmpname):
- shutil.rmtree(tmpname)
- else:
- try:
- os.unlink(tmpname)
- except OSError, e:
- pass
-
endtime = time.time()
log("Compilation succeeded; %d seconds elapsed" % (int(endtime - starttime),))
log("Results placed in %s" % (ostbuild_resultdir, ))
-def _install_and_unlink(src, dest):
- statsrc = os.lstat(src)
- dirname = os.path.dirname(dest)
- if not os.path.isdir(dirname):
- os.makedirs(dirname)
-
- # Ensure that all installed files are at least rw-rw-r--;
- # we don't support private/hidden files.
- # Directories also need u+x, i.e. they're rwxrw-r--
- if not stat.S_ISLNK(statsrc.st_mode):
- minimal_mode = (stat.S_IRUSR | stat.S_IWUSR |
- stat.S_IRGRP | stat.S_IWGRP |
- stat.S_IROTH)
- if stat.S_ISDIR(statsrc.st_mode):
- minimal_mode |= stat.S_IXUSR
- os.chmod(src, statsrc.st_mode | minimal_mode)
-
- if stat.S_ISDIR(statsrc.st_mode):
- if not os.path.isdir(dest):
- os.mkdir(dest)
- for filename in os.listdir(src):
- src_child = os.path.join(src, filename)
- dest_child = os.path.join(dest, filename)
-
- _install_and_unlink(src_child, dest_child)
- os.rmdir(src)
- else:
- basename = os.path.basename(src)
- ignored = False
- for r in _IGNORE_FILENAME_REGEXPS:
- if r.match(basename):
- ignored = True
- break
- if ignored:
- log("Not installing %s" % (src, ))
- os.unlink(src)
- return
- try:
- os.rename(src, dest)
- except OSError, e:
- if stat.S_ISLNK(statsrc.st_mode):
- linkto = os.readlink(src)
- os.symlink(linkto, dest)
- else:
- shutil.copy2(src, dest)
- os.unlink(src)
-
main(sys.argv[1:])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]