]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
build-essentials: Many other changes for the new pakfire build system.
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 5 Feb 2011 19:18:31 +0000 (20:18 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 5 Feb 2011 19:18:31 +0000 (20:18 +0100)
19 files changed:
pkgs/core/build-essentials/build-essentials.nm
pkgs/core/build-essentials/buildsystem-tools/chroot-shell [new file with mode: 0755]
pkgs/core/build-essentials/buildsystem-tools/common-functions [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/dependency-tracker [new file with mode: 0755]
pkgs/core/build-essentials/buildsystem-tools/functions-common [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/functions-constants [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/functions-directories [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/functions-files [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/functions-lists [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/functions-logging [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/functions-packager-find [new file with mode: 0644]
pkgs/core/build-essentials/buildsystem-tools/patch [moved from pkgs/core/build-essentials/patch with 100% similarity]
pkgs/core/build-essentials/buildsystem-tools/perl.prov [new file with mode: 0755]
pkgs/core/build-essentials/buildsystem-tools/perl.req [new file with mode: 0755]
pkgs/core/build-essentials/buildsystem-tools/py-compile [new file with mode: 0755]
pkgs/core/build-essentials/buildsystem/Constants
pkgs/core/build-essentials/buildsystem/Functions
pkgs/core/build-essentials/buildsystem/Targets
pkgs/core/build-essentials/quality-agent/quality-agent.d/qa-include

index 08c4ccbb6e7543b310f3f2516113d668ba85123c..a1d2d607a7724750f90e926062c0dbfba481d663 100644 (file)
@@ -27,6 +27,7 @@ include $(PKGROOT)/Include
 PKG_NAME       = build-essentials
 PKG_VER        = $(DISTRO_VERSION)
 PKG_REL        = 2
+#PKG_ARCH       = noarch
 
 PKG_MAINTAINER = Michael Tremer <michael.tremer@ipfire.org>
 PKG_GROUP      = Development/Tools
@@ -47,12 +48,12 @@ STAGE_BUILD = # Nothing to do here
 
 define STAGE_INSTALL
        # Install the quality-agent and buildsystem header files.
-       -mkdir -pv $(BUILDROOT)/usr/bin
-       -mkdir -pv $(BUILDROOT)/usr/sbin
-       -mkdir -pv $(BUILDROOT)/usr/lib/buildsystem
+       -mkdir -pv $(BUILDROOT)/usr/{,s}bin
+       -mkdir -pv $(BUILDROOT)/usr/lib/buildsystem{,-tools}
        -mkdir -pv $(BUILDROOT)/usr/lib/quality-agent
 
        cp -vf buildsystem/* $(BUILDROOT)/usr/lib/buildsystem
+       cp -vf buildsystem-tools/* $(BUILDROOT)/usr/lib/buildsystem-tools
 
        cp -vf quality-agent/quality-agent $(BUILDROOT)/usr/sbin/
        cp -vrf quality-agent/quality-agent.d/* \
@@ -61,11 +62,7 @@ define STAGE_INSTALL
        -mkdir -pv $(BUILDROOT)/etc/profile.d
        cp -vf buildsystem.sh $(BUILDROOT)/etc/profile.d/
 
-       # Install chroot shell
-       cp -vf chroot-shell $(BUILDROOT)/usr/bin/chroot-shell
-       chmod -v 755 $(BUILDROOT)/usr/bin/chroot-shell
-
-       # Install patch utility
-       cp -vf patch $(BUILDROOT)/usr/lib/buildsystem/patch
-       chmod -v 755 $(BUILDROOT)/usr/lib/buildsystem/patch
+       # Create symlink to chroot-shell
+       ln -svf ../lib/buildsystem-tools/chroot-shell \
+               $(BUILDROOT)/usr/bin/chroot-shell
 endef
diff --git a/pkgs/core/build-essentials/buildsystem-tools/chroot-shell b/pkgs/core/build-essentials/buildsystem-tools/chroot-shell
new file mode 100755 (executable)
index 0000000..0d4a61f
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+cat <<EOF
+
+       You are now dropped to a chrooted shell of the package's environment.
+
+       The sources have been extracted to /build and maybe there are files left
+       from a last (broken) build. Nothing of that content will be saved after
+       you left the shell.
+
+       You can leave the environment by typing "exit" or Ctrl-D.
+
+EOF
+
+# Setting nice environment
+export PS1="pakfire-chroot \w> "
+
+# Change to directory the user will most likely work in
+if [ -z "${SOURCE_DIR}" ]; then
+       SOURCE_DIR="/build"
+fi
+cd "${SOURCE_DIR}"
+
+exec /bin/bash --login
diff --git a/pkgs/core/build-essentials/buildsystem-tools/common-functions b/pkgs/core/build-essentials/buildsystem-tools/common-functions
new file mode 100644 (file)
index 0000000..4c44a58
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# Simply import all files from this directory that
+# begin with functions-*.
+
+BASEDIR=$(dirname ${BASH_SOURCE[0]})
+
+for file in ${BASEDIR}/functions-*; do
+       # Avoid infinite loop when importing this file again
+       [ "$(basename ${file})" = "functions-common" ] && continue
+
+       . ${file}
+done
+
diff --git a/pkgs/core/build-essentials/buildsystem-tools/dependency-tracker b/pkgs/core/build-essentials/buildsystem-tools/dependency-tracker
new file mode 100755 (executable)
index 0000000..5fb9718
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+dirname=$(dirname ${0})
+
+. ${dirname}/common-functions
+
+action=${1}
+shift
+
+case "${action}" in
+       requires)
+               find_requires $@
+               exit $?
+               ;;
+
+       provides)
+               find_provides $@
+               exit $?
+               ;;
+esac
+
+exit 1
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-common b/pkgs/core/build-essentials/buildsystem-tools/functions-common
new file mode 100644 (file)
index 0000000..4c44a58
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+# Simply import all files from this directory that
+# begin with functions-*.
+
+BASEDIR=$(dirname ${BASH_SOURCE[0]})
+
+for file in ${BASEDIR}/functions-*; do
+       # Avoid infinite loop when importing this file again
+       [ "$(basename ${file})" = "functions-common" ] && continue
+
+       . ${file}
+done
+
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-constants b/pkgs/core/build-essentials/buildsystem-tools/functions-constants
new file mode 100644 (file)
index 0000000..396e045
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Debugging mode for these scripts
+DEBUG=0
+
+# Interpreters that should not be found by find_interpreters()
+INTERPRETERS_TO_BE_SKIPPED="/usr/bin/env"
+
+# Some path constants...
+LIBRARY_PATHS="/lib /usr/lib /libexec /usr/libexec"
+BINARY_PATHS="${LIBRARY_PATHS} /bin /sbin /usr/bin /usr/sbin"
+
+# List of directories that could probably empty and are removed automatically
+# so they won't appear in any package.
+ORPHAN_CANDIDATES="${BINARY_PATHS} /usr /usr/include /usr/share"
+for i in $(seq 0 9); do
+       ORPHAN_CANDIDATES="${ORPHAN_CANDIDATES} /usr/share/man/man${i}"
+done
+ORPHAN_CANDIDATES="${ORPHAN_CANDIDATES} /usr/lib/pkgconfig"
+
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-directories b/pkgs/core/build-essentials/buildsystem-tools/functions-directories
new file mode 100644 (file)
index 0000000..5b0867b
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+function dir_is_empty() {
+       [ "$(ls -A $@ 2>/dev/null | wc -l)" = "0" ]
+}
+
+function directory_remove_orphans() {
+       local basedir=${1}
+
+       log DEBUG "Removing orphans in ${basedir}"
+
+       local dir
+       for dir in ${ORPHAN_CANDIDATES}; do
+               dir="${basedir}/${dir}"
+
+               [ -d "${dir}" ] || continue
+
+               if dir_is_empty ${dir}; then
+                       log DEBUG "  Found orphaned directory: ${dir}"
+                       rm -rf ${dir}
+               fi
+       done
+}
+
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-files b/pkgs/core/build-essentials/buildsystem-tools/functions-files
new file mode 100644 (file)
index 0000000..41ce3be
--- /dev/null
@@ -0,0 +1,195 @@
+#!/bin/bash
+
+# Check if a file is an ELF binary
+#
+function file_is_elf() {
+       local file=${1}
+
+       file "${file}" | grep -q "ELF"
+}
+
+# Check if a file is a script.
+#   If the first line starts with #! this is sufficient.
+#
+function file_is_script() {
+       local file=${1}
+
+       local first_line=$(head -n1 ${file})
+
+       [ "${first_line:0:2}" = "#!" ]
+}
+
+# Get the interpreter of a file.
+#
+function file_get_interpreter() {
+       local file=${1}
+
+       if file_is_elf ${file}; then
+               _file_get_elf_interpreter ${file}
+       elif file_is_script ${file}; then
+               _file_get_script_interpreter ${file}
+       fi
+}
+
+# Hidden function that gets the interpreter from an ELF file.
+#
+function _file_get_elf_interpreter() {
+       local file=${1}
+
+       readelf -l ${file} | grep "program interpreter" | \
+               tr -d "]" | awk '{ print $NF }'
+}
+
+# Hidden fucntion that gets the interpreter from a script file.
+#
+function _file_get_script_interpreter() {
+       local file=${1}
+
+       # If the file is not executeable, no interpreter will be needed
+       [ -x "${file}" ] || return
+
+       local first_line=$(head -n1 ${file})
+
+       first_line="${first_line:2:${#first_line}}"
+
+       # Choose the first argument and strip any parameters if available
+       local interpreter
+       for interpreter in ${first_line}; do
+               echo "${interpreter}"
+               return
+       done
+}
+
+# Check if a file is statically linked.
+#
+function file_is_static() {
+       local file=${1}
+
+       file ${file} | grep -q "statically linked"
+}
+
+# Get NEEDED from a file.
+#
+function file_get_needed() {
+       local file=${1}
+
+       readelf -d ${file} | grep NEEDED | \
+               tr -d "[]" | awk '{ print $NF }'
+}
+
+# Get RPATH from a file.
+#
+function file_get_rpath() {
+       local file=${1}
+
+       readelf -d ${file} | grep RPATH | \
+               tr -d "[]" | awk '{ print $NF }'
+}
+
+# Get SONAME from a file.
+#
+function file_get_soname() {
+       local file=${1}
+
+       local file_basename=$(basename ${file})
+       if [ "${file_basename:0:3}" = "ld-" ]; then
+               log DEBUG "Don't return a SONAME for linkers: ${file}"
+               return
+       fi
+
+       readelf -d ${file} | grep SONAME | \
+               tr -d "[]" | awk '{ print $NF }'
+}
+
+# Check if a file is a shared object.
+#
+function file_is_shared_object() {
+       local file=${1}
+
+       file ${file} | grep -q "shared object"
+}
+
+# Check if a file has the canary.
+#
+function file_has_canary() {
+       local file=${1}
+
+       readelf -s ${file} | grep -q "__stack_chk_fail"
+}
+
+# Check if a file has an executeable stack.
+#
+function file_has_execstack() {
+       local file=${1}
+
+       readelf -h ${file} | grep -qE "Type:[[:space:]]*EXEC"
+}
+
+# Check if a file has NX.
+#
+function file_has_nx() {
+       local file=${1}
+
+       readelf -l ${file} | grep "GNU_STACK" | grep -q "RWE"
+       [ $? != 0 ]
+}
+
+# Check if a file is partly RELRO.
+#
+function file_is_relro_partly() {
+       local file=${1}
+
+       readelf -l ${file} | grep -q "GNU_RELRO"
+}
+
+# Check if a file is fully RELRO.
+#
+function file_is_relro_full() {
+       local file=${1}
+
+       if file_is_relro_partly ${file}; then
+               readelf -d ${file} | grep -q "BIND_NOW"
+               return $?
+       fi
+       return 1
+}
+
+# Find all ELF files.
+#
+function find_elf_files() {
+       local dir
+       local dirs
+       local prefix
+
+       while [ $# -gt 0 ]; do
+               case "${1}" in
+                       --prefix=*)
+                               prefix="${1#--prefix=}/"
+                               ;;
+                       *)
+                               dirs="${dirs} ${1}"
+                               ;;
+               esac
+               shift
+       done
+
+       local file
+       local files
+
+       for dir in ${dirs}; do
+               dir="${prefix}${dir}"
+               for file in $(find ${dir} -type f 2>/dev/null); do
+                       if file_is_elf ${file} && file_is_shared_object ${file} && ! file_is_static ${file}; then
+                               files="${files} ${file}"
+                       fi
+               done
+       done
+
+       echo ${files}
+}
+
+function filter_startfiles() {
+       local file=${1}
+
+       grep -qE "crt[1in]\.o$" <<<${file}
+}
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-lists b/pkgs/core/build-essentials/buildsystem-tools/functions-lists
new file mode 100644 (file)
index 0000000..d8152d4
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+function listsort() {
+       local item
+       for item in $@; do
+               echo "${item}"
+       done | sort -u | tr "\n" " "
+}
+
+function listmatch() {
+       local arg=${1}
+       shift
+
+       local item
+       for item in $@; do
+               if [ "${arg}" = "${item}" ]; then
+                       return 0
+               fi
+       done
+       return 1
+}
+
+function sort_by_length() {
+       local c
+       local i
+       for i in $@; do
+               echo "$(wc -c <<<${i}) ${i}"
+       done | sort -n -r | while read c i; do
+               echo "${i}"
+       done
+}
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-logging b/pkgs/core/build-essentials/buildsystem-tools/functions-logging
new file mode 100644 (file)
index 0000000..4fd43ed
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+function log() {
+       local level=${1}
+       shift
+
+       if [ "${level}" = "DEBUG" ] && [ "${DEBUG}" != "1" ]; then
+               return
+       fi
+
+       printf " %1s | %s\n" "${level:0:1}" "$@" >&2
+}
diff --git a/pkgs/core/build-essentials/buildsystem-tools/functions-packager-find b/pkgs/core/build-essentials/buildsystem-tools/functions-packager-find
new file mode 100644 (file)
index 0000000..bc97483
--- /dev/null
@@ -0,0 +1,214 @@
+#!/bin/bash
+
+# A function that finds needed libraries and interpreters.
+#
+function find_requires() {
+       local dir
+       local dirs=$@
+
+       # Find interpreters of all files in the dirs and skip those we provide
+       # ourself.
+       local interpreter
+       local interpreters
+       for interpreter in $(find_interpreters ${dirs}); do
+               local found=0
+               for dir in ${dirs}; do
+                       if [ -e "${dir}/${interpreter}" ]; then
+                               found=1
+                               break
+                       fi
+               done
+
+               [ "${found}" = "0" ] && interpreters="${interpreters} ${interpreter}"
+       done
+
+       # Find NEEDED libs and add them to a list if they are not provided by any
+       # other file in dirs.
+       local neededs
+       for file in $(find_elf_files ${dirs}); do
+               for needed in $(file_get_needed ${file}); do
+                       neededs="${neededs} ${needed}"
+               done
+       done
+
+       # Find all symlink destinations
+       local links=$(find_symlink_destinations ${dirs})
+
+       # Others
+       local others=$(find_python_requires ${dirs})
+       others="${others} $(find_weak_symbols_requires ${dirs})"
+       others="${others} $(find_perl_requires ${dirs})"
+
+       # Get provides, because packages should not depend on features they provide
+       # by themselves.
+       local provides=$(find_provides ${dirs})
+
+       # Return a sorted and unique(!) list
+       local require
+       local requires
+       for require in $(listsort ${PKG_DEPS} ${interpreters} ${neededs} ${links} ${others}); do
+               [ "${require:0:3}" = "ld-" ] && continue
+               listmatch ${require} ${provides} || requires="${requires} ${require}"
+       done
+
+       echo ${requires}
+}
+
+function find_provides() {
+       local dirs=$@
+
+       local file
+       local sonames
+       for file in $(find_elf_files ${dirs}); do
+               sonames="${sonames} $(file_get_soname ${file})"
+       done
+       sonames=$(listsort ${sonames})
+
+       # Others
+       local others=$(find_python_provides ${dirs})
+       others="${others} $(find_weak_symbols_provides ${dirs})"
+       others="${others} $(find_perl_provides ${dirs})"
+
+       listsort ${PKG_PROVIDES} ${sonames} ${others}
+}
+
+function find_interpreters() {
+       local dirs=$@
+
+       log DEBUG "Searching for interpreters in ${dirs}"
+
+       local file
+       local interpreter
+       local interpreters
+       for file in $(find ${dirs} -type f 2>/dev/null); do
+               # Get interpreter information from file.
+               interpreter=$(file_get_interpreter ${file})
+
+               # Skip the file silently if the result was empty.
+               [ -z "${interpreter}" ] && continue
+
+               # Skip invalid interpreters that don't start with a slash.
+               if [ "${interpreter:0:1}" != "/" ]; then
+                       log WARNING "Skipping invalid interpreter \"${interpreter}\" from \"${file}\"."
+                       continue
+               fi
+
+               if ! listmatch ${interpreter} ${INTERPRETERS_TO_BE_SKIPPED}; then
+                       interpreters="${interpreters} ${interpreter}"
+               fi
+       done
+
+       interpreters=$(listsort ${interpreters})
+
+       log DEBUG "find_interpreters ${dirs}: ${interpreters}"
+
+       echo "${interpreters}"
+}
+
+# Find the destinations of all symlinks and adds a dependency for that.
+#
+function find_symlink_destinations() {
+        local dir=$@
+
+        local link
+        local links
+        for link in $(find ${dir} -type l 2>/dev/null); do
+                link="$(readlink -m ${link})"
+                [ -e "${link}" ] && continue
+
+                link="${link#${dir}}"
+                links="${links} ${link}"
+        done
+
+        echo ${links}
+}
+
+function find_python_provides() {
+       local dir=${1}
+
+       local file
+       for file in $(find ${dir}/usr/bin/python* 2>/dev/null); do
+               file=$(basename ${file})
+               file=${file#python}
+
+               if [ -n "${file}" ]; then
+                       echo "python-api=${file}"
+               fi
+       done
+}
+
+function find_python_requires() {
+       local dir=${1}
+
+       local file
+       for file in $(find ${dir}/usr/lib -maxdepth 1 2>/dev/null); do
+               file=$(basename ${file})
+
+               if [ "${file:0:6}" = "python" ]; then
+                       file=${file#python}
+
+                       if [ -n "${file}" ]; then
+                               echo "python-api=${file}"
+                       fi
+               fi
+       done
+}
+
+function find_perl_files() {
+       local extension
+       for extension in pm pl; do
+               find $@ -name "*.${extension}" 2>/dev/null
+       done
+}
+
+function find_perl_provides() {
+       [ -x "/usr/bin/perl" ] || return 0
+       ${BASEDIR}/perl.prov $(find_perl_files $@) | sort -u
+}
+
+function find_perl_requires() {
+       [ -x "/usr/bin/perl" ] || return 0
+       ${BASEDIR}/perl.req $(find_perl_files $@) | sort -u
+}
+
+function find_weak_symbols_provides() {
+       local dirs=$@
+
+       local file
+       local soname
+       local symbol
+       for file in $(find_elf_files ${dirs}); do
+               soname=$(file_get_soname ${file})
+               [ -z "${soname}" ] && continue
+
+               for symbol in $(objdump -p ${file} | grep -E "^[0-9]+" | awk '{ print $4 }'); do
+                       [ "${symbol}" = "${soname}" ] && continue
+                       [ "${symbol}" = "GLIBC_PRIVATE" ] && continue
+
+                       echo "${soname}(${symbol})"
+               done
+       done | sort -u
+}
+
+function find_weak_symbols_requires() {
+       local dirs=$@
+
+       local file
+       for file in $(find_elf_files ${dirs}); do
+           objdump -p ${file} | awk 'BEGIN { START=0; LIBNAME=""; }
+                       /^$/ { START=0; }
+                       /^Dynamic Section:$/ { START=1; }
+                       (START==1) && /NEEDED/ {
+                               print $2;
+                       }
+                       (START==2) && /^[A-Za-z]/ { START=3; }
+                       /^Version References:$/ { START=2; }
+                       (START==2) && /required from/ {
+                           sub(/:/, "", $3);
+                           LIBNAME=$3;
+                       }
+                       (START==2) && (LIBNAME!="") && ($4!="") && (($4~/^GLIBC_*/) || ($4~/^GCC_*/)) {
+                           print LIBNAME "(" $4 ")";
+                       }'
+       done | grep -v "GLIBC_PRIVATE" | sort -u
+}
diff --git a/pkgs/core/build-essentials/buildsystem-tools/perl.prov b/pkgs/core/build-essentials/buildsystem-tools/perl.prov
new file mode 100755 (executable)
index 0000000..73bec51
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/bin/perl
+
+# RPM (and it's source code) is covered under two separate licenses.
+
+# The entire code base may be distributed under the terms of the GNU
+# General Public License (GPL), which appears immediately below.
+# Alternatively, all of the source code in the lib subdirectory of the
+# RPM source code distribution as well as any code derived from that
+# code may instead be distributed under the GNU Library General Public
+# License (LGPL), at the choice of the distributor. The complete text
+# of the LGPL appears at the bottom of this file.
+
+# This alternative is allowed to enable applications to be linked
+# against the RPM library (commonly called librpm) without forcing
+# such applications to be distributed under the GPL.
+
+# Any questions regarding the licensing of RPM should be addressed to
+# Erik Troan <ewt@redhat.com>.
+
+# a simple script to print the proper name for perl libraries.
+
+# To save development time I do not parse the perl grammmar but
+# instead just lex it looking for what I want.  I take special care to
+# ignore comments and pod's.
+
+# it would be much better if perl could tell us the proper name of a
+# given script.
+
+# The filenames to scan are either passed on the command line or if
+# that is empty they are passed via stdin.
+
+# If there are lines in the file which match the pattern
+#      (m/^\s*\$VERSION\s*=\s+/)
+# then these are taken to be the version numbers of the modules.
+# Special care is taken with a few known idioms for specifying version
+# numbers of files under rcs/cvs control.
+
+# If there are strings in the file which match the pattern
+#     m/^\s*\$RPM_Provides\s*=\s*["'](.*)['"]/i
+# then these are treated as additional names which are provided by the
+# file and are printed as well.
+
+# I plan to rewrite this in C so that perl is not required by RPM at
+# build time.
+
+# by Ken Estes Mail.com kestes@staff.mail.com
+
+if ("@ARGV") {
+  foreach (@ARGV) {
+    process_file($_);
+  }
+} else {
+
+  # notice we are passed a list of filenames NOT as common in unix the
+  # contents of the file.
+
+  foreach (<>) {
+    process_file($_);
+  }
+}
+
+
+foreach $module (sort keys %require) {
+  if (length($require{$module}) == 0) {
+    print "perl($module)\n";
+  } else {
+
+    # I am not using rpm3.0 so I do not want spaces arround my
+    # operators. Also I will need to change the processing of the
+    # $RPM_* variable when I upgrade.
+
+    print "perl($module)=$require{$module}\n";
+  }
+}
+
+exit 0;
+
+
+
+sub process_file {
+
+  my ($file) = @_;
+  chomp $file;
+  
+  open(FILE, "<$file") || return;
+
+  my ($package, $version, $incomment, $inover) = ();
+
+  while (<FILE>) {
+    
+    # skip the documentation
+
+    # we should not need to have item in this if statement (it
+    # properly belongs in the over/back section) but people do not
+    # read the perldoc.
+
+    if (m/^=(head[1-4]|pod|item)/) {
+      $incomment = 1;
+    }
+
+    if (m/^=(cut)/) {
+      $incomment = 0;
+      $inover = 0;
+    }
+    
+    if (m/^=(over)/) {
+      $inover = 1;
+    }
+
+    if (m/^=(back)/) {
+      $inover = 0;
+    }
+
+    if ($incomment || $inover) {
+       next;
+    }
+    
+    # skip the data section
+    if (m/^__(DATA|END)__$/) {
+      last;
+    }
+
+    # not everyone puts the package name of the file as the first
+    # package name so we report all namespaces except some common
+    # false positives as if they were provided packages (really ugly).
+
+    if (m/^\s*package\s+([_:a-zA-Z0-9]+)\s*;/) {
+      $package=$1;
+      undef $version;
+      if ($package eq 'main') {
+        undef $package;
+      } else {
+        # If $package already exists in the $require hash, it means
+        # the package definition is broken up over multiple blocks.
+        # In that case, don't stomp a previous $VERSION we might have
+        # found.  (See BZ#214496.)
+        $require{$package}=undef unless (exists $require{$package});
+      }
+    }
+
+    # after we found the package name take the first assignment to
+    # $VERSION as the version number. Exporter requires that the
+    # variable be called VERSION so we are safe.
+
+    # here are examples of VERSION lines from the perl distribution
+
+    #FindBin.pm:$VERSION = $VERSION = sprintf("%d.%02d", q$Revision: 1.9 $ =~ /(\d+)\.(\d+)/);
+    #ExtUtils/Install.pm:$VERSION = substr q$Revision: 1.9 $, 10;
+    #CGI/Apache.pm:$VERSION = (qw$Revision: 1.9 $)[1];
+    #DynaLoader.pm:$VERSION = $VERSION = "1.03";     # avoid typo warning
+    #General.pm:$Config::General::VERSION = 2.33;
+    # 
+    # or with the new "our" pragma you could (read will) see:
+    #
+    #    our $VERSION = '1.00'
+    if (($package) && (m/^\s*(our\s+)?\$(\Q$package\E::)?VERSION\s*=\s+/)) {
+
+      # first see if the version string contains the string
+      # '$Revision' this often causes bizzare strings and is the most
+      # common method of non static numbering.
+
+      if (m/(\$Revision: (\d+[.0-9]+))/) {
+       $version= $2; 
+      } elsif (m/[\'\"]?(\d+[.0-9]+)[\'\"]?/) {
+       
+       # look for a static number hard coded in the script
+       
+       $version= $1; 
+      }
+      $require{$package}=$version;
+    }
+  
+    # Allow someone to have a variable that defines virtual packages
+    # The variable is called $RPM_Provides.  It must be scoped with 
+    # "our", but not "local" or "my" (just would not make sense). 
+    # 
+    # For instance:
+    #  
+    #     $RPM_Provides = "blah bleah"
+    # 
+    # Will generate provides for "blah" and "bleah".
+    #
+    # Each keyword can appear multiple times.  Don't
+    #  bother with datastructures to store these strings,
+    #  if we need to print it print it now.
+       
+    if ( m/^\s*(our\s+)?\$RPM_Provides\s*=\s*["'](.*)['"]/i) {
+      foreach $_ (split(/\s+/, $2)) {
+       print "$_\n";
+      }
+    }
+
+  }
+
+  close(FILE) ||
+    die("$0: Could not close file: '$file' : $!\n");
+
+  return ;
+}
diff --git a/pkgs/core/build-essentials/buildsystem-tools/perl.req b/pkgs/core/build-essentials/buildsystem-tools/perl.req
new file mode 100755 (executable)
index 0000000..d0a1cd7
--- /dev/null
@@ -0,0 +1,249 @@
+#!/usr/bin/perl
+
+# RPM (and its source code) is covered under two separate licenses. 
+
+# The entire code base may be distributed under the terms of the GNU
+# General Public License (GPL), which appears immediately below.
+# Alternatively, all of the source code in the lib subdirectory of the
+# RPM source code distribution as well as any code derived from that
+# code may instead be distributed under the GNU Library General Public
+# License (LGPL), at the choice of the distributor. The complete text
+# of the LGPL appears at the bottom of this file.
+
+# This alternatively is allowed to enable applications to be linked
+# against the RPM library (commonly called librpm) without forcing
+# such applications to be distributed under the GPL.
+
+# Any questions regarding the licensing of RPM should be addressed to
+# Erik Troan <ewt@redhat.com>.
+
+# a simple makedepend like script for perl.
+# To save development time I do not parse the perl grammmar but
+# instead just lex it looking for what I want.  I take special care to
+# ignore comments and pod's.
+
+# It would be much better if perl could tell us the dependencies of a
+# given script.
+
+# The filenames to scan are either passed on the command line or if
+# that is empty they are passed via stdin.
+
+# If there are strings in the file which match the pattern
+#     m/^\s*\$RPM_Requires\s*=\s*["'](.*)['"]/i
+# then these are treated as additional names which are required by the
+# file and are printed as well.
+
+# I plan to rewrite this in C so that perl is not required by RPM at
+# build time.
+
+# by Ken Estes Mail.com kestes@staff.mail.com
+
+if ("@ARGV") {
+  foreach (@ARGV) {
+    process_file($_);
+  }
+} else {
+  
+  # notice we are passed a list of filenames NOT as common in unix the
+  # contents of the file.
+  
+  foreach (<>) {
+    process_file($_);
+  }
+}
+
+
+foreach $module (sort keys %require) {
+  if (length($require{$module}) == 0) {
+    print "perl($module)\n";
+  } else {
+
+    # I am not using rpm3.0 so I do not want spaces around my
+    # operators. Also I will need to change the processing of the
+    # $RPM_* variable when I upgrade.
+
+    print "perl($module)>=$require{$module}\n";
+  }
+}
+
+exit 0;
+
+
+
+sub process_file {
+  
+  my ($file) = @_;
+  chomp $file;
+  
+  open(FILE, "<$file") || return;
+  
+  while (<FILE>) {
+    
+    # skip the "= <<" block
+
+    if ( ( m/^\s*\$(?:.*)\s*=\s*<<\s*(["'`])(.*)\1/) ||
+         ( m/^\s*\$(.*)\s*=\s*<<(\w*)\s*;/) ) {
+      $tag = $2;
+      while (<FILE>) {
+        chomp;
+        ( $_ eq $tag ) && last;
+      }
+      $_ = <FILE>;
+    }
+
+    # skip q{} quoted sections - just hope we don't have curly brackets
+    # within the quote, nor an escaped hash mark that isn't a comment
+    # marker, such as occurs right here. Draw the line somewhere.
+    if ( m/^.*\Wq[qxwr]?\s*([\{\(\[#|\/])[^})\]#|\/]*$/ && ! m/^\s*(require|use)\s/ ) {
+      $tag = $1;
+      $tag =~ tr/{\(\[\#|\//})]#|\//;
+      while (<FILE>) {
+        ( $_ =~ m/\}/ ) && last;
+      }
+    }
+
+    # skip the documentation
+
+    # we should not need to have item in this if statement (it
+    # properly belongs in the over/back section) but people do not
+    # read the perldoc.
+
+    if ( (m/^=(head[1-4]|pod|item)/) .. (m/^=(cut)/) ) {
+      next;
+    }
+
+    if ( (m/^=(over)/) .. (m/^=(back)/) ) {
+      next;
+    }
+    
+    # skip the data section
+    if (m/^__(DATA|END)__$/) {
+      last;
+    }
+
+    # Each keyword can appear multiple times.  Don't
+    #  bother with datastructures to store these strings,
+    #  if we need to print it print it now.
+    #
+       # Again allow for "our".
+    if ( m/^\s*(our\s+)?\$RPM_Requires\s*=\s*["'](.*)['"]/i) {
+      foreach $_ (split(/\s+/, $2)) {
+       print "$_\n";
+      }
+    }
+
+    if ( 
+
+# ouch could be in a eval, perhaps we do not want these since we catch
+# an exception they must not be required
+
+#   eval { require Term::ReadLine } or die $@;
+#   eval "require Term::Rendezvous;" or die $@;
+#   eval { require Carp } if defined $^S; # If error/warning during compilation,
+
+
+       (m/^(\s*)         # we hope the inclusion starts the line
+        (require|use)\s+(?!\{)     # do not want 'do {' loops
+        # quotes around name are always legal
+        [\'\"]?([^\;\ \'\"\t]*)[\'\"]?[\t\;\ ]
+        # the syntax for 'use' allows version requirements
+        \s*([.0-9]*)
+        /x)
+       ) {
+      my ($whitespace, $statement, $module, $version) = ($1, $2, $3,$4);
+
+      # we only consider require statements that are flush against
+      # the left edge. any other require statements give too many
+      # false positives, as they are usually inside of an if statement
+      # as a fallback module or a rarely used option
+
+      ($whitespace ne "" && $statement eq "require") && next;
+
+      # if there is some interpolation of variables just skip this
+      # dependency, we do not want
+      #        do "$ENV{LOGDIR}/$rcfile";
+   
+      ($module =~ m/\$/) && next;
+
+      # skip if the phrase was "use of" -- shows up in gimp-perl, et al.
+      next if $module eq 'of';
+
+      # if the module ends in a comma we probaly caught some
+      # documentation of the form 'check stuff,\n do stuff, clean
+      # stuff.' there are several of these in the perl distribution
+
+      ($module  =~ m/[,>]$/) && next;
+
+      # if the module name starts in a dot it is not a module name.
+      # Is this necessary?  Please give me an example if you turn this
+      # back on.
+
+      #      ($module =~ m/^\./) && next;
+
+      # if the module ends with .pm strip it to leave only basename.
+      # starts with /, which means its an absolute path to a file
+      if ($module =~ m(^/)) {
+        print "$module\n";
+        next;
+      }
+
+      # sometimes people do use POSIX qw(foo), or use POSIX(qw(foo)) etc.
+      # we can strip qw.*$, as well as (.*$:
+      $module =~ s/qw.*$//;
+      $module =~ s/\(.*$//;
+
+      $module =~ s/\.pm$//;
+
+      # some perl programmers write 'require URI/URL;' when 
+      # they mean 'require URI::URL;'
+
+      $module =~ s/\//::/;
+
+      # trim off trailing parentheses if any.  Sometimes people pass
+      # the module an empty list.
+
+      $module =~ s/\(\s*\)$//;
+
+      if ( $module =~ m/^v?([0-9._]+)$/ ) {
+      # if module is a number then both require and use interpret that
+      # to mean that a particular version of perl is specified
+
+      my $ver=$1;
+      if ($ver =~ /5.00/) {
+        print "perl>=0:$ver\n";
+        next;
+      }
+      else {
+        print "perl>=1:$ver\n";
+        next;
+      }
+
+      };
+
+      # ph files do not use the package name inside the file.
+      # perlmodlib documentation says:
+      
+      #       the .ph files made by h2ph will probably end up as
+      #       extension modules made by h2xs.
+      
+      # so do not expend much effort on these.
+
+
+      # there is no easy way to find out if a file named systeminfo.ph
+      # will be included with the name sys/systeminfo.ph so only use the
+      # basename of *.ph files
+
+      ($module  =~ m/\.ph$/) && next;
+
+      $require{$module}=$version;
+      $line{$module}=$_;
+    }
+    
+  }
+
+  close(FILE) ||
+    die("$0: Could not close file: '$file' : $!\n");
+  
+  return ; 
+}
diff --git a/pkgs/core/build-essentials/buildsystem-tools/py-compile b/pkgs/core/build-essentials/buildsystem-tools/py-compile
new file mode 100755 (executable)
index 0000000..66c33ed
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+PYTHON=$(which python 2>/dev/null)
+
+if [ -z "${PYTHON}" ]; then
+       # Python is not present. Fail silently.
+       exit 0
+fi
+
+files=""
+for i in $*; do
+       if [ -e ${i}c ] && [ -e ${i}o ]; then
+               continue # all files we want are already there
+       fi
+       files="$files $i"
+done
+
+if [ -z "${files}" ]; then
+       # No files need to be proceeded.
+       exit 0
+fi
+
+$PYTHON -c "
+import sys, os, string, py_compile
+
+files = '''$files'''
+print 'Byte-compiling python modules...'
+for file in string.split(files):
+    if not os.path.exists(file) or not (len(file) >= 3 and file[-3:] == '.py'):
+        continue
+    print file,
+    sys.stdout.flush()
+    py_compile.compile(file)
+print" || exit $?
+
+# this will fail for python < 1.5, but that doesn't matter ...
+$PYTHON -O -c "
+import sys, os, string, py_compile
+
+files = '''$files'''
+print 'Byte-compiling python modules (optimised versions) ...'
+for file in string.split(files):
+    if not os.path.exists(file) or not (len(file) >= 3 and file[-3:] == '.py'):
+        continue
+    print file,
+    sys.stdout.flush()
+    py_compile.compile(file)
+print" 2>/dev/null || :
index e882ad1b6bd48b17d0a99e142c81c0d6e1d9863e..6eb6dfb2dd65c8ddf51625172af3ad8fa2e02757 100644 (file)
@@ -5,21 +5,18 @@
 #
 ###############################################################################
 
-# If we are running in a chroot, we map all directories to $(BASEDIR), otherwise
-# BASEDIR will be the absolute path (for gathering information from the source
-# packages)
-ifeq "$(CHROOT)" "1"
-       BASEDIR = /usr/src
-endif
+BASEDIR = /build
+
+BUILD_TOOLS = /usr/lib/buildsystem-tools
 
 # Set default directories
 DIR_APP      = $(DIR_SRC)/$(THISAPP)
-DIR_DL       = $(BASEDIR)/cache
+DIR_DL       = $(BASEDIR)/files
 DIR_PACKAGES = /usr/src/packages/$(PKG_ARCH)
-DIR_PATCHES  = $(DIR_SOURCE)/patches
+DIR_PATCHES  = $(BASEDIR)/patches
 DIR_SRC      = /usr/src
 DIR_TMP      = /tmp
-DIR_SOURCE   = $(CURDIR)
+DIR_SOURCE   = $(BASEDIR)
 DIR_TOOLS    = $(BASEDIR)/tools
 
 # Directory where to search for object files
@@ -27,7 +24,7 @@ VPATH        = $(DIR_DL)
 
 # Paths to scripts
 DO_EXTRACT       = tar xaf
-DO_QUALITY_AGENT = $(DIR_TOOLS)/quality-agent
+DO_QUALITY_AGENT = quality-agent
 
 ###############################################################################
 #
@@ -36,11 +33,18 @@ DO_QUALITY_AGENT = $(DIR_TOOLS)/quality-agent
 ###############################################################################
 
 # Export CFLAGS + CXXFLAGS
-export CFLAGS
-export CXXFLAGS
+GLOBAL_CFLAGS = -O2 -g -pipe -Wall -fexceptions --param=ssp-buffer-size=4
+
+CFLAGS_i686   = -m32 -march=i686 -mtune=atom -fasynchronous-unwind-tables
+CFLAGS_x86_64 = -m64 -mtune=generic
+
+export CFLAGS   = $(GLOBAL_CFLAGS) $(CFLAGS_$(DISTRO_ARCH))
+export CXXFLAGS = $(CFLAGS)
 
 # Options that get passed to configure by default
 CONFIGURE_OPTIONS = \
+       --host=$(DISTRO_MACHINE) \
+       --build=$(DISTRO_MACHINE) \
        --prefix=/usr
 
 ###############################################################################
@@ -66,7 +70,7 @@ PKG_VARIABLES = \
        PKG_MAINTAINER \
        PKG_LICENSE \
        PKG_PROVIDES \
-       PKG_REL \
+       PKG_RELEASE \
        PKG_SUMMARY \
        PKG_URL \
        PKG_VER
@@ -87,11 +91,13 @@ export BUILD_ID
 #
 
 # The actual package name (the name of the directory)
-PKG_NAME_REAL  = $(notdir $(CURDIR))
+PKG_NAME_REAL  = $(notdir $(subst .nm,,$(firstword $(MAKEFILE_LIST))))
 PKG_NAME       = $(PKG_NAME_REAL)
 
-# Set default epoch
+# Set default epoch, release and arch
 PKG_EPOCH      = 0
+PKG_RELEASE    = $(PKG_REL).$(DISTRO_DISTTAG)
+PKG_ARCH       = $(DISTRO_ARCH)
 
 # Shortcut to package name + version
 THISAPP        = $(PKG_NAME)-$(PKG_VER)
@@ -124,7 +130,8 @@ PKG_PATCHES += \
        $(foreach patch,$(wildcard $(DIR_PATCHES)/*.diff),$(notdir $(patch)))
 
 # Dynamic command that applies all patches
-DO_PATCHES = cd $(DIR_APP) && $(DIR_TOOLS)/patch $(foreach patch,$(PKG_PATCHES),$(DIR_PATCHES)/$(patch))
+DO_PATCHES = cd $(DIR_APP) && $(BUILD_TOOLS)/patch \
+       $(foreach patch,$(PKG_PATCHES),$(DIR_PATCHES)/$(patch))
 
 # Get a list of files that are installed automatically
 PKG_DEFAULT_FILES  = $(wildcard *.default)
index 42cfa80feecf325e3c62e675e2be19c81df4ce5b..e2efad8d5a7b821f0c6e01af44007c38511bee4a 100644 (file)
@@ -36,6 +36,19 @@ define DO_FILELIST
        @cd $(BUILDROOT) && find -ls
 endef
 
+define DO_PACKAGE_VARIABLE
+       @echo $(if $($(1)-$(2)),$(1)="\"$(strip $($(1)-$(2)))\"",$(1)="\"$(strip $($(1)))\"")
+
+endef
+
+define DO_PACKAGE_INFO
+       @echo "PKG_NAME=\"$(1)\""
+       $(foreach var,$(PKG_VARIABLES),$(call DO_PACKAGE_VARIABLE,$(var),$(1)))
+
+       @echo
+
+endef
+
 define __INSTALL_DEFAULT
        -mkdir -pv $(BUILDROOT)/etc/default
        cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/$(1) $(BUILDROOT)/etc/default/$(subst .default,,$(notdir $(1)))
@@ -67,7 +80,7 @@ define DO_INSTALL_PAM
 endef
 
 define DO_PYTHON_COMPILE
-       @find $(BUILDROOT) -name "*.py" | xargs $(DIR_TOOLS)/py-compile
+       @find $(BUILDROOT) -name "*.py" | xargs $(BUILD_TOOLS)/py-compile
 endef
 
 define DO_FIX_LIBTOOL
index e969f3cd34e81f6872cdfb96e67fd411f02bf135..f9edd84efbd16ffda7065144fde982fa24663c2c 100644 (file)
@@ -5,45 +5,51 @@
 #
 ###############################################################################
 
-.PHONY: info
-info:
-       @echo "PKG_ARCH=\"$(PKG_ARCH)\""
+.PHONY: packageinfo
+packageinfo:
+       $(foreach package,$(PKG_PACKAGES),$(call DO_PACKAGE_INFO,$(package)))
+
+.PHONY: buildinfo
+buildinfo:
+       @echo "PKG_NAME=\"$(PKG_NAME_REAL)\""
+       @echo "PKG_EPOCH=\"$(PKG_EPOCH)\""
+       @echo "PKG_VER=\"$(PKG_VER)\""
+       @echo "PKG_RELEASE=\"$(PKG_RELEASE)\""
+
+       @echo "PKG_ARCH=\"src\""
        @echo "PKG_BUILD_DEPENDENCIES=\"$(PKG_BUILD_DEPS)\""
        @echo "PKG_DEPENDENCIES=\"$(PKG_DEPS)\""
        @echo "PKG_DESCRIPTION=\"$(strip $(PKG_DESCRIPTION))\""
-       @echo "PKG_EPOCH=\"$(PKG_EPOCH)\""
        @echo "PKG_GROUP=\"$(PKG_GROUP)\""
        @echo "PKG_LICENSE=\"$(PKG_LICENSE)\""
        @echo "PKG_MAINTAINER=\"$(PKG_MAINTAINER)\""
-       @echo "PKG_NAME=\"$(PKG_NAME_REAL)\""
-       @echo "PKG_OBJECTS=\"$(strip $(OBJECTS))\""
-       @echo "PKG_PACKAGES=\"$(PKG_PACKAGES)\""
-       @echo "PKG_PACKAGES_FILES=\"$(PKG_PACKAGES_FILES)\""
-       @echo "PKG_PATCHES=\"$(PKG_PATCHES)\""
-       @echo "PKG_VER=\"$(PKG_VER)\""
-       @echo "PKG_REL=\"$(PKG_REL)\""
-       @echo "PKG_SUMMARY=\"$(strip $(PKG_SUMMARY))\""
        @echo "PKG_URL=\"$(PKG_URL)\""
-       @echo "SOURCE_DIR=\"$(DIR_APP)\""
+
+       @echo "PKG_FILES=\"$(PKG_OBJECTS)\""
+       @echo "PKG_BUILD_DEPS=\"$(PKG_BUILD_DEPS)\""
+
+       @echo "CFLAGS=\"$(CFLAGS)\""
+       @echo "CXXFLAGS=\"$(CXXFLAGS)\""
 
 $(OBJECTS):
        @echo "Object file \"$@\" is required." >&2
        @exit 1
 
-.PHONY: build
-build: $(STAGE_DONE)
+.PHONY: package
+package: $(STAGE_DONE)
        $(foreach package,$(call reverse,$(PKG_PACKAGES)),$(call DO_PACKAGE,$(package)))
 
 .PHONY: shell
 shell: $(OBJECTS)
        $(if $(STAGE_PREPARE),$(DO_PREPARE))
 
-prepare:
+.PHONY: prepare
+prepare: $(OBJECTS)
        $(if $(STAGE_PREPARE),$(DO_PREPARE))
 
-$(STAGE_DONE): $(OBJECTS)
+.PHONY: build
+build: $(OBJECTS)
        $(if $(STAGE_PREPARE),$(DO_PREPARE))
        $(if $(STAGE_BUILD),$(DO_BUILD))
        $(if $(STAGE_TEST),$(DO_TEST))
        $(if $(STAGE_INSTALL),$(DO_INSTALL))
-       @touch $@
index 4fe1c472bfa5b1fc0f4a6d842bfb7d4f41abe810..28467338838d548409d568439d2c72abe1fe9203 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 # Include additional functions
-. $(dirname ${0})/../common-functions
+. /usr/lib/buildsystem-tools/common-functions
 
 function debug() {
        [ "${NAOKI_DEBUG}" = "1" ] || [ "${DEBUG}" = "1" ]