]>
git.ipfire.org Git - pakfire.git/blob - python/pakfire/builder.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
39 import packages
.packager
46 log
= logging
.getLogger("pakfire")
48 from config
import ConfigBuilder
49 from system
import system
50 from constants
import *
52 from errors
import BuildError
, BuildRootLocked
, Error
55 BUILD_LOG_HEADER
= """
57 | _ \ __ _| | __/ _(_)_ __ ___ | |__ _ _(_) | __| | ___ _ __
58 | |_) / _` | |/ / |_| | '__/ _ \ | '_ \| | | | | |/ _` |/ _ \ '__|
59 | __/ (_| | <| _| | | | __/ | |_) | |_| | | | (_| | __/ |
60 |_| \__,_|_|\_\_| |_|_| \___| |_.__/ \__,_|_|_|\__,_|\___|_|
63 Host : %(hostname)s (%(host_arch)s)
68 class BuildEnviron(object):
69 # The version of the kernel this machine is running.
70 kernel_version
= os
.uname()[2]
72 def __init__(self
, pakfire
, filename
=None, distro_name
=None, build_id
=None, logfile
=None, release_build
=True):
73 self
.pakfire
= pakfire
75 # Check if the given pakfire instance is of the correct type.
76 assert isinstance(self
.pakfire
, base
.PakfireBuilder
)
78 # Check if this host can build the requested architecture.
79 if not system
.host_supports_arch(self
.arch
):
80 raise BuildError
, _("Cannot build for %s on this host.") % self
.arch
82 # Save the build id and generate one if no build id was provided.
84 build_id
= "%s" % uuid
.uuid4()
86 self
.build_id
= build_id
89 self
.init_logging(logfile
)
91 # Initialize a cgroup (if supported).
94 # This build is a release build?
95 self
.release_build
= release_build
97 if self
.release_build
:
98 # Disable the local build repository in release mode.
99 self
.pakfire
.repos
.disable_repo("build")
101 # Log information about pakfire and some more information, when we
102 # are running in release mode.
104 "host_arch" : system
.arch
,
105 "hostname" : system
.hostname
,
106 "time" : time
.strftime("%a, %d %b %Y %H:%M:%S +0000", time
.gmtime()),
107 "version" : "Pakfire %s" % PAKFIRE_VERSION
,
110 for line
in BUILD_LOG_HEADER
.splitlines():
111 self
.log
.info(line
% logdata
)
113 # XXX need to make this configureable
115 "enable_loop_devices" : True,
116 "enable_ccache" : True,
117 "enable_icecream" : False,
118 "sign_packages" : False,
119 "buildroot_tmpfs" : False,
121 #self.settings.update(settings)
123 # Try to get the configured host key. If it is available,
124 # we will automatically sign all packages with it.
125 if self
.keyring
.get_host_key(secret
=True):
126 self
.settings
["sign_packages"] = True
128 # Where do we put the result?
129 self
.resultdir
= os
.path
.join(self
.pakfire
.path
, "result")
132 # If we have a plain makefile, we first build a source package and go with that.
134 # Open source package.
135 self
.pkg
= packages
.SourcePackage(self
.pakfire
, None, filename
)
136 assert self
.pkg
, filename
138 # Log the package information.
139 self
.log
.info(_("Package information:"))
140 for line
in self
.pkg
.dump(long=True).splitlines():
141 self
.log
.info(" %s" % line
)
144 # Path where we extract the package and put all the source files.
145 self
.build_dir
= os
.path
.join(self
.path
, "usr/src/packages", self
.pkg
.friendly_name
)
153 # Save the build time.
154 self
.build_time
= time
.time()
156 def setup_signal_handlers(self
):
160 assert not self
.pakfire
.initialized
, "Pakfire has already been initialized"
162 # Mount the directories.
165 # Lock the build environment.
168 # Initialize pakfire instance.
169 self
.pakfire
.initialize()
174 # Setup domain name resolution in chroot.
177 # Extract all needed packages.
182 # Kill all still running processes in the cgroup.
183 self
.cgroup
.kill_and_wait()
185 # Remove cgroup and all parent cgroups if they are empty.
186 self
.cgroup
.migrate_task(self
.cgroup
.root
, os
.getpid())
187 self
.cgroup
.destroy()
189 parent
= self
.cgroup
.parent
191 if not parent
.is_empty(recursive
=True):
195 parent
= parent
.parent
198 util
.orphans_kill(self
.path
)
200 # Shut down pakfire instance.
201 self
.pakfire
.destroy()
203 # Unlock build environment.
206 # Umount the build environment.
215 Proxy method for easy access to the distribution.
217 return self
.pakfire
.distro
222 Proxy method for easy access to the path.
224 return self
.pakfire
.path
229 Inherit architecture from distribution configuration.
231 return self
.pakfire
.distro
.arch
234 def personality(self
):
236 Gets the personality from the distribution configuration.
238 return self
.pakfire
.distro
.personality
243 "build_date" : time
.strftime("%a, %d %b %Y %H:%M:%S +0000", time
.gmtime(self
.build_time
)),
244 "build_host" : socket
.gethostname(),
245 "build_id" : self
.build_id
,
246 "build_time" : self
.build_time
,
252 Shortcut to access the pakfire keyring.
254 return self
.pakfire
.keyring
257 filename
= os
.path
.join(self
.path
, ".lock")
260 self
._lock
= open(filename
, "a+")
265 fcntl
.lockf(self
._lock
.fileno(), fcntl
.LOCK_EX | fcntl
.LOCK_NB
)
267 raise BuildRootLocked
, "Buildroot is locked"
276 def init_cgroup(self
):
278 Initialize cgroup (if the system supports it).
280 if not cgroup
.supported():
284 self
.cgroup
= cgroup
.CGroup("pakfire/builder/%s" % self
.build_id
)
286 # Attach the pakfire-builder process to the parent group.
287 self
.cgroup
.parent
.attach()
289 def init_logging(self
, logfile
):
291 self
.log
= log
.getChild(self
.build_id
)
292 # Propage everything to the root logger that we will see something
294 self
.log
.propagate
= 1
295 self
.log
.setLevel(logging
.INFO
)
297 # Add the given logfile to the logger.
298 h
= logging
.FileHandler(logfile
)
299 self
.log
.addHandler(h
)
301 # Format the log output for the file.
302 f
= logger
.BuildFormatter()
305 # If no logile was given, we use the root logger.
306 self
.log
= logging
.getLogger("pakfire")
308 def copyin(self
, file_out
, file_in
):
309 if file_in
.startswith("/"):
310 file_in
= file_in
[1:]
312 file_in
= self
.chrootPath(file_in
)
314 #if not os.path.exists(file_out):
317 dir_in
= os
.path
.dirname(file_in
)
318 if not os
.path
.exists(dir_in
):
321 self
.log
.debug("%s --> %s" % (file_out
, file_in
))
323 shutil
.copy2(file_out
, file_in
)
325 def copyout(self
, file_in
, file_out
):
326 if file_in
.startswith("/"):
327 file_in
= file_in
[1:]
329 file_in
= self
.chrootPath(file_in
)
331 #if not os.path.exists(file_in):
334 dir_out
= os
.path
.dirname(file_out
)
335 if not os
.path
.exists(dir_out
):
338 self
.log
.debug("%s --> %s" % (file_in
, file_out
))
340 shutil
.copy2(file_in
, file_out
)
342 def copy_result(self
, resultdir
):
343 # XXX should use find_result_packages
345 dir_in
= self
.chrootPath("result")
347 for dir, subdirs
, files
in os
.walk(dir_in
):
348 basename
= os
.path
.basename(dir)
349 dir = dir[len(self
.chrootPath()):]
351 file_in
= os
.path
.join(dir, file)
353 file_out
= os
.path
.join(
359 self
.copyout(file_in
, file_out
)
361 def find_result_packages(self
):
364 for dir, subdirs
, files
in os
.walk(self
.resultdir
):
366 if not file.endswith(".%s" % PACKAGE_EXTENSION
):
369 file = os
.path
.join(dir, file)
374 def extract(self
, requires
=None):
376 Gets a dependency set and extracts all packages
382 # Add neccessary build dependencies.
383 requires
+= BUILD_PACKAGES
385 # If we have ccache enabled, we need to extract it
386 # to the build chroot.
387 if self
.settings
.get("enable_ccache"):
388 requires
.append("ccache")
390 # If we have icecream enabled, we need to extract it
391 # to the build chroot.
392 if self
.settings
.get("enable_icecream"):
393 requires
.append("icecream")
395 # Get build dependencies from source package.
397 for req
in self
.pkg
.requires
:
400 # Install all packages.
401 self
.log
.info(_("Install packages needed for build..."))
402 self
.install(requires
)
404 # Copy the makefile and load source tarballs.
406 self
.pkg
.extract(_("Extracting"), prefix
=self
.build_dir
)
408 def install(self
, requires
, **kwargs
):
410 Install everything that is required in requires.
412 # If we got nothing to do, we quit immediately.
417 "interactive" : False,
421 if not kwargs
.has_key("allow_downgrade"):
422 kwargs
["allow_downgrade"] = True
424 # Install everything.
425 self
.pakfire
.install(requires
, **kwargs
)
427 def chrootPath(self
, *args
):
428 # Remove all leading slashes
431 if arg
.startswith("/"):
436 ret
= os
.path
.join(self
.path
, *args
)
437 ret
= ret
.replace("//", "/")
439 assert ret
.startswith(self
.path
)
443 def populate_dev(self
):
457 # If we need loop devices (which are optional) we create them here.
458 if self
.settings
["enable_loop_devices"]:
459 for i
in range(0, 7):
460 nodes
.append("/dev/loop%d" % i
)
463 # Stat the original node of the host system and copy it to
465 node_stat
= os
.stat(node
)
467 self
._create
_node
(node
, node_stat
.st_mode
, node_stat
.st_rdev
)
469 os
.symlink("/proc/self/fd/0", self
.chrootPath("dev", "stdin"))
470 os
.symlink("/proc/self/fd/1", self
.chrootPath("dev", "stdout"))
471 os
.symlink("/proc/self/fd/2", self
.chrootPath("dev", "stderr"))
472 os
.symlink("/proc/self/fd", self
.chrootPath("dev", "fd"))
476 Add DNS resolution facility to chroot environment by copying
477 /etc/resolv.conf and /etc/hosts.
479 for i
in ("/etc/resolv.conf", "/etc/hosts"):
482 def _create_node(self
, filename
, mode
, device
):
483 self
.log
.debug("Create node: %s (%s)" % (filename
, mode
))
485 filename
= self
.chrootPath(filename
)
487 # Create parent directory if it is missing.
488 dirname
= os
.path
.dirname(filename
)
489 if not os
.path
.exists(dirname
):
492 os
.mknod(filename
, mode
, device
)
495 self
.log
.debug("Destroying environment %s" % self
.path
)
497 if os
.path
.exists(self
.path
):
501 self
.log
.debug("Cleaning environemnt.")
503 # Remove the build directory and buildroot.
504 dirs
= (self
.build_dir
, self
.chrootPath("result"),)
507 if not os
.path
.exists(d
):
514 self
.log
.debug("Mounting environment")
515 for src
, dest
, fs
, options
in self
.mountpoints
:
516 mountpoint
= self
.chrootPath(dest
)
518 options
= "-o %s" % options
520 # Eventually create mountpoint directory
521 if not os
.path
.exists(mountpoint
):
522 os
.makedirs(mountpoint
)
524 self
.execute_root("mount -n -t %s %s %s %s" % (fs
, options
, src
, mountpoint
), shell
=True)
526 def _umountall(self
):
527 self
.log
.debug("Umounting environment")
530 for src
, dest
, fs
, options
in reversed(self
.mountpoints
):
531 dest
= self
.chrootPath(dest
)
533 if not dest
in mountpoints
:
534 mountpoints
.append(dest
)
537 for mp
in mountpoints
:
539 self
.execute_root("umount -n %s" % mp
, shell
=True)
540 except ShellEnvironmentError
:
543 if not os
.path
.ismount(mp
):
544 mountpoints
.remove(mp
)
547 def mountpoints(self
):
550 # Make root as a tmpfs if enabled.
551 if self
.settings
.get("buildroot_tmpfs"):
553 ("pakfire_root", "/", "tmpfs", "defaults"),
557 # src, dest, fs, options
558 ("pakfire_proc", "/proc", "proc", "nosuid,noexec,nodev"),
559 ("/proc/sys", "/proc/sys", "bind", "bind"),
560 ("/proc/sys", "/proc/sys", "bind", "bind,ro,remount"),
561 ("/sys", "/sys", "bind", "bind"),
562 ("/sys", "/sys", "bind", "bind,ro,remount"),
563 ("pakfire_tmpfs", "/dev", "tmpfs", "mode=755,nosuid"),
564 ("/dev/pts", "/dev/pts", "bind", "bind"),
565 ("pakfire_tmpfs", "/run", "tmpfs", "mode=755,nosuid,nodev"),
568 # If selinux is enabled.
569 if os
.path
.exists("/sys/fs/selinux"):
571 ("/sys/fs/selinux", "/sys/fs/selinux", "bind", "bind"),
572 ("/sys/fs/selinux", "/sys/fs/selinux", "bind", "bind,ro,remount"),
575 # If ccache support is requested, we bind mount the cache.
576 if self
.settings
.get("enable_ccache"):
577 # Create ccache cache directory if it does not exist.
578 if not os
.path
.exists(CCACHE_CACHE_DIR
):
579 os
.makedirs(CCACHE_CACHE_DIR
)
582 (CCACHE_CACHE_DIR
, "/var/cache/ccache", "bind", "bind"),
590 # Add HOME manually, because it is occasionally not set
591 # and some builds get in trouble then.
592 "PATH" : "/usr/bin:/bin:/usr/sbin:/sbin",
594 "TERM" : os
.environ
.get("TERM", "vt100"),
598 "LANG" : os
.environ
.setdefault("LANG", "en_US.UTF-8"),
600 # Set the container that we can detect, if we are inside a
602 "container" : "pakfire-builder",
605 # Inherit environment from distro
606 env
.update(self
.pakfire
.distro
.environ
)
608 # Icecream environment settings
609 if self
.settings
.get("enable_icecream", False):
610 # Set the toolchain path
611 if self
.settings
.get("icecream_toolchain", None):
612 env
["ICECC_VERSION"] = self
.settings
.get("icecream_toolchain")
614 # Set preferred host if configured.
615 if self
.settings
.get("icecream_preferred_host", None):
616 env
["ICECC_PREFERRED_HOST"] = \
617 self
.settings
.get("icecream_preferred_host")
619 # Fake UTS_MACHINE, when we cannot use the personality syscall and
620 # if the host architecture is not equal to the target architecture.
621 if not self
.pakfire
.distro
.personality
and \
622 not system
.native_arch
== self
.pakfire
.distro
.arch
:
624 "LD_PRELOAD" : "/usr/lib/libpakfire_preload.so",
625 "UTS_MACHINE" : self
.pakfire
.distro
.arch
,
631 def installed_packages(self
):
633 Returns an iterator over all installed packages in this build environment.
635 # Get the repository of all installed packages.
636 repo
= self
.pakfire
.repos
.get_repo("@system")
638 # Return an iterator over the packages.
641 def write_config(self
):
642 # Cleanup everything in /etc/pakfire.
643 util
.rm(self
.chrootPath(CONFIG_DIR
))
645 for i
in (CONFIG_DIR
, CONFIG_REPOS_DIR
):
646 i
= self
.chrootPath(i
)
647 if not os
.path
.exists(i
):
650 # Write general.conf.
651 f
= open(self
.chrootPath(CONFIG_DIR
, "general.conf"), "w")
654 # Write builder.conf.
655 f
= open(self
.chrootPath(CONFIG_DIR
, "builder.conf"), "w")
656 f
.write(self
.distro
.get_config())
659 # Create pakfire configuration files.
660 for repo
in self
.pakfire
.repos
:
661 conf
= repo
.get_config()
666 filename
= self
.chrootPath(CONFIG_REPOS_DIR
, "%s.repo" % repo
.name
)
667 f
= open(filename
, "w")
668 f
.write("\n".join(conf
))
672 def pkg_makefile(self
):
673 return os
.path
.join(self
.build_dir
, "%s.%s" % (self
.pkg
.name
, MAKEFILE_EXTENSION
))
675 def execute(self
, command
, logger
=None, **kwargs
):
677 Executes the given command in the build chroot.
679 # Environment variables
682 if kwargs
.has_key("env"):
683 env
.update(kwargs
.pop("env"))
685 self
.log
.debug("Environment:")
686 for k
, v
in sorted(env
.items()):
687 self
.log
.debug(" %s=%s" % (k
, v
))
689 # Make every shell to a login shell because we set a lot of
690 # environment things there.
691 command
= ["bash", "--login", "-c", command
]
694 "chroot_path" : self
.chrootPath(),
695 "cgroup" : self
.cgroup
,
698 "personality" : self
.personality
,
704 shellenv
= shell
.ShellExecuteEnvironment(command
, **args
)
709 def execute_root(self
, command
, **kwargs
):
711 Executes the given command outside the build chroot.
713 shellenv
= shell
.ShellExecuteEnvironment(command
, **kwargs
)
718 def build(self
, install_test
=True, prepare
=False):
720 raise BuildError
, _("You cannot run a build when no package was given.")
722 # Search for the package file in build_dir and raise BuildError if it is not present.
723 if not os
.path
.exists(self
.pkg_makefile
):
724 raise BuildError
, _("Could not find makefile in build root: %s") % self
.pkg_makefile
726 # Write pakfire configuration into the chroot.
729 # Create the build command, that is executed in the chroot.
731 "/usr/lib/pakfire/builder",
734 "/%s" % os
.path
.relpath(self
.pkg_makefile
, self
.chrootPath()),
737 "--resultdir=/result",
740 # Check if only the preparation stage should be run.
742 build_command
.append("--prepare")
744 build_command
= " ".join(build_command
)
748 self
.execute(build_command
, logger
=self
.log
)
750 # Perform the install test after the actual build.
751 if install_test
and not prepare
:
754 except ShellEnvironmentError
:
756 self
.log
.error(_("Build failed"))
758 # Catch all other errors.
761 self
.log
.error(_("Build failed."), exc_info
=True)
764 # Don't sign packages in prepare mode.
768 # Sign all built packages with the host key (if available).
771 # Dump package information.
776 # End here in case of an error.
777 raise BuildError
, _("The build command failed. See logfile for details.")
779 def install_test(self
):
780 self
.log
.info(_("Running installation test..."))
782 # Install all packages that were built.
783 self
.install(self
.find_result_packages(),
784 allow_vendorchange
=True, allow_archchange
=True,
785 allow_uninstall
=True, signatures_mode
="disabled")
787 self
.log
.info(_("Installation test succeeded."))
790 def shell(self
, args
=[]):
791 if not util
.cli_is_interactive():
792 self
.log
.warning("Cannot run shell on non-interactive console.")
795 # Install all packages that are needed to run a shell.
796 self
.install(SHELL_PACKAGES
)
798 # XXX need to set CFLAGS here
799 command
= "/usr/sbin/chroot %s %s %s" % \
800 (self
.chrootPath(), SHELL_SCRIPT
, " ".join(args
))
802 # Add personality if we require one
803 if self
.pakfire
.distro
.personality
:
804 command
= "%s %s" % (self
.pakfire
.distro
.personality
, command
)
806 for key
, val
in self
.environ
.items():
807 command
= "%s=\"%s\" " % (key
, val
) + command
809 # Empty the environment
810 command
= "env -i - %s" % command
812 self
.log
.debug("Shell command: %s" % command
)
814 shell
= os
.system(command
)
815 return os
.WEXITSTATUS(shell
)
817 def sign_packages(self
, keyfp
=None):
818 # Do nothing if signing is not requested.
819 if not self
.settings
.get("sign_packages"):
822 # Get key, that should be used for signing.
824 keyfp
= self
.keyring
.get_host_key_id()
826 # Find all files to process.
827 files
= self
.find_result_packages()
829 # Create a progressbar.
830 print _("Signing packages...")
831 p
= util
.make_progress(keyfp
, len(files
))
835 # Update progressbar.
841 pkg
= packages
.open(self
.pakfire
, None, file)
849 print "" # Print an empty line.
854 for file in self
.find_result_packages():
855 pkg
= packages
.open(self
.pakfire
, None, file)
858 # If there are no packages, there is nothing to do.
864 self
.log
.info(_("Dumping package information:"))
866 dump
= pkg
.dump(long=True)
868 for line
in dump
.splitlines():
869 self
.log
.info(" %s" % line
)
870 self
.log
.info("") # Empty line.
873 class Builder(object):
874 def __init__(self
, pakfire
, filename
, resultdir
, **kwargs
):
875 self
.pakfire
= pakfire
877 self
.filename
= filename
879 self
.resultdir
= resultdir
882 self
.pkg
= packages
.Makefile(self
.pakfire
, self
.filename
)
890 return self
.pkg
.buildroot
894 return self
.pakfire
.distro
900 # Get all definitions from the package.
901 environ
.update(self
.pkg
.exports
)
903 # Overwrite some definitions by default values.
904 environ
.update(self
._environ
)
908 def execute(self
, command
, logger
=None, **kwargs
):
910 logger
= logging
.getLogger("pakfire")
912 # Make every shell to a login shell because we set a lot of
913 # environment things there.
914 command
= ["bash", "--login", "-c", command
]
917 "cwd" : "/%s" % LOCAL_TMP_PATH
,
918 "env" : self
.environ
,
920 "personality" : self
.distro
.personality
,
926 shellenv
= shell
.ShellExecuteEnvironment(command
, **args
)
929 except ShellEnvironmentError
:
930 logger
.error("Command exited with an error: %s" % command
)
935 def run_script(self
, script
, *args
):
936 if not script
.startswith("/"):
937 script
= os
.path
.join(SCRIPT_DIR
, script
)
939 assert os
.path
.exists(script
), "Script we should run does not exist: %s" % script
946 # Returns the output of the command, but the output won't get
948 exe
= self
.execute(cmd
, record_output
=True, log_output
=False)
950 # Return the output of the command.
951 if exe
.exitcode
== 0:
954 def create_icecream_toolchain(self
):
957 "icecc --build-native 2>/dev/null",
958 record_output
=True, record_stderr
=False,
959 log_output
=False, log_errors
=False,
962 except ShellEnvironmentError
:
965 for line
in exe
.output
.splitlines():
966 m
= re
.match(r
"^creating ([a-z0-9]+\.tar\.gz)", line
)
968 self
._environ
["ICECC_VERSION"] = "/tmp/%s" % m
.group(1)
970 def create_buildscript(self
, stage
):
971 # Get buildscript from the package.
972 script
= self
.pkg
.get_buildscript(stage
)
974 # Write script to an empty file.
975 f
= tempfile
.NamedTemporaryFile(mode
="w", delete
=False)
976 f
.write("#!/bin/sh\n\n")
979 f
.write("\n%s\n" % script
)
983 # Make the script executable.
984 os
.chmod(f
.name
, 700)
988 def build(self
, stages
=None):
989 # Create buildroot and remove all content if it was existant.
990 util
.rm(self
.buildroot
)
991 os
.makedirs(self
.buildroot
)
993 # Build icecream toolchain if icecream is installed.
994 self
.create_icecream_toolchain()
996 # Process stages in order.
997 for stage
in ("prepare", "build", "test", "install"):
998 # Skip unwanted stages.
999 if stages
and not stage
in stages
:
1003 self
.build_stage(stage
)
1005 # Stop if install stage has not been processed.
1006 if stages
and not "install" in stages
:
1009 # Run post-build stuff.
1010 self
.post_compress_man_pages()
1011 self
.post_remove_static_libs()
1012 self
.post_extract_debuginfo()
1014 # Package the result.
1015 # Make all these little package from the build environment.
1016 log
.info(_("Creating packages:"))
1018 for pkg
in reversed(self
.pkg
.packages
):
1019 packager
= packages
.packager
.BinaryPackager(self
.pakfire
, pkg
,
1020 self
, self
.buildroot
)
1021 pkg
= packager
.run(self
.resultdir
)
1025 def build_stage(self
, stage
):
1026 # Get the buildscript for this stage.
1027 buildscript
= self
.create_buildscript(stage
)
1029 # Execute the buildscript of this stage.
1030 log
.info(_("Running stage %s:") % stage
)
1033 self
.execute(buildscript
)
1036 # Remove the buildscript.
1037 if os
.path
.exists(buildscript
):
1038 os
.unlink(buildscript
)
1040 def post_remove_static_libs(self
):
1041 keep_libs
= self
.pkg
.lexer
.build
.get_var("keep_libraries")
1042 keep_libs
= keep_libs
.split()
1045 self
.execute("%s/remove-static-libs %s %s" % \
1046 (SCRIPT_DIR
, self
.buildroot
, " ".join(keep_libs
)))
1047 except ShellEnvironmentError
, e
:
1048 log
.warning(_("Could not remove static libraries: %s") % e
)
1050 def post_compress_man_pages(self
):
1052 self
.execute("%s/compress-man-pages %s" % (SCRIPT_DIR
, self
.buildroot
))
1053 except ShellEnvironmentError
, e
:
1054 log
.warning(_("Compressing man pages did not complete successfully."))
1056 def post_extract_debuginfo(self
):
1059 # Check if we need to run with strict build-id.
1060 strict_id
= self
.pkg
.lexer
.build
.get_var("debuginfo_strict_build_id", "true")
1061 if strict_id
in ("true", "yes", "1"):
1062 args
.append("--strict-build-id")
1064 args
.append("--buildroot=%s" % self
.pkg
.buildroot
)
1065 args
.append("--sourcedir=%s" % self
.pkg
.sourcedir
)
1067 # Get additional options to pass to script.
1068 options
= self
.pkg
.lexer
.build
.get_var("debuginfo_options", "")
1069 args
+= options
.split()
1072 self
.execute("%s/extract-debuginfo %s %s" % (SCRIPT_DIR
, " ".join(args
), self
.pkg
.buildroot
))
1073 except ShellEnvironmentError
, e
:
1074 log
.error(_("Extracting debuginfo did not complete with success. Aborting build."))
1077 def find_prerequires(self
, scriptlet_file
):
1078 assert os
.path
.exists(scriptlet_file
), "Scriptlet file does not exist: %s" % scriptlet_file
1080 res
= self
.run_script("find-prerequires", scriptlet_file
)
1081 prerequires
= set(res
.splitlines())
1086 if os
.path
.exists(self
.buildroot
):
1087 util
.rm(self
.buildroot
)