]>
git.ipfire.org Git - people/ms/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
)
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"),
575 ("pakfire_tmpfs", "/tmp", "tmpfs", "mode=755,nosuid,nodev"),
578 # If selinux is enabled.
579 if os
.path
.exists("/sys/fs/selinux"):
581 ("/sys/fs/selinux", "/sys/fs/selinux", "bind", "bind"),
582 ("/sys/fs/selinux", "/sys/fs/selinux", "bind", "bind,ro,remount"),
585 # If ccache support is requested, we bind mount the cache.
586 if self
.settings
.get("enable_ccache"):
587 # Create ccache cache directory if it does not exist.
588 if not os
.path
.exists(CCACHE_CACHE_DIR
):
589 os
.makedirs(CCACHE_CACHE_DIR
)
592 (CCACHE_CACHE_DIR
, "/var/cache/ccache", "bind", "bind"),
600 # Add HOME manually, because it is occasionally not set
601 # and some builds get in trouble then.
602 "PATH" : "/usr/bin:/bin:/usr/sbin:/sbin",
604 "TERM" : os
.environ
.get("TERM", "vt100"),
608 "LANG" : os
.environ
.setdefault("LANG", "en_US.UTF-8"),
610 # Set the container that we can detect, if we are inside a
612 "container" : "pakfire-builder",
615 # Inherit environment from distro
616 env
.update(self
.pakfire
.distro
.environ
)
618 # Icecream environment settings
619 if self
.settings
.get("enable_icecream", False):
620 # Set the toolchain path
621 if self
.settings
.get("icecream_toolchain", None):
622 env
["ICECC_VERSION"] = self
.settings
.get("icecream_toolchain")
624 # Set preferred host if configured.
625 if self
.settings
.get("icecream_preferred_host", None):
626 env
["ICECC_PREFERRED_HOST"] = \
627 self
.settings
.get("icecream_preferred_host")
629 # Fake UTS_MACHINE, when we cannot use the personality syscall and
630 # if the host architecture is not equal to the target architecture.
631 if not self
.pakfire
.distro
.personality
and \
632 not system
.native_arch
== self
.pakfire
.distro
.arch
:
634 "LD_PRELOAD" : "/usr/lib/libpakfire_preload.so",
635 "UTS_MACHINE" : self
.pakfire
.distro
.arch
,
641 def installed_packages(self
):
643 Returns an iterator over all installed packages in this build environment.
645 # Get the repository of all installed packages.
646 repo
= self
.pakfire
.repos
.get_repo("@system")
648 # Return an iterator over the packages.
651 def write_config(self
):
652 # Cleanup everything in /etc/pakfire.
653 util
.rm(self
.chrootPath(CONFIG_DIR
))
655 for i
in (CONFIG_DIR
, CONFIG_REPOS_DIR
):
656 i
= self
.chrootPath(i
)
657 if not os
.path
.exists(i
):
660 # Write general.conf.
661 f
= open(self
.chrootPath(CONFIG_DIR
, "general.conf"), "w")
664 # Write builder.conf.
665 f
= open(self
.chrootPath(CONFIG_DIR
, "builder.conf"), "w")
666 f
.write(self
.distro
.get_config())
669 # Create pakfire configuration files.
670 for repo
in self
.pakfire
.repos
:
671 conf
= repo
.get_config()
676 filename
= self
.chrootPath(CONFIG_REPOS_DIR
, "%s.repo" % repo
.name
)
677 f
= open(filename
, "w")
678 f
.write("\n".join(conf
))
682 def pkg_makefile(self
):
683 return os
.path
.join(self
.build_dir
, "%s.%s" % (self
.pkg
.name
, MAKEFILE_EXTENSION
))
685 def execute(self
, command
, logger
=None, **kwargs
):
687 Executes the given command in the build chroot.
689 # Environment variables
692 if kwargs
.has_key("env"):
693 env
.update(kwargs
.pop("env"))
695 self
.log
.debug("Environment:")
696 for k
, v
in sorted(env
.items()):
697 self
.log
.debug(" %s=%s" % (k
, v
))
699 # Make every shell to a login shell because we set a lot of
700 # environment things there.
701 command
= ["bash", "--login", "-c", command
]
704 "chroot_path" : self
.chrootPath(),
705 "cgroup" : self
.cgroup
,
708 "personality" : self
.personality
,
714 shellenv
= shell
.ShellExecuteEnvironment(command
, **args
)
719 def execute_root(self
, command
, **kwargs
):
721 Executes the given command outside the build chroot.
723 shellenv
= shell
.ShellExecuteEnvironment(command
, **kwargs
)
728 def build(self
, install_test
=True, prepare
=False):
730 raise BuildError
, _("You cannot run a build when no package was given.")
732 # Search for the package file in build_dir and raise BuildError if it is not present.
733 if not os
.path
.exists(self
.pkg_makefile
):
734 raise BuildError
, _("Could not find makefile in build root: %s") % self
.pkg_makefile
736 # Write pakfire configuration into the chroot.
739 # Create the build command, that is executed in the chroot.
741 "/usr/lib/pakfire/builder",
744 "/%s" % os
.path
.relpath(self
.pkg_makefile
, self
.chrootPath()),
747 "--resultdir=/result",
750 # Check if only the preparation stage should be run.
752 build_command
.append("--prepare")
754 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
:
764 self
.log
.error(_("Build failed"))
766 except KeyboardInterrupt:
767 self
.log
.error(_("Build interrupted"))
771 # Catch all other errors.
773 self
.log
.error(_("Build failed."), exc_info
=True)
776 # Don't sign packages in prepare mode.
780 # Sign all built packages with the host key (if available).
783 # Dump package information.
788 # End here in case of an error.
789 raise BuildError
, _("The build command failed. See logfile for details.")
791 def install_test(self
):
792 self
.log
.info(_("Running installation test..."))
794 # Install all packages that were built.
795 self
.install(self
.find_result_packages(), allow_vendorchange
=True,
796 allow_uninstall
=True, signatures_mode
="disabled")
798 self
.log
.info(_("Installation test succeeded."))
801 def shell(self
, args
=[]):
802 if not util
.cli_is_interactive():
803 self
.log
.warning("Cannot run shell on non-interactive console.")
806 # Install all packages that are needed to run a shell.
807 self
.install(SHELL_PACKAGES
)
809 # XXX need to set CFLAGS here
810 command
= "/usr/sbin/chroot %s %s %s" % \
811 (self
.chrootPath(), SHELL_SCRIPT
, " ".join(args
))
813 # Add personality if we require one
814 if self
.pakfire
.distro
.personality
:
815 command
= "%s %s" % (self
.pakfire
.distro
.personality
, command
)
817 for key
, val
in self
.environ
.items():
818 command
= "%s=\"%s\" " % (key
, val
) + command
820 # Empty the environment
821 command
= "env -i - %s" % command
823 self
.log
.debug("Shell command: %s" % command
)
825 shell
= os
.system(command
)
826 return os
.WEXITSTATUS(shell
)
828 def sign_packages(self
, keyfp
=None):
829 # Do nothing if signing is not requested.
830 if not self
.settings
.get("sign_packages"):
833 # Get key, that should be used for signing.
835 keyfp
= self
.keyring
.get_host_key_id()
837 # Find all files to process.
838 files
= self
.find_result_packages()
840 # Create a progressbar.
841 print _("Signing packages...")
842 p
= util
.make_progress(keyfp
, len(files
))
846 # Update progressbar.
852 pkg
= packages
.open(self
.pakfire
, None, file)
860 print "" # Print an empty line.
865 for file in self
.find_result_packages():
866 pkg
= packages
.open(self
.pakfire
, None, file)
869 # If there are no packages, there is nothing to do.
875 self
.log
.info(_("Dumping package information:"))
877 dump
= pkg
.dump(long=True)
879 for line
in dump
.splitlines():
880 self
.log
.info(" %s" % line
)
881 self
.log
.info("") # Empty line.
884 class Builder(object):
885 def __init__(self
, pakfire
, filename
, resultdir
, **kwargs
):
886 self
.pakfire
= pakfire
888 self
.filename
= filename
890 self
.resultdir
= resultdir
893 self
.pkg
= packages
.Makefile(self
.pakfire
, self
.filename
)
901 return self
.pkg
.buildroot
905 return self
.pakfire
.distro
911 # Get all definitions from the package.
912 environ
.update(self
.pkg
.exports
)
914 # Overwrite some definitions by default values.
915 environ
.update(self
._environ
)
919 def execute(self
, command
, logger
=None, **kwargs
):
921 logger
= logging
.getLogger("pakfire")
923 # Make every shell to a login shell because we set a lot of
924 # environment things there.
925 command
= ["bash", "--login", "-c", command
]
928 "cwd" : "/%s" % LOCAL_TMP_PATH
,
929 "env" : self
.environ
,
931 "personality" : self
.distro
.personality
,
937 shellenv
= shell
.ShellExecuteEnvironment(command
, **args
)
940 except ShellEnvironmentError
:
941 logger
.error("Command exited with an error: %s" % command
)
946 def run_script(self
, script
, *args
):
947 if not script
.startswith("/"):
948 script
= os
.path
.join(SCRIPT_DIR
, script
)
950 assert os
.path
.exists(script
), "Script we should run does not exist: %s" % script
957 # Returns the output of the command, but the output won't get
959 exe
= self
.execute(cmd
, record_output
=True, log_output
=False)
961 # Return the output of the command.
962 if exe
.exitcode
== 0:
965 def create_icecream_toolchain(self
):
968 "icecc --build-native 2>/dev/null",
969 record_output
=True, record_stderr
=False,
970 log_output
=False, log_errors
=False,
973 except ShellEnvironmentError
:
976 for line
in exe
.output
.splitlines():
977 m
= re
.match(r
"^creating ([a-z0-9]+\.tar\.gz)", line
)
979 self
._environ
["ICECC_VERSION"] = "/tmp/%s" % m
.group(1)
981 def create_buildscript(self
, stage
):
982 # Get buildscript from the package.
983 script
= self
.pkg
.get_buildscript(stage
)
985 # Write script to an empty file.
986 f
= tempfile
.NamedTemporaryFile(mode
="w", delete
=False)
987 f
.write("#!/bin/sh\n\n")
990 f
.write("\n%s\n" % script
)
994 # Make the script executable.
995 os
.chmod(f
.name
, 700)
999 def build(self
, stages
=None):
1000 # Create buildroot and remove all content if it was existant.
1001 util
.rm(self
.buildroot
)
1002 os
.makedirs(self
.buildroot
)
1004 # Build icecream toolchain if icecream is installed.
1005 self
.create_icecream_toolchain()
1007 # Process stages in order.
1008 for stage
in ("prepare", "build", "test", "install"):
1009 # Skip unwanted stages.
1010 if stages
and not stage
in stages
:
1014 self
.build_stage(stage
)
1016 # Stop if install stage has not been processed.
1017 if stages
and not "install" in stages
:
1020 # Run post-build stuff.
1021 self
.post_compress_man_pages()
1022 self
.post_remove_static_libs()
1023 self
.post_extract_debuginfo()
1025 # Package the result.
1026 # Make all these little package from the build environment.
1027 log
.info(_("Creating packages:"))
1029 for pkg
in reversed(self
.pkg
.packages
):
1030 packager
= packages
.packager
.BinaryPackager(self
.pakfire
, pkg
,
1031 self
, self
.buildroot
)
1032 pkg
= packager
.run(self
.resultdir
)
1036 def build_stage(self
, stage
):
1037 # Get the buildscript for this stage.
1038 buildscript
= self
.create_buildscript(stage
)
1040 # Execute the buildscript of this stage.
1041 log
.info(_("Running stage %s:") % stage
)
1044 self
.execute(buildscript
)
1047 # Remove the buildscript.
1048 if os
.path
.exists(buildscript
):
1049 os
.unlink(buildscript
)
1051 def post_remove_static_libs(self
):
1052 keep_libs
= self
.pkg
.lexer
.build
.get_var("keep_libraries")
1053 keep_libs
= keep_libs
.split()
1056 self
.execute("%s/remove-static-libs %s %s" % \
1057 (SCRIPT_DIR
, self
.buildroot
, " ".join(keep_libs
)))
1058 except ShellEnvironmentError
, e
:
1059 log
.warning(_("Could not remove static libraries: %s") % e
)
1061 def post_compress_man_pages(self
):
1063 self
.execute("%s/compress-man-pages %s" % (SCRIPT_DIR
, self
.buildroot
))
1064 except ShellEnvironmentError
, e
:
1065 log
.warning(_("Compressing man pages did not complete successfully."))
1067 def post_extract_debuginfo(self
):
1070 # Check if we need to run with strict build-id.
1071 strict_id
= self
.pkg
.lexer
.build
.get_var("debuginfo_strict_build_id", "true")
1072 if strict_id
in ("true", "yes", "1"):
1073 args
.append("--strict-build-id")
1075 args
.append("--buildroot=%s" % self
.pkg
.buildroot
)
1076 args
.append("--sourcedir=%s" % self
.pkg
.sourcedir
)
1078 # Get additional options to pass to script.
1079 options
= self
.pkg
.lexer
.build
.get_var("debuginfo_options", "")
1080 args
+= options
.split()
1083 self
.execute("%s/extract-debuginfo %s %s" % (SCRIPT_DIR
, " ".join(args
), self
.pkg
.buildroot
))
1084 except ShellEnvironmentError
, e
:
1085 log
.error(_("Extracting debuginfo did not complete with success. Aborting build."))
1088 def find_prerequires(self
, scriptlet_file
):
1089 assert os
.path
.exists(scriptlet_file
), "Scriptlet file does not exist: %s" % scriptlet_file
1091 res
= self
.run_script("find-prerequires", scriptlet_file
)
1092 prerequires
= set(res
.splitlines())
1097 if os
.path
.exists(self
.buildroot
):
1098 util
.rm(self
.buildroot
)