]>
git.ipfire.org Git - people/stevee/pakfire.git/blob - python/pakfire/builder.py
e821757149d3ff23223e2b2619e902ec490ca54f
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
)
115 "enable_loop_devices" : self
.config
.get_bool("builder", "use_loop_devices", True),
116 "enable_ccache" : self
.config
.get_bool("builder", "use_ccache", True),
117 "enable_icecream" : self
.config
.get_bool("builder", "use_icecream", False),
118 "sign_packages" : False,
119 "buildroot_tmpfs" : self
.config
.get_bool("builder", "use_tmpfs", False),
122 # Try to get the configured host key. If it is available,
123 # we will automatically sign all packages with it.
124 if self
.keyring
.get_host_key(secret
=True):
125 self
.settings
["sign_packages"] = True
127 # Where do we put the result?
128 self
.resultdir
= os
.path
.join(self
.pakfire
.path
, "result")
131 # If we have a plain makefile, we first build a source package and go with that.
133 # Open source package.
134 self
.pkg
= packages
.SourcePackage(self
.pakfire
, None, filename
)
135 assert self
.pkg
, filename
137 # Log the package information.
138 self
.log
.info(_("Package information:"))
139 for line
in self
.pkg
.dump(long=True).splitlines():
140 self
.log
.info(" %s" % line
)
143 # Path where we extract the package and put all the source files.
144 self
.build_dir
= os
.path
.join(self
.path
, "usr/src/packages", self
.pkg
.friendly_name
)
152 # Save the build time.
153 self
.build_time
= time
.time()
155 def setup_signal_handlers(self
):
159 assert not self
.pakfire
.initialized
, "Pakfire has already been initialized"
161 # Mount the directories.
164 # Lock the build environment.
167 # Initialize pakfire instance.
168 self
.pakfire
.initialize()
173 # Setup domain name resolution in chroot.
176 # Extract all needed packages.
181 # Kill all still running processes in the cgroup.
182 self
.cgroup
.kill_and_wait()
184 # Remove cgroup and all parent cgroups if they are empty.
185 self
.cgroup
.migrate_task(self
.cgroup
.root
, os
.getpid())
186 self
.cgroup
.destroy()
188 parent
= self
.cgroup
.parent
190 if not parent
.is_empty(recursive
=True):
194 parent
= parent
.parent
197 util
.orphans_kill(self
.path
)
199 # Shut down pakfire instance.
200 self
.pakfire
.destroy()
202 # Unlock build environment.
205 # Umount the build environment.
214 Proxy method for easy access to the configuration.
216 return self
.pakfire
.config
221 Proxy method for easy access to the distribution.
223 return self
.pakfire
.distro
228 Proxy method for easy access to the path.
230 return self
.pakfire
.path
235 Inherit architecture from distribution configuration.
237 return self
.pakfire
.distro
.arch
240 def personality(self
):
242 Gets the personality from the distribution configuration.
244 return self
.pakfire
.distro
.personality
249 "build_date" : time
.strftime("%a, %d %b %Y %H:%M:%S +0000", time
.gmtime(self
.build_time
)),
250 "build_host" : socket
.gethostname(),
251 "build_id" : self
.build_id
,
252 "build_time" : self
.build_time
,
258 Shortcut to access the pakfire keyring.
260 return self
.pakfire
.keyring
263 filename
= os
.path
.join(self
.path
, ".lock")
266 self
._lock
= open(filename
, "a+")
271 fcntl
.lockf(self
._lock
.fileno(), fcntl
.LOCK_EX | fcntl
.LOCK_NB
)
273 raise BuildRootLocked
, "Buildroot is locked"
282 def init_cgroup(self
):
284 Initialize cgroup (if the system supports it).
286 if not cgroup
.supported():
290 self
.cgroup
= cgroup
.CGroup("pakfire/builder/%s" % self
.build_id
)
292 # Attach the pakfire-builder process to the parent group.
293 self
.cgroup
.parent
.attach()
295 def init_logging(self
, logfile
):
297 self
.log
= log
.getChild(self
.build_id
)
298 # Propage everything to the root logger that we will see something
300 self
.log
.propagate
= 1
301 self
.log
.setLevel(logging
.INFO
)
303 # Add the given logfile to the logger.
304 h
= logging
.FileHandler(logfile
)
305 self
.log
.addHandler(h
)
307 # Format the log output for the file.
308 f
= logger
.BuildFormatter()
311 # If no logile was given, we use the root logger.
312 self
.log
= logging
.getLogger("pakfire")
314 def copyin(self
, file_out
, file_in
):
315 if file_in
.startswith("/"):
316 file_in
= file_in
[1:]
318 file_in
= self
.chrootPath(file_in
)
320 #if not os.path.exists(file_out):
323 dir_in
= os
.path
.dirname(file_in
)
324 if not os
.path
.exists(dir_in
):
327 self
.log
.debug("%s --> %s" % (file_out
, file_in
))
329 shutil
.copy2(file_out
, file_in
)
331 def copyout(self
, file_in
, file_out
):
332 if file_in
.startswith("/"):
333 file_in
= file_in
[1:]
335 file_in
= self
.chrootPath(file_in
)
337 #if not os.path.exists(file_in):
340 dir_out
= os
.path
.dirname(file_out
)
341 if not os
.path
.exists(dir_out
):
344 self
.log
.debug("%s --> %s" % (file_in
, file_out
))
346 shutil
.copy2(file_in
, file_out
)
348 def copy_result(self
, resultdir
):
349 # XXX should use find_result_packages
351 dir_in
= self
.chrootPath("result")
353 for dir, subdirs
, files
in os
.walk(dir_in
):
354 basename
= os
.path
.basename(dir)
355 dir = dir[len(self
.chrootPath()):]
357 file_in
= os
.path
.join(dir, file)
359 file_out
= os
.path
.join(
365 self
.copyout(file_in
, file_out
)
367 def find_result_packages(self
):
370 for dir, subdirs
, files
in os
.walk(self
.resultdir
):
372 if not file.endswith(".%s" % PACKAGE_EXTENSION
):
375 file = os
.path
.join(dir, file)
380 def extract(self
, requires
=None):
382 Gets a dependency set and extracts all packages
388 # Add neccessary build dependencies.
389 requires
+= BUILD_PACKAGES
391 # If we have ccache enabled, we need to extract it
392 # to the build chroot.
393 if self
.settings
.get("enable_ccache"):
394 requires
.append("ccache")
396 # If we have icecream enabled, we need to extract it
397 # to the build chroot.
398 if self
.settings
.get("enable_icecream"):
399 requires
.append("icecream")
401 # Get build dependencies from source package.
403 for req
in self
.pkg
.requires
:
406 # Install all packages.
407 self
.log
.info(_("Install packages needed for build..."))
408 self
.install(requires
)
410 # Copy the makefile and load source tarballs.
412 self
.pkg
.extract(_("Extracting"), prefix
=self
.build_dir
)
414 # Add an empty line at the end.
417 def install(self
, requires
, **kwargs
):
419 Install everything that is required in requires.
421 # If we got nothing to do, we quit immediately.
426 "interactive" : False,
430 if not kwargs
.has_key("allow_downgrade"):
431 kwargs
["allow_downgrade"] = True
433 # Install everything.
434 self
.pakfire
.install(requires
, **kwargs
)
436 def chrootPath(self
, *args
):
437 # Remove all leading slashes
440 if arg
.startswith("/"):
445 ret
= os
.path
.join(self
.path
, *args
)
446 ret
= ret
.replace("//", "/")
448 assert ret
.startswith(self
.path
)
452 def populate_dev(self
):
466 # If we need loop devices (which are optional) we create them here.
467 if self
.settings
["enable_loop_devices"]:
468 for i
in range(0, 7):
469 nodes
.append("/dev/loop%d" % i
)
472 # Stat the original node of the host system and copy it to
474 node_stat
= os
.stat(node
)
476 self
._create
_node
(node
, node_stat
.st_mode
, node_stat
.st_rdev
)
478 os
.symlink("/proc/self/fd/0", self
.chrootPath("dev", "stdin"))
479 os
.symlink("/proc/self/fd/1", self
.chrootPath("dev", "stdout"))
480 os
.symlink("/proc/self/fd/2", self
.chrootPath("dev", "stderr"))
481 os
.symlink("/proc/self/fd", self
.chrootPath("dev", "fd"))
485 Add DNS resolution facility to chroot environment by copying
486 /etc/resolv.conf and /etc/hosts.
488 for i
in ("/etc/resolv.conf", "/etc/hosts"):
491 def _create_node(self
, filename
, mode
, device
):
492 self
.log
.debug("Create node: %s (%s)" % (filename
, mode
))
494 filename
= self
.chrootPath(filename
)
496 # Create parent directory if it is missing.
497 dirname
= os
.path
.dirname(filename
)
498 if not os
.path
.exists(dirname
):
501 os
.mknod(filename
, mode
, device
)
504 self
.log
.debug("Destroying environment %s" % self
.path
)
506 if os
.path
.exists(self
.path
):
510 self
.log
.debug("Cleaning environemnt.")
512 # Remove the build directory and buildroot.
513 dirs
= (self
.build_dir
, self
.chrootPath("result"),)
516 if not os
.path
.exists(d
):
523 self
.log
.debug("Mounting environment")
524 for src
, dest
, fs
, options
in self
.mountpoints
:
525 mountpoint
= self
.chrootPath(dest
)
527 options
= "-o %s" % options
529 # Eventually create mountpoint directory
530 if not os
.path
.exists(mountpoint
):
531 os
.makedirs(mountpoint
)
533 self
.execute_root("mount -n -t %s %s %s %s" % (fs
, options
, src
, mountpoint
), shell
=True)
535 def _umountall(self
):
536 self
.log
.debug("Umounting environment")
539 for src
, dest
, fs
, options
in reversed(self
.mountpoints
):
540 dest
= self
.chrootPath(dest
)
542 if not dest
in mountpoints
:
543 mountpoints
.append(dest
)
546 for mp
in mountpoints
:
548 self
.execute_root("umount -n %s" % mp
, shell
=True)
549 except ShellEnvironmentError
:
552 if not os
.path
.ismount(mp
):
553 mountpoints
.remove(mp
)
556 def mountpoints(self
):
559 # Make root as a tmpfs if enabled.
560 if self
.settings
.get("buildroot_tmpfs"):
562 ("pakfire_root", "/", "tmpfs", "defaults"),
566 # src, dest, fs, options
567 ("pakfire_proc", "/proc", "proc", "nosuid,noexec,nodev"),
568 ("/proc/sys", "/proc/sys", "bind", "bind"),
569 ("/proc/sys", "/proc/sys", "bind", "bind,ro,remount"),
570 ("/sys", "/sys", "bind", "bind"),
571 ("/sys", "/sys", "bind", "bind,ro,remount"),
572 ("pakfire_tmpfs", "/dev", "tmpfs", "mode=755,nosuid"),
573 ("/dev/pts", "/dev/pts", "bind", "bind"),
574 ("pakfire_tmpfs", "/run", "tmpfs", "mode=755,nosuid,nodev"),
577 # If selinux is enabled.
578 if os
.path
.exists("/sys/fs/selinux"):
580 ("/sys/fs/selinux", "/sys/fs/selinux", "bind", "bind"),
581 ("/sys/fs/selinux", "/sys/fs/selinux", "bind", "bind,ro,remount"),
584 # If ccache support is requested, we bind mount the cache.
585 if self
.settings
.get("enable_ccache"):
586 # Create ccache cache directory if it does not exist.
587 if not os
.path
.exists(CCACHE_CACHE_DIR
):
588 os
.makedirs(CCACHE_CACHE_DIR
)
591 (CCACHE_CACHE_DIR
, "/var/cache/ccache", "bind", "bind"),
599 # Add HOME manually, because it is occasionally not set
600 # and some builds get in trouble then.
601 "PATH" : "/usr/bin:/bin:/usr/sbin:/sbin",
603 "TERM" : os
.environ
.get("TERM", "vt100"),
607 "LANG" : os
.environ
.setdefault("LANG", "en_US.UTF-8"),
609 # Set the container that we can detect, if we are inside a
611 "container" : "pakfire-builder",
614 # Inherit environment from distro
615 env
.update(self
.pakfire
.distro
.environ
)
617 # Icecream environment settings
618 if self
.settings
.get("enable_icecream", False):
619 # Set the toolchain path
620 if self
.settings
.get("icecream_toolchain", None):
621 env
["ICECC_VERSION"] = self
.settings
.get("icecream_toolchain")
623 # Set preferred host if configured.
624 if self
.settings
.get("icecream_preferred_host", None):
625 env
["ICECC_PREFERRED_HOST"] = \
626 self
.settings
.get("icecream_preferred_host")
628 # Fake UTS_MACHINE, when we cannot use the personality syscall and
629 # if the host architecture is not equal to the target architecture.
630 if not self
.pakfire
.distro
.personality
and \
631 not system
.native_arch
== self
.pakfire
.distro
.arch
:
633 "LD_PRELOAD" : "/usr/lib/libpakfire_preload.so",
634 "UTS_MACHINE" : self
.pakfire
.distro
.arch
,
640 def installed_packages(self
):
642 Returns an iterator over all installed packages in this build environment.
644 # Get the repository of all installed packages.
645 repo
= self
.pakfire
.repos
.get_repo("@system")
647 # Return an iterator over the packages.
650 def write_config(self
):
651 # Cleanup everything in /etc/pakfire.
652 util
.rm(self
.chrootPath(CONFIG_DIR
))
654 for i
in (CONFIG_DIR
, CONFIG_REPOS_DIR
):
655 i
= self
.chrootPath(i
)
656 if not os
.path
.exists(i
):
659 # Write general.conf.
660 f
= open(self
.chrootPath(CONFIG_DIR
, "general.conf"), "w")
663 # Write builder.conf.
664 f
= open(self
.chrootPath(CONFIG_DIR
, "builder.conf"), "w")
665 f
.write(self
.distro
.get_config())
668 # Create pakfire configuration files.
669 for repo
in self
.pakfire
.repos
:
670 conf
= repo
.get_config()
675 filename
= self
.chrootPath(CONFIG_REPOS_DIR
, "%s.repo" % repo
.name
)
676 f
= open(filename
, "w")
677 f
.write("\n".join(conf
))
681 def pkg_makefile(self
):
682 return os
.path
.join(self
.build_dir
, "%s.%s" % (self
.pkg
.name
, MAKEFILE_EXTENSION
))
684 def execute(self
, command
, logger
=None, **kwargs
):
686 Executes the given command in the build chroot.
688 # Environment variables
691 if kwargs
.has_key("env"):
692 env
.update(kwargs
.pop("env"))
694 self
.log
.debug("Environment:")
695 for k
, v
in sorted(env
.items()):
696 self
.log
.debug(" %s=%s" % (k
, v
))
698 # Make every shell to a login shell because we set a lot of
699 # environment things there.
700 command
= ["bash", "--login", "-c", command
]
703 "chroot_path" : self
.chrootPath(),
704 "cgroup" : self
.cgroup
,
707 "personality" : self
.personality
,
713 shellenv
= shell
.ShellExecuteEnvironment(command
, **args
)
718 def execute_root(self
, command
, **kwargs
):
720 Executes the given command outside the build chroot.
722 shellenv
= shell
.ShellExecuteEnvironment(command
, **kwargs
)
727 def build(self
, install_test
=True, prepare
=False):
729 raise BuildError
, _("You cannot run a build when no package was given.")
731 # Search for the package file in build_dir and raise BuildError if it is not present.
732 if not os
.path
.exists(self
.pkg_makefile
):
733 raise BuildError
, _("Could not find makefile in build root: %s") % self
.pkg_makefile
735 # Write pakfire configuration into the chroot.
738 # Create the build command, that is executed in the chroot.
740 "/usr/lib/pakfire/builder",
743 "/%s" % os
.path
.relpath(self
.pkg_makefile
, self
.chrootPath()),
746 "--resultdir=/result",
749 # Check if only the preparation stage should be run.
751 build_command
.append("--prepare")
753 build_command
= " ".join(build_command
)
757 self
.execute(build_command
, logger
=self
.log
)
759 # Perform the install test after the actual build.
760 if install_test
and not prepare
:
763 except ShellEnvironmentError
:
765 self
.log
.error(_("Build failed"))
767 except KeyboardInterrupt:
769 self
.log
.error(_("Build interrupted"))
773 # Catch all other errors.
776 self
.log
.error(_("Build failed."), exc_info
=True)
779 # Don't sign packages in prepare mode.
783 # Sign all built packages with the host key (if available).
786 # Dump package information.
791 # End here in case of an error.
792 raise BuildError
, _("The build command failed. See logfile for details.")
794 def install_test(self
):
795 self
.log
.info(_("Running installation test..."))
797 # Install all packages that were built.
798 self
.install(self
.find_result_packages(), allow_vendorchange
=True,
799 allow_uninstall
=True, signatures_mode
="disabled")
801 self
.log
.info(_("Installation test succeeded."))
804 def shell(self
, args
=[]):
805 if not util
.cli_is_interactive():
806 self
.log
.warning("Cannot run shell on non-interactive console.")
809 # Install all packages that are needed to run a shell.
810 self
.install(SHELL_PACKAGES
)
812 # XXX need to set CFLAGS here
813 command
= "/usr/sbin/chroot %s %s %s" % \
814 (self
.chrootPath(), SHELL_SCRIPT
, " ".join(args
))
816 # Add personality if we require one
817 if self
.pakfire
.distro
.personality
:
818 command
= "%s %s" % (self
.pakfire
.distro
.personality
, command
)
820 for key
, val
in self
.environ
.items():
821 command
= "%s=\"%s\" " % (key
, val
) + command
823 # Empty the environment
824 command
= "env -i - %s" % command
826 self
.log
.debug("Shell command: %s" % command
)
828 shell
= os
.system(command
)
829 return os
.WEXITSTATUS(shell
)
831 def sign_packages(self
, keyfp
=None):
832 # Do nothing if signing is not requested.
833 if not self
.settings
.get("sign_packages"):
836 # Get key, that should be used for signing.
838 keyfp
= self
.keyring
.get_host_key_id()
840 # Find all files to process.
841 files
= self
.find_result_packages()
843 # Create a progressbar.
844 print _("Signing packages...")
845 p
= util
.make_progress(keyfp
, len(files
))
849 # Update progressbar.
855 pkg
= packages
.open(self
.pakfire
, None, file)
863 print "" # Print an empty line.
868 for file in self
.find_result_packages():
869 pkg
= packages
.open(self
.pakfire
, None, file)
872 # If there are no packages, there is nothing to do.
878 self
.log
.info(_("Dumping package information:"))
880 dump
= pkg
.dump(long=True)
882 for line
in dump
.splitlines():
883 self
.log
.info(" %s" % line
)
884 self
.log
.info("") # Empty line.
887 class Builder(object):
888 def __init__(self
, pakfire
, filename
, resultdir
, **kwargs
):
889 self
.pakfire
= pakfire
891 self
.filename
= filename
893 self
.resultdir
= resultdir
896 self
.pkg
= packages
.Makefile(self
.pakfire
, self
.filename
)
904 return self
.pkg
.buildroot
908 return self
.pakfire
.distro
914 # Get all definitions from the package.
915 environ
.update(self
.pkg
.exports
)
917 # Overwrite some definitions by default values.
918 environ
.update(self
._environ
)
922 def execute(self
, command
, logger
=None, **kwargs
):
924 logger
= logging
.getLogger("pakfire")
926 # Make every shell to a login shell because we set a lot of
927 # environment things there.
928 command
= ["bash", "--login", "-c", command
]
931 "cwd" : "/%s" % LOCAL_TMP_PATH
,
932 "env" : self
.environ
,
934 "personality" : self
.distro
.personality
,
940 shellenv
= shell
.ShellExecuteEnvironment(command
, **args
)
943 except ShellEnvironmentError
:
944 logger
.error("Command exited with an error: %s" % command
)
949 def run_script(self
, script
, *args
):
950 if not script
.startswith("/"):
951 script
= os
.path
.join(SCRIPT_DIR
, script
)
953 assert os
.path
.exists(script
), "Script we should run does not exist: %s" % script
960 # Returns the output of the command, but the output won't get
962 exe
= self
.execute(cmd
, record_output
=True, log_output
=False)
964 # Return the output of the command.
965 if exe
.exitcode
== 0:
968 def create_icecream_toolchain(self
):
971 "icecc --build-native 2>/dev/null",
972 record_output
=True, record_stderr
=False,
973 log_output
=False, log_errors
=False,
976 except ShellEnvironmentError
:
979 for line
in exe
.output
.splitlines():
980 m
= re
.match(r
"^creating ([a-z0-9]+\.tar\.gz)", line
)
982 self
._environ
["ICECC_VERSION"] = "/tmp/%s" % m
.group(1)
984 def create_buildscript(self
, stage
):
985 # Get buildscript from the package.
986 script
= self
.pkg
.get_buildscript(stage
)
988 # Write script to an empty file.
989 f
= tempfile
.NamedTemporaryFile(mode
="w", delete
=False)
990 f
.write("#!/bin/sh\n\n")
993 f
.write("\n%s\n" % script
)
997 # Make the script executable.
998 os
.chmod(f
.name
, 700)
1002 def build(self
, stages
=None):
1003 # Create buildroot and remove all content if it was existant.
1004 util
.rm(self
.buildroot
)
1005 os
.makedirs(self
.buildroot
)
1007 # Build icecream toolchain if icecream is installed.
1008 self
.create_icecream_toolchain()
1010 # Process stages in order.
1011 for stage
in ("prepare", "build", "test", "install"):
1012 # Skip unwanted stages.
1013 if stages
and not stage
in stages
:
1017 self
.build_stage(stage
)
1019 # Stop if install stage has not been processed.
1020 if stages
and not "install" in stages
:
1023 # Run post-build stuff.
1024 self
.post_compress_man_pages()
1025 self
.post_remove_static_libs()
1026 self
.post_extract_debuginfo()
1028 # Package the result.
1029 # Make all these little package from the build environment.
1030 log
.info(_("Creating packages:"))
1032 for pkg
in reversed(self
.pkg
.packages
):
1033 packager
= packages
.packager
.BinaryPackager(self
.pakfire
, pkg
,
1034 self
, self
.buildroot
)
1035 pkg
= packager
.run(self
.resultdir
)
1039 def build_stage(self
, stage
):
1040 # Get the buildscript for this stage.
1041 buildscript
= self
.create_buildscript(stage
)
1043 # Execute the buildscript of this stage.
1044 log
.info(_("Running stage %s:") % stage
)
1047 self
.execute(buildscript
)
1050 # Remove the buildscript.
1051 if os
.path
.exists(buildscript
):
1052 os
.unlink(buildscript
)
1054 def post_remove_static_libs(self
):
1055 keep_libs
= self
.pkg
.lexer
.build
.get_var("keep_libraries")
1056 keep_libs
= keep_libs
.split()
1059 self
.execute("%s/remove-static-libs %s %s" % \
1060 (SCRIPT_DIR
, self
.buildroot
, " ".join(keep_libs
)))
1061 except ShellEnvironmentError
, e
:
1062 log
.warning(_("Could not remove static libraries: %s") % e
)
1064 def post_compress_man_pages(self
):
1066 self
.execute("%s/compress-man-pages %s" % (SCRIPT_DIR
, self
.buildroot
))
1067 except ShellEnvironmentError
, e
:
1068 log
.warning(_("Compressing man pages did not complete successfully."))
1070 def post_extract_debuginfo(self
):
1073 # Check if we need to run with strict build-id.
1074 strict_id
= self
.pkg
.lexer
.build
.get_var("debuginfo_strict_build_id", "true")
1075 if strict_id
in ("true", "yes", "1"):
1076 args
.append("--strict-build-id")
1078 args
.append("--buildroot=%s" % self
.pkg
.buildroot
)
1079 args
.append("--sourcedir=%s" % self
.pkg
.sourcedir
)
1081 # Get additional options to pass to script.
1082 options
= self
.pkg
.lexer
.build
.get_var("debuginfo_options", "")
1083 args
+= options
.split()
1086 self
.execute("%s/extract-debuginfo %s %s" % (SCRIPT_DIR
, " ".join(args
), self
.pkg
.buildroot
))
1087 except ShellEnvironmentError
, e
:
1088 log
.error(_("Extracting debuginfo did not complete with success. Aborting build."))
1091 def find_prerequires(self
, scriptlet_file
):
1092 assert os
.path
.exists(scriptlet_file
), "Scriptlet file does not exist: %s" % scriptlet_file
1094 res
= self
.run_script("find-prerequires", scriptlet_file
)
1095 prerequires
= set(res
.splitlines())
1100 if os
.path
.exists(self
.buildroot
):
1101 util
.rm(self
.buildroot
)