This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 3.x development tree".
The branch, master has been updated via 38fffe4c19326678ff4914048fda376a42a59e61 (commit) via 60afce8412c32f212c865a031ce19450ebe26231 (commit) via 4d8505a4b501d10caa1fbca41e8f5682a42708fb (commit) via 3a65898df8b8e154b2f852463c60c0dc99328295 (commit) via de50740ac5777351f97a9b0be12d70247c27be5c (commit) via 972223caa33a1f648c2800638e24215a1608c12a (commit) via 5b0d7bc122889931b73e6f73eda1fe054c45e242 (commit) via 4ea2e3d98fbe50e7cae260a95c329a2f5af6a7f7 (commit) via 235217d273cf7ae9cce69e86459ed57215466254 (commit) via c4b73613eb81488524d45f859c78ab7e23111ffe (commit) via 8c9bc13bf206aa9fa064d82ae4dd869097ab15ce (commit) via 9b924ca43917193507658e90801dc8adac5755d2 (commit) via 54fb3a5ed11efafbcd0c91027a2e33ff7e025e47 (commit) via 43bed62fa45cc624173c8c8ab87db5db900fe509 (commit) via 95cdc7abbd6e0fc587a32631ab068eb970025e7b (commit) from 37bc2396441b67f5a55c2e11dc69c5e7e4971cd6 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 38fffe4c19326678ff4914048fda376a42a59e61 Merge: 37bc239 60afce8 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 15:03:08 2011 +0100
Merge branch 'pakfire3'
commit 60afce8412c32f212c865a031ce19450ebe26231 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 15:01:10 2011 +0100
ncurses: Use configure && make from template.
commit 4d8505a4b501d10caa1fbca41e8f5682a42708fb Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 15:00:47 2011 +0100
ccache: Use DISTRO_MACHINE instead of TARGET.
commit 3a65898df8b8e154b2f852463c60c0dc99328295 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 14:58:43 2011 +0100
naoki: Add DISTRO_MACHINE to be compatible with pakfire3.
commit de50740ac5777351f97a9b0be12d70247c27be5c Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 14:44:07 2011 +0100
util-linux-ng: Requires libsepol-devel for build.
commit 972223caa33a1f648c2800638e24215a1608c12a Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 14:43:10 2011 +0100
zlib: configure does not support --build and --host.
commit 5b0d7bc122889931b73e6f73eda1fe054c45e242 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 14:42:44 2011 +0100
gcc: Respect the --build option.
commit 4ea2e3d98fbe50e7cae260a95c329a2f5af6a7f7 Author: Michael Tremer michael.tremer@ipfire.org Date: Sun Feb 6 14:36:22 2011 +0100
gcc: Move libgcc_s to /lib.
commit 235217d273cf7ae9cce69e86459ed57215466254 Author: Michael Tremer michael.tremer@ipfire.org Date: Sat Feb 5 20:18:31 2011 +0100
build-essentials: Many other changes for the new pakfire build system.
commit c4b73613eb81488524d45f859c78ab7e23111ffe Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 2 19:30:37 2011 +0100
build-essentials: Add patch command.
commit 8c9bc13bf206aa9fa064d82ae4dd869097ab15ce Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 2 18:01:53 2011 +0100
build-essentials: Add chroot-shell.
commit 9b924ca43917193507658e90801dc8adac5755d2 Merge: 54fb3a5 43bed62 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 2 17:58:29 2011 +0100
Merge branch 'pakfire3' of ssh://git.ipfire.org/pub/git/people/ms/ipfire-3.x into pakfire3
commit 54fb3a5ed11efafbcd0c91027a2e33ff7e025e47 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 2 17:58:06 2011 +0100
build-essentials: Add buildsystem includes to package.
commit 43bed62fa45cc624173c8c8ab87db5db900fe509 Author: Michael Tremer michael.tremer@ipfire.org Date: Wed Feb 2 16:47:42 2011 +0100
build-essentials: Add system-release as a dependency.
commit 95cdc7abbd6e0fc587a32631ab068eb970025e7b Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Jan 24 16:47:28 2011 +0100
build-essentials: New package.
-----------------------------------------------------------------------
Summary of changes: naoki/constants.py | 18 +------- pkgs/Constants | 3 + .../build-essentials.nm} | 50 +++++++++++--------- .../buildsystem-tools}/chroot-shell | 6 +- .../buildsystem-tools/common-functions | 0 .../buildsystem-tools/dependency-tracker | 22 +++++++++ .../buildsystem-tools}/functions-common | 0 .../buildsystem-tools}/functions-constants | 0 .../buildsystem-tools}/functions-directories | 0 .../buildsystem-tools}/functions-files | 0 .../buildsystem-tools}/functions-lists | 0 .../buildsystem-tools}/functions-logging | 0 .../buildsystem-tools}/functions-packager-find | 0 .../core/build-essentials/buildsystem-tools}/patch | 0 .../build-essentials/buildsystem-tools}/perl.prov | 0 .../build-essentials/buildsystem-tools}/perl.req | 0 .../build-essentials/buildsystem-tools}/py-compile | 0 pkgs/core/build-essentials/buildsystem.sh | 8 +++ .../build-essentials/buildsystem}/Constants | 39 +++++++++------ .../build-essentials/buildsystem}/Functions | 15 ++++++- .../build-essentials/buildsystem}/Include | 0 .../build-essentials/buildsystem}/Targets | 38 +++++++++------ .../build-essentials/buildsystem}/Templates | 0 .../{ => core/build-essentials/buildsystem}/__gmsl | 0 pkgs/{ => core/build-essentials/buildsystem}/gmsl | 0 .../build-essentials/quality-agent}/quality-agent | 2 +- .../quality-agent.d/001-include-files | 0 .../quality-agent.d/001-remove-info-files | 0 .../quality-agent.d/001-remove-static-libs | 0 .../quality-agent.d/001-unsafe-files | 0 .../quality-agent.d/002-bad-symlinks | 0 .../quality-agent.d/003-libs-location | 0 .../quality-agent}/quality-agent.d/050-canary | 0 .../quality-agent}/quality-agent.d/050-execstacks | 0 .../quality-agent.d/050-invalid-interpreters | 0 .../quality-agent}/quality-agent.d/050-libs-needed | 0 .../quality-agent}/quality-agent.d/050-libs-soname | 0 .../quality-agent}/quality-agent.d/050-nx | 0 .../quality-agent}/quality-agent.d/050-relro | 0 .../quality-agent.d/050-root-links-to-usr | 0 .../quality-agent}/quality-agent.d/050-rpaths | 0 .../quality-agent}/quality-agent.d/090-man-pages | 0 .../quality-agent.d/090-python-hardlinks | 0 .../quality-agent.d/090-remove-empty-dirs | 0 .../quality-agent.d/095-directory-layout | 0 .../quality-agent}/quality-agent.d/099-strip | 0 .../quality-agent}/quality-agent.d/qa-include | 2 +- pkgs/core/ccache/ccache.nm | 2 +- pkgs/core/gcc/gcc.nm | 9 +++- pkgs/core/ncurses/ncurses.nm | 26 ++++------- pkgs/core/util-linux-ng/util-linux-ng.nm | 4 +- pkgs/core/zlib/zlib.nm | 3 +- 52 files changed, 147 insertions(+), 100 deletions(-) copy pkgs/core/{system-release/system-release.nm => build-essentials/build-essentials.nm} (62%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/chroot-shell (76%) copy tools/functions-common => pkgs/core/build-essentials/buildsystem-tools/common-functions (100%) create mode 100755 pkgs/core/build-essentials/buildsystem-tools/dependency-tracker copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-common (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-constants (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-directories (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-files (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-lists (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-logging (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/functions-packager-find (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/patch (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/perl.prov (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/perl.req (100%) copy {tools => pkgs/core/build-essentials/buildsystem-tools}/py-compile (100%) create mode 100644 pkgs/core/build-essentials/buildsystem.sh copy pkgs/{ => core/build-essentials/buildsystem}/Constants (81%) copy pkgs/{ => core/build-essentials/buildsystem}/Functions (93%) copy pkgs/{ => core/build-essentials/buildsystem}/Include (100%) copy pkgs/{ => core/build-essentials/buildsystem}/Targets (71%) copy pkgs/{ => core/build-essentials/buildsystem}/Templates (100%) copy pkgs/{ => core/build-essentials/buildsystem}/__gmsl (100%) copy pkgs/{ => core/build-essentials/buildsystem}/gmsl (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent (80%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/001-include-files (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/001-remove-info-files (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/001-remove-static-libs (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/001-unsafe-files (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/002-bad-symlinks (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/003-libs-location (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-canary (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-execstacks (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-invalid-interpreters (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-libs-needed (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-libs-soname (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-nx (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-relro (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-root-links-to-usr (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/050-rpaths (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/090-man-pages (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/090-python-hardlinks (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/090-remove-empty-dirs (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/095-directory-layout (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/099-strip (100%) copy {tools => pkgs/core/build-essentials/quality-agent}/quality-agent.d/qa-include (96%)
Difference in files: diff --git a/naoki/constants.py b/naoki/constants.py index 72af9aa..e1c2f6c 100644 --- a/naoki/constants.py +++ b/naoki/constants.py @@ -50,23 +50,7 @@ class Config(object): _items = { "toolchain" : False, "mandatory_packages" : [ - "bash", - "bzip2", - "ccache", - "coreutils", - "cpio", - "diffutils", - "file", - "findutils", - "gawk", - "grep", - "gzip", - "make", - "patch", - "sed", - "tar", - "which", - "xz", + "build-essentials", ], "shell_packages" : [ "/bin/bash", diff --git a/pkgs/Constants b/pkgs/Constants index e882ad1..c6b634b 100644 --- a/pkgs/Constants +++ b/pkgs/Constants @@ -43,6 +43,9 @@ export CXXFLAGS CONFIGURE_OPTIONS = \ --prefix=/usr
+# For compatibility with pakfire3 +DISTRO_MACHINE=$(TARGET) + ############################################################################### # # Packager variables diff --git a/pkgs/core/build-essentials/build-essentials.nm b/pkgs/core/build-essentials/build-essentials.nm new file mode 100644 index 0000000..a1d2d60 --- /dev/null +++ b/pkgs/core/build-essentials/build-essentials.nm @@ -0,0 +1,68 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +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 +PKG_URL = http://www.ipfire.org +PKG_LICENSE = GPL +PKG_SUMMARY = Elementary scripts for the build system. + +PKG_BUILD_DEPS = +PKG_DEPS += bash bzip2 ccache coreutils cpio diffutils file findutils \ + gawk grep gzip make patch sed system-release tar which xz + +define PKG_DESCRIPTION + This package contains elementary scripts for the pakfire build system. +endef + +STAGE_PREPARE = # Nothing to do here +STAGE_BUILD = # Nothing to do here + +define STAGE_INSTALL + # Install the quality-agent and buildsystem header files. + -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/* \ + $(BUILDROOT)/usr/lib/quality-agent/ + + -mkdir -pv $(BUILDROOT)/etc/profile.d + cp -vf buildsystem.sh $(BUILDROOT)/etc/profile.d/ + + # 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 index 0000000..0d4a61f --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/chroot-shell @@ -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 index 0000000..4c44a58 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/common-functions @@ -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 index 0000000..5fb9718 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/dependency-tracker @@ -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 index 0000000..4c44a58 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-common @@ -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 index 0000000..396e045 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-constants @@ -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 index 0000000..5b0867b --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-directories @@ -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 index 0000000..41ce3be --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-files @@ -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 index 0000000..d8152d4 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-lists @@ -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 index 0000000..4fd43ed --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-logging @@ -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 index 0000000..bc97483 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/functions-packager-find @@ -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/patch b/pkgs/core/build-essentials/buildsystem-tools/patch new file mode 100755 index 0000000..68fef90 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/patch @@ -0,0 +1,18 @@ +#!/bin/bash + +for patch in $@; do + echo "Applying file ${patch}..." + + if [ "${patch##*/*.}" = "patch0" ]; then + cmd="patch -Np0" + else + cmd="patch -Np1" + fi + + ${cmd} -i ${patch} + ret=$? + + if [ ${ret} -ne 0 ]; then + exit ${ret} + fi +done diff --git a/pkgs/core/build-essentials/buildsystem-tools/perl.prov b/pkgs/core/build-essentials/buildsystem-tools/perl.prov new file mode 100755 index 0000000..73bec51 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/perl.prov @@ -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 index 0000000..d0a1cd7 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/perl.req @@ -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 index 0000000..66c33ed --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem-tools/py-compile @@ -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 || : diff --git a/pkgs/core/build-essentials/buildsystem.sh b/pkgs/core/build-essentials/buildsystem.sh new file mode 100644 index 0000000..6e45524 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem.sh @@ -0,0 +1,8 @@ + +# Path where the include files of the buildsystem +# are located. +export BUILDSYSTEM_ROOT="/usr/lib/buildsystem" + +# XXX just for now, we need to set PKGROOT to be compatible +# with the old makefiles +export PKGROOT=${BUILDSYSTEM_ROOT} diff --git a/pkgs/core/build-essentials/buildsystem/Constants b/pkgs/core/build-essentials/buildsystem/Constants new file mode 100644 index 0000000..6eb6dfb --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/Constants @@ -0,0 +1,155 @@ + +############################################################################### +# +# Constant definitions of the naoki build system +# +############################################################################### + +BASEDIR = /build + +BUILD_TOOLS = /usr/lib/buildsystem-tools + +# Set default directories +DIR_APP = $(DIR_SRC)/$(THISAPP) +DIR_DL = $(BASEDIR)/files +DIR_PACKAGES = /usr/src/packages/$(PKG_ARCH) +DIR_PATCHES = $(BASEDIR)/patches +DIR_SRC = /usr/src +DIR_TMP = /tmp +DIR_SOURCE = $(BASEDIR) +DIR_TOOLS = $(BASEDIR)/tools + +# Directory where to search for object files +VPATH = $(DIR_DL) + +# Paths to scripts +DO_EXTRACT = tar xaf +DO_QUALITY_AGENT = quality-agent + +############################################################################### +# +# Build environment +# +############################################################################### + +# Export CFLAGS + 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 + +############################################################################### +# +# Packager variables +# +############################################################################### +# Variables that get exported (and expanded for the sub-packages) to the +# packager process +PKG_VARIABLES = \ + CONTROL_PREIN \ + CONTROL_PREUN \ + CONTROL_POSTIN \ + CONTROL_POSTUN \ + \ + PKG_ARCH \ + PKG_BUILD_DEPS \ + PKG_DEPS \ + PKG_DESCRIPTION \ + PKG_EPOCH \ + PKG_FILES \ + PKG_GROUP \ + PKG_MAINTAINER \ + PKG_LICENSE \ + PKG_PROVIDES \ + PKG_RELEASE \ + PKG_SUMMARY \ + PKG_URL \ + PKG_VER + +# Variables that exported to the packager process +# These reflect settings from the build system +export BUILD_DATE ?= $(shell date -u) +export BUILD_HOST ?= $(shell cat /proc/sys/kernel/hostname) +export BUILD_ID + +############################################################################### +# +# Package variables +# +############################################################################### +# +# Variables +# + +# The actual package name (the name of the directory) +PKG_NAME_REAL = $(notdir $(subst .nm,,$(firstword $(MAKEFILE_LIST)))) +PKG_NAME = $(PKG_NAME_REAL) + +# 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) +THISVER = $(PKG_EPOCH):$(PKG_VER)-$(PKG_REL) + +# All packages depend on gcc and headers by default. +PKG_BUILD_DEPS+= gcc glibc-devel kernel-headers +PKG_DEPS += + +# All PKG_OBJECTS are downloaded. This is in most cases the tarball. +PKG_OBJECTS = $(PKG_TARBALL) +OBJECTS = $(PKG_OBJECTS) + +# List of packages to build +PKG_PACKAGES = $(PKG_NAME_REAL) + +# +# Macros +# + +# Abstract variable that translates the package names to a list of filenames +PKG_PACKAGES_FILES = $(foreach package,$(PKG_PACKAGES),$(call DO_PACKAGE_FILENAME,$(package))) + +# Automatically detect all patches in "patches" +PKG_PATCHES = \ + $(foreach patch,$(wildcard $(DIR_PATCHES)/*.patch),$(notdir $(patch))) +PKG_PATCHES += \ + $(foreach patch,$(wildcard $(DIR_PATCHES)/*.patch0),$(notdir $(patch))) +PKG_PATCHES += \ + $(foreach patch,$(wildcard $(DIR_PATCHES)/*.diff),$(notdir $(patch))) + +# Dynamic command that applies all patches +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) +PKG_DEFAULT_FILES += $(wildcard default/*) +PKG_INIT_FILES = $(wildcard *.init) +PKG_INIT_FILES += $(wildcard init/*.conf) +PKG_PAM_FILES = $(wildcard *.pam) +PKG_PAM_FILES += $(wildcard pam.d/*) + +############################################################################### +# +# Quality agent +# +############################################################################### + +export QUALITY_AGENT_PERMIT_NOT_FULL_RELRO +export QUALITY_AGENT_RPATH_ALLOW_ORIGIN +export QUALITY_AGENT_WHITELIST_EXECSTACK +export QUALITY_AGENT_WHITELIST_NX +export QUALITY_AGENT_WHITELIST_RPATH +export QUALITY_AGENT_WHITELIST_SONAME diff --git a/pkgs/core/build-essentials/buildsystem/Functions b/pkgs/core/build-essentials/buildsystem/Functions new file mode 100644 index 0000000..e2efad8 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/Functions @@ -0,0 +1,190 @@ + +############################################################################### +# +# Function definitions of the naoki build system +# +############################################################################### + +include $(PKGROOT)/gmsl + +DO_PACKAGE_FILENAME = $(1)$(call DO_PKG_SUFFIX,$(1)) + +DO_PKG_SUFFIX = \ + -$(if $(PKG_VER-$(1)),$(PKG_VER-$(1)),$(PKG_VER))-$(DISTRO_SNAME)$(DISTRO_EPOCH)-$(PKG_ARCH).$(if $(PKG_REL-$(1)),$(PKG_REL-$(1)),$(PKG_REL)).ipk + +define DO_INIT + # Run ldconfig + ldconfig +endef + +define DO_PACKAGE + @echo "#####################################################################" + @echo "# $(1) - Package build started" + @echo "#####################################################################" + + @$(foreach var,$(PKG_VARIABLES),$(if $($(var)-$(1)),$(var)="$(strip $($(var)-$(1)))",$(var)="$(strip $($(var)))")) \ + $(DIR_TOOLS)/packager $(1) $(DIR_PACKAGES)/$(call DO_PACKAGE_FILENAME,$(1)) + + @echo "#####################################################################" + @echo "# $(1) - Package build finished" + @echo "#####################################################################" + +endef + +define DO_FILELIST + @echo "# Filelist dump" + @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))) + +endef + +define DO_INSTALL_DEFAULT + $(foreach file,$(PKG_DEFAULT_FILES),$(call __INSTALL_DEFAULT,$(file))) +endef + +define __INSTALL_INIT + -mkdir -pv $(BUILDROOT)/etc/init + cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/$(1) $(BUILDROOT)/etc/init/$(subst .init,.conf,$(notdir $(1))) + +endef + +define DO_INSTALL_INIT + $(foreach file,$(PKG_INIT_FILES),$(call __INSTALL_INIT,$(file))) +endef + +define __INSTALL_PAM + -mkdir -pv $(BUILDROOT)/etc/pam.d + cd $(DIR_APP) && cp -vf $(DIR_SOURCE)/$(1) $(BUILDROOT)/etc/pam.d/$(subst .pam,,$(notdir $(1))) + +endef + +define DO_INSTALL_PAM + $(foreach file,$(PKG_PAM_FILES),$(call __INSTALL_PAM,$(file))) +endef + +define DO_PYTHON_COMPILE + @find $(BUILDROOT) -name "*.py" | xargs $(BUILD_TOOLS)/py-compile +endef + +define DO_FIX_LIBTOOL + # remove rpath from libtool + @if [ -e "libtool" ]; then \ + sed -i libtool \ + -e 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' \ + -e 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g'; \ + fi +endef + +define DO_PREPARE + # Initialize the environment at the beginning + $(DO_INIT) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Preparation started" + @echo "#####################################################################" + + $(STAGE_PREPARE) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Preparation finished" + @echo "#####################################################################" +endef + +define DO_BUILD + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Build started" + @echo "#####################################################################" + + $(STAGE_BUILD) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Build finished" + @echo "#####################################################################" +endef + +define DO_TEST + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Test started" + @echo "#####################################################################" + + $(STAGE_TEST) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Test finished" + @echo "#####################################################################" +endef + +define DO_INSTALL + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Install started" + @echo "#####################################################################" + + -mkdir -pv $(BUILDROOT) + + $(STAGE_INSTALL) + + $(DO_INSTALL_DEFAULT) + $(DO_INSTALL_INIT) + $(DO_INSTALL_PAM) + + $(DO_PYTHON_COMPILE) + + @echo "#####################################################################" + @echo "# $(PKG_NAME) - Install finished" + @echo "#####################################################################" + + $(DO_QUALITY_AGENT) + $(DO_FILELIST) +endef + +STAGE_PACKAGE_TARGETS = $(call reverse,$(PKG_PACKAGES_FILES)) +STAGE_DONE = $(ROOT)/.done + +define STAGE_PREPARE + $(if $(PKG_TARBALL),cd $(DIR_SRC) && $(DO_EXTRACT) $(DIR_DL)/$(PKG_TARBALL)) + + $(if $(PKG_PATCHES),$(DO_PATCHES)) + + $(STAGE_PREPARE_CMDS) + $(STAGE_PREPARE_CMDS2) +endef + +STAGE_BUILD_TARGETS = + +define STAGE_BUILD + cd $(DIR_APP) && \ + $(CONFIGURE_ENVIRONMENT) \ + ./configure \ + $(CONFIGURE_OPTIONS) + + $(DO_FIX_LIBTOOL) + $(STAGE_CONFIGURE_CMDS) + + cd $(DIR_APP) && make $(STAGE_BUILD_TARGETS) $(PARALLELISMFLAGS) + $(STAGE_BUILD_CMDS) +endef + +STAGE_INSTALL_TARGETS = install + +define STAGE_INSTALL + cd $(DIR_APP) && make $(STAGE_INSTALL_TARGETS) DESTDIR=$(BUILDROOT) + + $(STAGE_INSTALL_CMDS) +endef diff --git a/pkgs/core/build-essentials/buildsystem/Include b/pkgs/core/build-essentials/buildsystem/Include new file mode 100644 index 0000000..a3d62be --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/Include @@ -0,0 +1,26 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007, 2008, 2009 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### + +.SECONDEXPANSION: + +include $(PKGROOT)/Constants +include $(PKGROOT)/Functions +include $(PKGROOT)/Targets +include $(PKGROOT)/Templates diff --git a/pkgs/core/build-essentials/buildsystem/Targets b/pkgs/core/build-essentials/buildsystem/Targets new file mode 100644 index 0000000..f9edd84 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/Targets @@ -0,0 +1,55 @@ + +############################################################################### +# +# Target definitions of the naoki build system +# +############################################################################### + +.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_GROUP="$(PKG_GROUP)"" + @echo "PKG_LICENSE="$(PKG_LICENSE)"" + @echo "PKG_MAINTAINER="$(PKG_MAINTAINER)"" + @echo "PKG_URL="$(PKG_URL)"" + + @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: package +package: $(STAGE_DONE) + $(foreach package,$(call reverse,$(PKG_PACKAGES)),$(call DO_PACKAGE,$(package))) + +.PHONY: shell +shell: $(OBJECTS) + $(if $(STAGE_PREPARE),$(DO_PREPARE)) + +.PHONY: prepare +prepare: $(OBJECTS) + $(if $(STAGE_PREPARE),$(DO_PREPARE)) + +.PHONY: build +build: $(OBJECTS) + $(if $(STAGE_PREPARE),$(DO_PREPARE)) + $(if $(STAGE_BUILD),$(DO_BUILD)) + $(if $(STAGE_TEST),$(DO_TEST)) + $(if $(STAGE_INSTALL),$(DO_INSTALL)) diff --git a/pkgs/core/build-essentials/buildsystem/Templates b/pkgs/core/build-essentials/buildsystem/Templates new file mode 100644 index 0000000..e1196ad --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/Templates @@ -0,0 +1,62 @@ + +############################################################################### +# +# Template definitions of the naoki build system +# +############################################################################### + +############################################################################### +# Default template +############################################################################### + +PKG_PROVIDES-$(PKG_NAME_REAL) = $(PKG_NAME_REAL)=$(THISVER) + +# Package all files by default +PKG_FILES = / + +############################################################################### +# Devel template +############################################################################### + +PKG_DESCRIPTION-$(PKG_NAME_REAL)-devel = Development files of $(THISAPP). +PKG_SUMMARY-$(PKG_NAME_REAL)-devel = $(PKG_DESCRIPTION-$(PKG_NAME_REAL)-devel) + +PKG_DEPS-$(PKG_NAME_REAL)-devel = $(PKG_NAME_REAL)=$(THISVER) + +define PKG_FILES-$(PKG_NAME_REAL)-devel + /usr/bin/*-config + /usr/include + /usr/lib/*.a + /usr/lib/pkgconfig + /usr/share/aclocal + */lib/*.so + /usr/share/*/cmake + /usr/share/man/man2 + /usr/share/man/man3 + /usr/share/vala +endef + + +############################################################################### +# Library template +############################################################################### + +PKG_DESCRIPTION-$(PKG_NAME_REAL)-libs = Library files of $(THISAPP). +PKG_SUMMARY-$(PKG_NAME_REAL)-libs = $(PKG_DESCRIPTION-$(PKG_NAME_REAL)-libs) + +PKG_DEPS-$(PKG_NAME_REAL)-libs = $(PKG_NAME_REAL)=$(THISVER) + +define PKG_FILES-$(PKG_NAME_REAL)-libs + /lib/lib*.so.* + /usr/lib/lib*.so.* +endef + +# Another naming scheme template... +PKG_DESCRIPTION-lib$(PKG_NAME_REAL) = $(PKG_DESCRIPTION-$(PKG_NAME_REAL)-libs) +PKG_SUMMARY-lib$(PKG_NAME_REAL) = $(PKG_SUMMARY-$(PKG_NAME_REAL)-libs) +PKG_FILES-lib$(PKG_NAME_REAL) = $(PKG_FILES-$(PKG_NAME_REAL)-libs) + +PKG_DESCRIPTION-lib$(PKG_NAME_REAL)-devel = $(PKG_DESCRIPTION-$(PKG_NAME_REAL)-devel) +PKG_SUMMARY-lib$(PKG_NAME_REAL)-devel = $(PKG_SUMMARY-$(PKG_NAME_REAL)-devel) +PKG_FILES-lib$(PKG_NAME_REAL)-devel = $(PKG_FILES-$(PKG_NAME_REAL)-devel) blah +PKG_BUILD_DEPS-lib$(PKG_NAME_REAL)-devel = $(PKG_BUILD_DEPS-$(PKG_NAME_REAL)-devel) diff --git a/pkgs/core/build-essentials/buildsystem/__gmsl b/pkgs/core/build-essentials/buildsystem/__gmsl new file mode 100644 index 0000000..596ff19 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/__gmsl @@ -0,0 +1,854 @@ +# ---------------------------------------------------------------------------- +# +# GNU Make Standard Library (GMSL) +# +# A library of functions to be used with GNU Make's $(call) that +# provides functionality not available in standard GNU Make. +# +# Copyright (c) 2005-2007 John Graham-Cumming +# +# This file is part of GMSL +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# Neither the name of the John Graham-Cumming nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# ---------------------------------------------------------------------------- + +# This is the GNU Make Standard Library version number as a list with +# three items: major, minor, revision + +gmsl_version := 1 0 11 + +# Used to output warnings and error from the library, it's possible to +# disable any warnings or errors by overriding these definitions +# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS + +__gmsl_name := GNU Make Standard Library +__gmsl_warning = $(warning $(__gmsl_name): $1) +__gmsl_error = $(error $(__gmsl_name): $1) + +ifdef GMSL_NO_WARNINGS +__gmsl_warning := +endif +ifdef GMSL_NO_ERRORS +__gmsl_error := +endif + +# If GMSL_TRACE is enabled then calls to the library functions are +# traced to stdout using warning messages with their arguments + +ifdef GMSL_TRACE +__gmsl_tr1 = $(warning $0('$1')) +__gmsl_tr2 = $(warning $0('$1','$2')) +__gmsl_tr3 = $(warning $0('$1','$2','$3')) +else +__gmsl_tr1 := +__gmsl_tr2 := +__gmsl_tr3 := +endif + +# Figure out whether we have $(eval) or not (GNU Make 3.80 and above) +# if we do not then output a warning message, if we do then some +# functions will be enabled. + +__gmsl_have_eval := $(false) +__gmsl_ignore := $(eval __gmsl_have_eval := $(true)) + +# If this is being run with Electric Cloud's emake then warn that +# their $(eval) support is incomplete. + +ifdef ECLOUD_BUILD_ID +$(warning You are using Electric Cloud's emake which has incomplete $$(eval) support) +__gmsl_have_eval := $(false) +endif + +# See if we have $(lastword) (GNU Make 3.81 and above) + +__gmsl_have_lastword := $(lastword $(false) $(true)) + +# See if we have native or and and (GNU Make 3.81 and above) + +__gmsl_have_or := $(if $(filter-out undefined, \ + $(origin or)),$(call or,$(true),$(false))) +__gmsl_have_and := $(if $(filter-out undefined, \ + $(origin and)),$(call and,$(true),$(true))) + +ifneq ($(__gmsl_have_eval),$(true)) +$(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled) +endif + +# ---------------------------------------------------------------------------- +# Function: gmsl_compatible +# Arguments: List containing the desired library version number (maj min rev) +# Returns: $(true) if this version of the library is compatible +# with the requested version number, otherwise $(false) +# ---------------------------------------------------------------------------- +gmsl_compatible = $(strip \ + $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))), \ + $(false), \ + $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))), \ + $(true), \ + $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))), \ + $(false), \ + $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))), \ + $(true), \ + $(call lte,$(word 3,$1),$(word 3,$(gmsl_version)))))))) + +# ########################################################################### +# LOGICAL OPERATORS +# ########################################################################### + +# not is defined in gmsl + +# ---------------------------------------------------------------------------- +# Function: and +# Arguments: Two boolean values +# Returns: Returns $(true) if both of the booleans are true +# ---------------------------------------------------------------------------- +ifneq ($(__gmsl_have_and),$(true)) +and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false)) +endif + +# ---------------------------------------------------------------------------- +# Function: or +# Arguments: Two boolean values +# Returns: Returns $(true) if either of the booleans is true +# ---------------------------------------------------------------------------- +ifneq ($(__gmsl_have_or),$(true)) +or = $(__gmsl_tr2)$(if $1$2,$(true),$(false)) +endif + +# ---------------------------------------------------------------------------- +# Function: xor +# Arguments: Two boolean values +# Returns: Returns $(true) if exactly one of the booleans is true +# ---------------------------------------------------------------------------- +xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false))) + +# ---------------------------------------------------------------------------- +# Function: nand +# Arguments: Two boolean values +# Returns: Returns value of 'not and' +# ---------------------------------------------------------------------------- +nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true)) + +# ---------------------------------------------------------------------------- +# Function: nor +# Arguments: Two boolean values +# Returns: Returns value of 'not or' +# ---------------------------------------------------------------------------- +nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true)) + +# ---------------------------------------------------------------------------- +# Function: xnor +# Arguments: Two boolean values +# Returns: Returns value of 'not xor' +# ---------------------------------------------------------------------------- +xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true))) + +# ########################################################################### +# LIST MANIPULATION FUNCTIONS +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Function: first (same as LISP's car, or head) +# Arguments: 1: A list +# Returns: Returns the first element of a list +# ---------------------------------------------------------------------------- +first = $(__gmsl_tr1)$(firstword $1) + +# ---------------------------------------------------------------------------- +# Function: last +# Arguments: 1: A list +# Returns: Returns the last element of a list +# ---------------------------------------------------------------------------- +ifeq ($(__gmsl_have_lastword),$(true)) +last = $(__gmsl_tr1)$(lastword $1) +else +last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1)) +endif + +# ---------------------------------------------------------------------------- +# Function: rest (same as LISP's cdr, or tail) +# Arguments: 1: A list +# Returns: Returns the list with the first element removed +# ---------------------------------------------------------------------------- +rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1) + +# ---------------------------------------------------------------------------- +# Function: chop +# Arguments: 1: A list +# Returns: Returns the list with the last element removed +# ---------------------------------------------------------------------------- +chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1) + +# ---------------------------------------------------------------------------- +# Function: map +# Arguments: 1: Name of function to $(call) for each element of list +# 2: List to iterate over calling the function in 1 +# Returns: The list after calling the function on each element +# ---------------------------------------------------------------------------- +map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a))) + +# ---------------------------------------------------------------------------- +# Function: pairmap +# Arguments: 1: Name of function to $(call) for each pair of elements +# 2: List to iterate over calling the function in 1 +# 3: Second list to iterate over calling the function in 1 +# Returns: The list after calling the function on each pair of elements +# ---------------------------------------------------------------------------- +pairmap = $(strip $(__gmsl_tr3)\ + $(if $2$3,$(call $1,$(call first,$2),$(call first,$3)) \ + $(call pairmap,$1,$(call rest,$2),$(call rest,$3)))) + +# ---------------------------------------------------------------------------- +# Function: leq +# Arguments: 1: A list to compare against... +# 2: ...this list +# Returns: Returns $(true) if the two lists are identical +# ---------------------------------------------------------------------------- +leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)), \ + $(call __gmsl_list_equal,$1,$2),$(false))) + +__gmsl_list_equal = $(if $(strip $1), \ + $(if $(call seq,$(call first,$1),$(call first,$2)), \ + $(call __gmsl_list_equal, \ + $(call rest,$1), \ + $(call rest,$2)), \ + $(false)), \ + $(true)) + +# ---------------------------------------------------------------------------- +# Function: lne +# Arguments: 1: A list to compare against... +# 2: ...this list +# Returns: Returns $(true) if the two lists are different +# ---------------------------------------------------------------------------- +lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2)) + +# ---------------------------------------------------------------------------- +# Function: reverse +# Arguments: 1: A list to reverse +# Returns: The list with its elements in reverse order +# ---------------------------------------------------------------------------- +reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \ + $(call first,$1))) + +# ---------------------------------------------------------------------------- +# Function: uniq +# Arguments: 1: A list from which to remove repeated elements +# Returns: The list with duplicate elements removed without reordering +# ---------------------------------------------------------------------------- +uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \ + $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1)))) + +# ---------------------------------------------------------------------------- +# Function: length +# Arguments: 1: A list +# Returns: The number of elements in the list +# ---------------------------------------------------------------------------- +length = $(__gmsl_tr1)$(words $1) + +# ########################################################################### +# STRING MANIPULATION FUNCTIONS +# ########################################################################### + +# Helper function that translates any GNU Make 'true' value (i.e. a +# non-empty string) to our $(true) + +__gmsl_make_bool = $(if $(strip $1),$(true),$(false)) + +# ---------------------------------------------------------------------------- +# Function: seq +# Arguments: 1: A string to compare against... +# 2: ...this string +# Returns: Returns $(true) if the two strings are identical +# ---------------------------------------------------------------------------- +seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true)) + +# ---------------------------------------------------------------------------- +# Function: sne +# Arguments: 1: A string to compare against... +# 2: ...this string +# Returns: Returns $(true) if the two strings are not the same +# ---------------------------------------------------------------------------- +sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2)) + +# ---------------------------------------------------------------------------- +# Function: split +# Arguments: 1: The character to split on +# 2: A string to split +# Returns: Splits a string into a list separated by spaces at the split +# character in the first argument +# ---------------------------------------------------------------------------- +split = $(__gmsl_tr2)$(strip $(subst $1, ,$2)) + +# ---------------------------------------------------------------------------- +# Function: merge +# Arguments: 1: The character to put between fields +# 2: A list to merge into a string +# Returns: Merges a list into a single string, list elements are separated +# by the character in the first argument +# ---------------------------------------------------------------------------- +merge = $(__gmsl_tr2)$(strip $(if $2, \ + $(if $(call seq,1,$(words $2)), \ + $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2))))) + +ifdef __gmsl_have_eval +# ---------------------------------------------------------------------------- +# Function: tr +# Arguments: 1: The list of characters to translate from +# 2: The list of characters to translate to +# 3: The text to translate +# Returns: Returns the text after translating characters +# ---------------------------------------------------------------------------- +tr = $(strip $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3) \ + $(eval __gmsl_t := $3) \ + $(foreach c, \ + $(join $(addsuffix :,$1),$2), \ + $(eval __gmsl_t := \ + $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \ + $(__gmsl_t))))$(__gmsl_t)) + +# Common character classes for use with the tr function. Each of +# these is actually a variable declaration and must be wrapped with +# $() or ${} to be used. + +[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z # +[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z # +[0-9] := 0 1 2 3 4 5 6 7 8 9 # +[A-F] := A B C D E F # + +# ---------------------------------------------------------------------------- +# Function: uc +# Arguments: 1: Text to upper case +# Returns: Returns the text in upper case +# ---------------------------------------------------------------------------- +uc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([a-z]),$([A-Z]),$1) + +# ---------------------------------------------------------------------------- +# Function: lc +# Arguments: 1: Text to lower case +# Returns: Returns the text in lower case +# ---------------------------------------------------------------------------- +lc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([A-Z]),$([a-z]),$1) + +# ---------------------------------------------------------------------------- +# Function: strlen +# Arguments: 1: A string +# Returns: Returns the length of the string +# ---------------------------------------------------------------------------- +__gmsl_characters := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +__gmsl_characters += a b c d e f g h i j k l m n o p q r s t u v w x y z +__gmsl_characters += 0 1 2 3 4 5 6 7 8 9 +__gmsl_characters += ` ~ ! @ # $$ % ^ & * ( ) - _ = + +__gmsl_characters += { } [ ] \ : ; ' " < > , . / ? | + +# Aside: if you read the above you might think that the lower-case +# letter x is missing, and that that's an error. It is missing, but +# it's not an error. __gmsl_characters is used by the strlen +# function. strlen works by transforming every character and space +# into the letter x and then counting the x's. Since there's no need +# to transform x into x I omitted it. + +# This results in __gmsl_space containing just a space + +__gmsl_space := +__gmsl_space += + +strlen = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(eval __temp := $(subst $(__gmsl_space),x,$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,x,$(__temp))))$(eval __temp := $(subst x,x ,$(__temp)))$(words $(__temp))) + +# This results in __gmsl_newline containing just a newline + +define __gmsl_newline + + +endef + +# This results in __gmsl_tab containing a tab + +__gmsl_tab := # + +# ---------------------------------------------------------------------------- +# Function: substr +# Arguments: 1: A string +# 2: Start position (first character is 1) +# 3: End position (inclusive) +# Returns: A substring. +# Note: The string in $1 must not contain a § +# ---------------------------------------------------------------------------- + +substr = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(strip $(eval __temp := $$(subst $$(__gmsl_space),§ ,$$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,$$a$$(__gmsl_space),$(__temp))))$(eval __temp := $(wordlist $2,$3,$(__temp))))$(subst §,$(__gmsl_space),$(subst $(__gmsl_space),,$(__temp))) + +endif # __gmsl_have_eval + +# ########################################################################### +# SET MANIPULATION FUNCTIONS +# ########################################################################### + +# Sets are represented by sorted, deduplicated lists. To create a set +# from a list use set_create, or start with the empty_set and +# set_insert individual elements + +# This is the empty set +empty_set := + +# ---------------------------------------------------------------------------- +# Function: set_create +# Arguments: 1: A list of set elements +# Returns: Returns the newly created set +# ---------------------------------------------------------------------------- +set_create = $(__gmsl_tr1)$(sort $1) + +# ---------------------------------------------------------------------------- +# Function: set_insert +# Arguments: 1: A single element to add to a set +# 2: A set +# Returns: Returns the set with the element added +# ---------------------------------------------------------------------------- +set_insert = $(__gmsl_tr2)$(sort $1 $2) + +# ---------------------------------------------------------------------------- +# Function: set_remove +# Arguments: 1: A single element to remove from a set +# 2: A set +# Returns: Returns the set with the element removed +# ---------------------------------------------------------------------------- +set_remove = $(__gmsl_tr2)$(filter-out $1,$2) + +# ---------------------------------------------------------------------------- +# Function: set_is_member +# Arguments: 1: A single element +# 2: A set +# Returns: Returns $(true) if the element is in the set +# ---------------------------------------------------------------------------- +set_is_member = $(__gmsl_tr2)$(if $(filter $1,$2),$(true),$(false)) + +# ---------------------------------------------------------------------------- +# Function: set_union +# Arguments: 1: A set +# 2: Another set +# Returns: Returns the union of the two sets +# ---------------------------------------------------------------------------- +set_union = $(__gmsl_tr2)$(sort $1 $2) + +# ---------------------------------------------------------------------------- +# Function: set_intersection +# Arguments: 1: A set +# 2: Another set +# Returns: Returns the intersection of the two sets +# ---------------------------------------------------------------------------- +set_intersection = $(__gmsl_tr2)$(filter $1,$2) + +# ---------------------------------------------------------------------------- +# Function: set_is_subset +# Arguments: 1: A set +# 2: Another set +# Returns: Returns $(true) if the first set is a subset of the second +# ---------------------------------------------------------------------------- +set_is_subset = $(__gmsl_tr2)$(call set_equal,$(call set_intersection,$1,$2),$1) + +# ---------------------------------------------------------------------------- +# Function: set_equal +# Arguments: 1: A set +# 2: Another set +# Returns: Returns $(true) if the two sets are identical +# ---------------------------------------------------------------------------- +set_equal = $(__gmsl_tr2)$(call seq,$1,$2) + +# ########################################################################### +# ARITHMETIC LIBRARY +# ########################################################################### + +# Integers a represented by lists with the equivalent number of x's. +# For example the number 4 is x x x x. The maximum integer that the +# library can handle as _input_ is __gmsl_input_int which is defined +# here as 65536 + +__gmsl_sixteen := x x x x x x x x x x x x x x x x +__gmsl_input_int := $(foreach a,$(__gmsl_sixteen), \ + $(foreach b,$(__gmsl_sixteen), \ + $(foreach c,$(__gmsl_sixteen), \ + $(__gmsl_sixteen))))) + +# ---------------------------------------------------------------------------- +# Function: int_decode +# Arguments: 1: A number of x's representation +# Returns: Returns the integer for human consumption that is represented +# by the string of x's +# ---------------------------------------------------------------------------- +int_decode = $(__gmsl_tr1)$(words $1) + +# ---------------------------------------------------------------------------- +# Function: int_encode +# Arguments: 1: A number in human-readable integer form +# Returns: Returns the integer encoded as a string of x's +# ---------------------------------------------------------------------------- +int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int)) + +# The arithmetic library functions come in two forms: one form of each +# function takes integers as arguments and the other form takes the +# encoded form (x's created by a call to int_encode). For example, +# there are two plus functions: +# +# plus Called with integer arguments and returns an integer +# int_plus Called with encoded arguments and returns an encoded result +# +# plus will be slower than int_plus because its arguments and result +# have to be translated between the x's format and integers. If doing +# a complex calculation use the int_* forms with a single encoding of +# inputs and single decoding of the output. For simple calculations +# the direct forms can be used. + +# Helper function used to wrap an int_* function into a function that +# takes a pair of integers, perhaps a function and returns an integer +# result +__gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3))) +__gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2))) +__gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3)) + +# ---------------------------------------------------------------------------- +# Function: int_plus +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the sum of the two numbers in x's representation +# ---------------------------------------------------------------------------- +int_plus = $(strip $(__gmsl_tr2)$1 $2) + +# ---------------------------------------------------------------------------- +# Function: plus (wrapped version of int_plus) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the sum of the two integers +# ---------------------------------------------------------------------------- +plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_subtract +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the difference of the two numbers in x's representation, +# or outputs an error on a numeric underflow +# ---------------------------------------------------------------------------- +int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \ + $(filter-out xx,$(join $1,$2)), \ + $(call __gmsl_warning,Subtraction underflow))) + +# ---------------------------------------------------------------------------- +# Function: subtract (wrapped version of int_subtract) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the difference of the two integers, +# or outputs an error on a numeric underflow +# ---------------------------------------------------------------------------- +subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_multiply +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the product of the two numbers in x's representation +# ---------------------------------------------------------------------------- +int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2)) + +# ---------------------------------------------------------------------------- +# Function: multiply (wrapped version of int_multiply) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the product of the two integers +# ---------------------------------------------------------------------------- +multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_divide +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the result of integer division of argument 1 divided +# by argument 2 in x's representation +# ---------------------------------------------------------------------------- +int_divide = $(__gmsl_tr2)$(strip $(if $2, \ + $(if $(call int_gte,$1,$2), \ + x $(call int_divide,$(call int_subtract,$1,$2),$2),), \ + $(call __gmsl_error,Division by zero))) + +# ---------------------------------------------------------------------------- +# Function: divide (wrapped version of int_divide) +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the integer division of the first argument by the second +# ---------------------------------------------------------------------------- +divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_max, int_min +# Arguments: 1: A number in x's representation +# 2: Another number in x's represntation +# Returns: Returns the maximum or minimum of its arguments in x's +# representation +# ---------------------------------------------------------------------------- +int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2)) +int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2))) + +# ---------------------------------------------------------------------------- +# Function: max, min +# Arguments: 1: An integer +# 2: Another integer +# Returns: Returns the maximum or minimum of its integer arguments +# ---------------------------------------------------------------------------- +max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2) +min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2) + +# ---------------------------------------------------------------------------- +# Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne +# Arguments: Two x's representation numbers to be compared +# Returns: $(true) or $(false) +# +# int_gt First argument greater than second argument +# int_gte First argument greater than or equal to second argument +# int_lt First argument less than second argument +# int_lte First argument less than or equal to second argument +# int_eq First argument is numerically equal to the second argument +# int_ne First argument is not numerically equal to the second argument +# ---------------------------------------------------------------------------- +int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter-out $(words $2), \ + $(words $(call int_max,$1,$2)))) +int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(call int_gt,$1,$2)$(call int_eq,$1,$2)) +int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter-out $(words $1), \ + $(words $(call int_max,$1,$2)))) +int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(call int_lt,$1,$2)$(call int_eq,$1,$2)) +int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter $(words $1),$(words $2))) +int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool, \ + $(filter-out $(words $1),$(words $2))) + +# ---------------------------------------------------------------------------- +# Function: gt, gte, lt, lte, eq, ne +# Arguments: Two integers to be compared +# Returns: $(true) or $(false) +# +# gt First argument greater than second argument +# gte First argument greater than or equal to second argument +# lt First argument less than second argument +# lte First argument less than or equal to second argument +# eq First argument is numerically equal to the second argument +# ne First argument is not numerically equal to the second argument +# ---------------------------------------------------------------------------- +gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2) +gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2) +lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2) +lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2) +eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2) +ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2) + +# increment adds 1 to its argument, decrement subtracts 1. Note that +# decrement does not range check and hence will not underflow, but +# will incorrectly say that 0 - 1 = 0 + +# ---------------------------------------------------------------------------- +# Function: int_inc +# Arguments: 1: A number in x's representation +# Returns: The number incremented by 1 in x's representation +# ---------------------------------------------------------------------------- +int_inc = $(strip $(__gmsl_tr1)$1 x) + +# ---------------------------------------------------------------------------- +# Function: inc +# Arguments: 1: An integer +# Returns: The argument incremented by 1 +# ---------------------------------------------------------------------------- +inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1) + +# ---------------------------------------------------------------------------- +# Function: int_dec +# Arguments: 1: A number in x's representation +# Returns: The number decremented by 1 in x's representation +# ---------------------------------------------------------------------------- +int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \ + $(wordlist 2,$(words $1),$1), \ + $(call __gmsl_warning,Decrement underflow))) + +# ---------------------------------------------------------------------------- +# Function: dec +# Arguments: 1: An integer +# Returns: The argument decremented by 1 +# ---------------------------------------------------------------------------- +dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1) + +# double doubles its argument, and halve halves it + +# ---------------------------------------------------------------------------- +# Function: int_double +# Arguments: 1: A number in x's representation +# Returns: The number doubled (i.e. * 2) and returned in x's representation +# ---------------------------------------------------------------------------- +int_double = $(strip $(__gmsl_tr1)$1 $1) + +# ---------------------------------------------------------------------------- +# Function: double +# Arguments: 1: An integer +# Returns: The integer times 2 +# ---------------------------------------------------------------------------- +double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1) + +# ---------------------------------------------------------------------------- +# Function: int_halve +# Arguments: 1: A number in x's representation +# Returns: The number halved (i.e. / 2) and returned in x's representation +# ---------------------------------------------------------------------------- +int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \ + $(join $1,$(foreach a,$1,y x))))) + +# ---------------------------------------------------------------------------- +# Function: halve +# Arguments: 1: An integer +# Returns: The integer divided by 2 +# ---------------------------------------------------------------------------- +halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1) + +ifdef __gmsl_have_eval +# ########################################################################### +# ASSOCIATIVE ARRAYS +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Function: set +# Arguments: 1: Name of associative array +# 2: The key value to associate +# 3: The value associated with the key +# Returns: None +# ---------------------------------------------------------------------------- +set = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(eval __gmsl_aa_$1_$2 = $3) + +# ---------------------------------------------------------------------------- +# Function: get +# Arguments: 1: Name of associative array +# 2: The key to retrieve +# Returns: The value stored in the array for that key +# ---------------------------------------------------------------------------- +get = $(strip $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \ + $(__gmsl_aa_$1_$2))) + +# ---------------------------------------------------------------------------- +# Function: keys +# Arguments: 1: Name of associative array +# Returns: Returns a list of all defined keys in the array +# ---------------------------------------------------------------------------- +keys = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(sort $(patsubst __gmsl_aa_$1_%,%, \ + $(filter __gmsl_aa_$1_%,$(.VARIABLES)))) + +# ---------------------------------------------------------------------------- +# Function: defined +# Arguments: 1: Name of associative array +# 2: The key to test +# Returns: Returns true if the key is defined (i.e. not empty) +# ---------------------------------------------------------------------------- +defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),) + +endif # __gmsl_have_eval + +ifdef __gmsl_have_eval +# ########################################################################### +# NAMED STACKS +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Function: push +# Arguments: 1: Name of stack +# 2: Value to push onto the top of the stack (must not contain +# a space) +# Returns: None +# ---------------------------------------------------------------------------- +push = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\ + $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1))) + +# ---------------------------------------------------------------------------- +# Function: pop +# Arguments: 1: Name of stack +# Returns: Top element from the stack after removing it +# ---------------------------------------------------------------------------- +pop = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \ + $(call first,$(__gmsl_stack_$1)) \ + $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1))))) + +# ---------------------------------------------------------------------------- +# Function: peek +# Arguments: 1: Name of stack +# Returns: Top element from the stack without removing it +# ---------------------------------------------------------------------------- +peek = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call first,$(__gmsl_stack_$1)) + +# ---------------------------------------------------------------------------- +# Function: depth +# Arguments: 1: Name of stack +# Returns: Number of items on the stack +# ---------------------------------------------------------------------------- +depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1)) + +endif # __gmsl_have_eval + +# ########################################################################### +# DEBUGGING FACILITIES +# ########################################################################### + +# ---------------------------------------------------------------------------- +# Target: gmsl-print-% +# Arguments: The % should be replaced by the name of a variable that you +# wish to print out. +# Action: Echos the name of the variable that matches the % and its value. +# For example, 'make gmsl-print-SHELL' will output the value of +# the SHELL variable +# ---------------------------------------------------------------------------- +gmsl-print-%: ; @echo $* = $($*) + +# ---------------------------------------------------------------------------- +# Function: assert +# Arguments: 1: A boolean that must be true or the assertion will fail +# 2: The message to print with the assertion +# Returns: None +# ---------------------------------------------------------------------------- +assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2)) + +# ---------------------------------------------------------------------------- +# Function: assert_exists +# Arguments: 1: Name of file that must exist, if it is missing an assertion +# will be generated +# Returns: None +# ---------------------------------------------------------------------------- +assert_exists = $(call assert,$(wildcard $1),file '$1' missing) + +# ---------------------------------------------------------------------------- +# Function: assert_no_dollar +# Arguments: 1: Name of a function being executd +# 2: Arguments to check +# Returns: None +# ---------------------------------------------------------------------------- +assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument) diff --git a/pkgs/core/build-essentials/buildsystem/gmsl b/pkgs/core/build-essentials/buildsystem/gmsl new file mode 100644 index 0000000..2ff2897 --- /dev/null +++ b/pkgs/core/build-essentials/buildsystem/gmsl @@ -0,0 +1,89 @@ +# ---------------------------------------------------------------------------- +# +# GNU Make Standard Library (GMSL) +# +# A library of functions to be used with GNU Make's $(call) that +# provides functionality not available in standard GNU Make. +# +# Copyright (c) 2005-2008 John Graham-Cumming +# +# This file is part of GMSL +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# Neither the name of the John Graham-Cumming nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# ---------------------------------------------------------------------------- + +# Determine if the library has already been included and if so don't +# bother including it again + +ifndef __gmsl_included + +# Standard definitions for true and false. true is any non-empty +# string, false is an empty string. These are intended for use with +# $(if). + +true := T +false := + +# ---------------------------------------------------------------------------- +# Function: not +# Arguments: 1: A boolean value +# Returns: Returns the opposite of the arg. (true -> false, false -> true) +# ---------------------------------------------------------------------------- +not = $(if $1,$(false),$(true)) + +# Prevent reinclusion of the library + +__gmsl_included := $(true) + +# Try to determine where this file is located. If the caller did +# include /foo/gmsl then extract the /foo/ so that __gmsl gets +# included transparently + +ifneq ($(MAKEFILE_LIST),) +__gmsl_root := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) + +# If there are any spaces in the path in __gmsl_root then give up + +ifeq (1,$(words $(__gmsl_root))) +__gmsl_root := $(patsubst %gmsl,%,$(__gmsl_root)) +else +__gmsl_root := +endif + +include $(__gmsl_root)__gmsl + +else + +include __gmsl + +endif + +endif # __gmsl_included + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent b/pkgs/core/build-essentials/quality-agent/quality-agent new file mode 100755 index 0000000..a83a1a3 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent @@ -0,0 +1,12 @@ +#!/bin/bash + +DIR_QA=/usr/lib/quality-agent + +failed=0 +for file in ${DIR_QA}/*; do + [ -x "${file}" ] || continue + + ${file} || failed=1 +done + +exit ${failed} diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-include-files b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-include-files new file mode 100755 index 0000000..34257e6 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-include-files @@ -0,0 +1,16 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Include files have to belong to the root user. \ + This script will fix this automatically." + +check() { + if [ ! -d "${BUILDROOT}/usr/include" ]; then + return 0 + fi + + chown -R root:root ${BUILDROOT}/usr/include +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-remove-info-files b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-remove-info-files new file mode 100755 index 0000000..e742dc9 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-remove-info-files @@ -0,0 +1,17 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Remove documentation files." + +function check() { + for dir in ${BUILDROOT}/usr/{,share}/{doc,gtk-doc,info}; do + if [ -d "${dir}" ]; then + log DEBUG " Removing: ${dir}" + rm -rf ${dir} || exit $? + fi + done +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-remove-static-libs b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-remove-static-libs new file mode 100755 index 0000000..e5c6e54 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-remove-static-libs @@ -0,0 +1,24 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Removing unwanted files: *.a *.la" + +function check() { + for file in $(find ${BUILDROOT} -name "*.a" -or -name "*.la"); do + + # Don't remove libc_nonshared.a. It is used by gcc/ld. + [ "${file##*/}" = "libc_nonshared.a" ] && continue + [ "${file##*/}" = "libpthread_nonshared.a" ] && continue + [ "${file##*/}" = "libgcc.a" ] && continue + [ "${file##*/}" = "libgcc_eh.a" ] && continue + [ "${file##*/}" = "libfl_pic.a" ] && continue + [ "${file##*/}" = "libpython2.6.a" ] && continue + + log DEBUG " Removing: ${file}" + rm -f ${file} || exit $? + done +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-unsafe-files b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-unsafe-files new file mode 100755 index 0000000..93a5dc8 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/001-unsafe-files @@ -0,0 +1,33 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Searching for world-writeable files..." + +function check() { + local ret=0 + + local files=$(find ${BUILDROOT} -type f -perm -2 2>/dev/null) + if [ -n "${files}" ]; then + log ERROR " QA Security Notice:" + log ERROR " - The folloing files will be world writable." + log ERROR " - This may or may not be a security problem, most of the time it is one." + log ERROR " - Please double check that these files really need a world writeable bit and file bugs accordingly." + log ERROR + log ERROR "${files}" + ret=1 + fi + + files=$(find ${BUILDROOT} -type f '(' -perm -2002 -o -perm -4002 ')') + if [ -n "${files}" ]; then + log ERROR " QA Notice: Unsafe files detected (set*id and world writable)" + log ERROR + log ERROR "${files}" + ret=1 + fi + + return ${ret} +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/002-bad-symlinks b/pkgs/core/build-essentials/quality-agent/quality-agent.d/002-bad-symlinks new file mode 100755 index 0000000..595a7c5 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/002-bad-symlinks @@ -0,0 +1,33 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +# Check for absolute symlinks. +# We do not allow them because they may point to any bad location. + +log_debug "Search for absolute symlinks" + +function check() { + local failed=0 + + for link in $(find ${BUILDROOT} -type l); do + if fgrep -q "/lib/udev/devices" <<<${link}; then + continue + fi + + destination=$(readlink ${link}) + if [ "${destination:0:1}" = "/" ]; then + log ERROR " Absolute symlink: ${link}" + failed=1 + fi + if [ ! -e "${link%/*}/${destination}" ]; then + log ERROR " Not existant destination: ${link} -> ${destination}" + failed=1 + fi + done + + return ${failed} +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/003-libs-location b/pkgs/core/build-essentials/quality-agent/quality-agent.d/003-libs-location new file mode 100755 index 0000000..185f44f --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/003-libs-location @@ -0,0 +1,23 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Checking correct installation of libraries" + +function check() { + local failed=0 + for lib in $(find ${BUILDROOT}/lib -type f -name "lib*.so.*" 2>/dev/null); do + lib=${lib##*/} + lib=${lib%%.so*} + + if [ ! -e "${BUILDROOT}/usr/lib/${lib}.so" ]; then + log ERROR " /usr/lib/${lib}.so is missing" + failed=1 + fi + done + + return ${failed} +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-canary b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-canary new file mode 100755 index 0000000..67b25e5 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-canary @@ -0,0 +1,28 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Every binary file has to provide a canary." + +function check() { + local failed=0 + + local file + for file in $(find_elf_files --prefix=${BUILDROOT} ${BINARY_PATHS}); do + if filter_startfiles ${file}; then + continue + fi + + if ! file_has_canary ${file}; then + log_warning " Has no canary: ${file}" + failed=1 + fi + done + + # This is currently disabled and will only return a warning ! + failed=0 + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-execstacks b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-execstacks new file mode 100755 index 0000000..9540eee --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-execstacks @@ -0,0 +1,22 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Files with executable stacks will not work properly (or at all!) \ + on some architectures/operating systems." + +check() { + local failed=0 + + local file + for file in $(find_elf_files --prefix=${BUILDROOT} ${BINARY_PATHS}); do + if file_has_execstack ${file}; then + log_error " File has execstack: ${file}" + failed=1 + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-invalid-interpreters b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-invalid-interpreters new file mode 100755 index 0000000..09d0ba5 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-invalid-interpreters @@ -0,0 +1,44 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Detect invalid interpreters." + +check() { + local failed=0 + + local file + local interpreter + for file in $(find ${BUILDROOT} -type f 2>/dev/null); do + # If a file is not executeable we don't need to check it + [ -x "${file}" ] || continue + + if file_is_script ${file}; then + interpreter=$(file_get_interpreter ${file}) + + if grep -q /usr/local <<<${interpreter}; then + failed=1 + log_error " Interpreter in /usr/local: ${file}" + fi + + # Search for bad /usr/bin/env + if [ "$(basename ${interpreter})" = "env" ]; then + # Autofix that crap + sed -i ${file} \ + -e "s,/usr/bin/env python...,/usr/bin/python," \ + -e "s,/usr/bin/env python,/usr/bin/python," \ + -e "s,/usr/bin/env perl,/usr/bin/perl," + + # If we could not fix it, raise an error + if [ "${interpreter}" = "$(file_get_interpreter ${file})" ]; then + failed=1 + log_error " Script uses forbidden "env" interpreter: ${file}" + fi + fi + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-libs-needed b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-libs-needed new file mode 100755 index 0000000..93f600d --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-libs-needed @@ -0,0 +1,31 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Every shared object has to provide the NEEDED entry." + +check() { + local failed=0 + + local file + local needed + for file in $(find_elf_files --prefix=${BUILDROOT} ${LIBARY_PATHS}); do + if ! file_is_shared_object ${file}; then + continue + fi + + if ! file_has_interpreter ${file}; then + continue + fi + + needed=$(file_get_needed ${file}) + if [ -z "${needed}" ]; then + log_error " File lacks needed attribute: ${file}" + failed=1 + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-libs-soname b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-libs-soname new file mode 100755 index 0000000..b6232b6 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-libs-soname @@ -0,0 +1,35 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Every shared object has to provide the SONAME entry." + +check() { + local failed=0 + + local file + local soname + for file in $(find_elf_files --prefix=${BUILDROOT} ${LIBARY_PATHS}); do + if ! grep -q ".so" <<<${file}; then + continue + fi + + if ! file_is_shared_object ${file}; then + continue + fi + + if ! file_has_interpreter ${file}; then + continue + fi + + soname=$(file_get_soname ${file}) + if [ -z "${soname}" ]; then + log_error " File lacks soname attribute: ${file}" + failed=1 + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-nx b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-nx new file mode 100755 index 0000000..c9c2733 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-nx @@ -0,0 +1,25 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +function check() { + local failed=0 + + FILTER="${QUALITY_AGENT_WHITELIST_NX}" + + local file + for file in $(find_elf_files --prefix=${BUILDROOT} ${BINARY_PATHS}); do + if filtered ${file}; then + continue + fi + + if ! file_has_nx ${file}; then + log_error " No NX: ${file}" + failed=1 + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-relro b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-relro new file mode 100755 index 0000000..f011056 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-relro @@ -0,0 +1,32 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Text relocations force the dynamic linker to perform extra \ + work at startup, waste system resources, and may pose a security \ + risk. On some architectures, the code may not even function \ + properly, if at all." + +function check() { + local failed=0 + + local file + for file in $(find_elf_files --prefix=${BUILDROOT} ${BINARY_PATHS}); do + if filter_startfiles ${file}; then + continue + fi + + if ! file_is_relro_full ${file}; then + if [ "${QUALITY_AGENT_PERMIT_NOT_FULL_RELRO}" = "yes" ]; then + log_warning " Is not full relro: ${file}" + else + log_error " Is not relro: ${file}" + failed=1 + fi + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-root-links-to-usr b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-root-links-to-usr new file mode 100755 index 0000000..98385c5 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-root-links-to-usr @@ -0,0 +1,31 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Check for binaries in /bin or /sbin that link to /usr/..." + +function check() { + local ret=0 + + for file in $(find ${BUILDROOT}/{bin,lib,sbin}/* 2>/dev/null); do + [ -f "${file}" ] || continue + log DEBUG " ${file}" + + interpreter=$(file_get_interpreter ${file}) + if [ ! -e "${interpreter}" ]; then + log WARN " SKIPPED because interpreter is not available" + continue + fi + + libs=$(ldd ${file}) + if grep -q /usr/lib <<<${libs}; then + log ERROR "${file} links to libs in /usr/lib..." + log ERROR " ${libs}" + ret=1 + fi + done + + return ${ret} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-rpaths b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-rpaths new file mode 100755 index 0000000..8250612 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/050-rpaths @@ -0,0 +1,36 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Searching for RPATHs. We don't want paths that point to the tree where \ + the package was built (older, broken libtools would do this). \ + Also check for null paths because the loader will search $PWD when it \ + finds null paths." + +check() { + local failed=0 + + local file + local rpath + for file in $(find_elf_files --prefix=${BUILDROOT} ${BINARY_PATHS}); do + if filtered ${file}; then + continue + fi + + rpath=$(file_get_rpath ${file}) + if [ -n "${rpath}" ]; then + if [ "${QUALITY_AGENT_RPATH_ALLOW_ORIGIN}" = "yes" ]; then + [ "${rpath}" = '$ORIGIN' ] && continue + fi + if listmatch ${rpath} ${QUALITY_AGENT_WHITELIST_RPATH}; then + continue + fi + log_error " File has unallowed rpath: ${file} - ${rpath}" + failed=1 + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-man-pages b/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-man-pages new file mode 100755 index 0000000..0720d10 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-man-pages @@ -0,0 +1,17 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Decompressing man-pages..." + +function check() { + for file in $(find ${BUILDROOT}/usr/share/man -type f 2>/dev/null); do + log DEBUG " Processing: ${file}" + if [[ ${file} =~ .gz$ ]]; then + gzip -d ${file} + fi + done +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-python-hardlinks b/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-python-hardlinks new file mode 100755 index 0000000..e2abf76 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-python-hardlinks @@ -0,0 +1,20 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Python byte-code files could be hardlinked if the optimized one is equal" +DESC="${DESC} to the other one." + +function check() { + for py in $(find ${BUILDROOT} -type f -name "*.py"); do + if [ -e "${py}c" ] && [ -e "${py}o" ]; then + if cmp -s "${py}c" "${py}o"; then + log DEBUG " ${py}c -> ${py}o" + ln -f "${py}c" "${py}o" + fi + fi + done +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-remove-empty-dirs b/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-remove-empty-dirs new file mode 100755 index 0000000..d1d61a1 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/090-remove-empty-dirs @@ -0,0 +1,18 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Remove unwanted files." + +function check() { + for dir in $(sort_by_length {,/usr}/{{,s}bin,lib{,exec}} /usr/share/man{,/man{0,1,2,3,4,5,6,7,8,9}}); do + dir="${BUILDROOT}/${dir}" + if [ -d "${dir}" ] && [ "$(ls -1A ${dir} | wc -l)" = "0" ]; then + log DEBUG " Removing ${dir}" + rm -rf ${dir} + fi + done +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/095-directory-layout b/pkgs/core/build-essentials/quality-agent/quality-agent.d/095-directory-layout new file mode 100755 index 0000000..14f600d --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/095-directory-layout @@ -0,0 +1,23 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="The filelayout should comply to the FHS." + +DIRS="/etc/init.d /etc/rc.d /lib/pkgconfig /usr/etc /usr/libexec /usr/local /usr/man /usr/usr /usr/var" + +function check() { + local failed=0 + + local dir + for dir in ${DIRS}; do + if [ -d "${BUILDROOT}${dir}" ]; then + log_error "Bad directory: ${dir}" + failed=1 + fi + done + + return ${failed} +} + +run diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/099-strip b/pkgs/core/build-essentials/quality-agent/quality-agent.d/099-strip new file mode 100755 index 0000000..bd7a16a --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/099-strip @@ -0,0 +1,23 @@ +#!/bin/bash + +. $(dirname ${0})/qa-include + +DESC="Stripping reduces size of binary files." + +function check() { + # Strip debugging symbols + for f in $(find ${BUILDROOT} -type f ( -perm -0100 -or -perm -0010 -or -perm -0001 )); do + if (file $f | grep -q ' shared object,'); then + strip --strip-debug "$f" || : + fi + done + + for f in $(find ${BUILDROOT} -type f); do + if (file $f | grep -q ' shared object,'); then + strip --strip-unneeded "$f" || : + fi + done +} + +run + diff --git a/pkgs/core/build-essentials/quality-agent/quality-agent.d/qa-include b/pkgs/core/build-essentials/quality-agent/quality-agent.d/qa-include new file mode 100644 index 0000000..2846733 --- /dev/null +++ b/pkgs/core/build-essentials/quality-agent/quality-agent.d/qa-include @@ -0,0 +1,90 @@ +#!/bin/bash + +# Include additional functions +. /usr/lib/buildsystem-tools/common-functions + +function debug() { + [ "${NAOKI_DEBUG}" = "1" ] || [ "${DEBUG}" = "1" ] +} + +#function log() { +# local facility=${1} +# shift +# +# printf " %-7s %s\n" "${facility}" "$@" +#} + +function log_debug() { + debug && log DEBUG "$@" +} + +function log_error() { + log "ERROR" "$@" +} + +function log_info() { + log "INFO" "$@" +} + +function log_warning() { + log "WARNING" "$@" +} + +if [ -z "${BUILDROOT}" ]; then + echo "${0##*/}: ERROR: BUILDROOT is not set." >&2 + exit 1 +fi + +function filtered() { + [ -z "${FILTER}" ] && return 1 + grep -qE ${FILTER} <<<$@ +} + +function print_description() { + # Remove all whitespaces + local desc=$(echo ${DESC}) + + log_info "Check: $(basename ${0})" + IFS=' +' + for line in $(fold -s -w 60 <<<${desc}); do + log_info " ${line}" + done + log_info # Empty line + + unset IFS +} + +function qa_find() { + local filetype=${1} + local command=${2} + + log_debug "Running qa_find with command ${command} in ${filetype}" + + local file + for file in $(find_elf_files --prefix=${BUILDROOT} ${!filetype}); do + ${command} ${file} + done +} + +function check() { + log_error "REPLACE THIS FUNCTION BY A CUSTOM CHECK" + return 1 +} + +function run() { + local error_message + local ret + + error_message=$(check) + ret=$? + + [ -z "${error_message}" ] && \ + [ "${ret}" = "0" ] && return 0 + + print_description + + echo "${error_message}" + return ${ret} +} + diff --git a/pkgs/core/ccache/ccache.nm b/pkgs/core/ccache/ccache.nm index 3c55710..375d23b 100644 --- a/pkgs/core/ccache/ccache.nm +++ b/pkgs/core/ccache/ccache.nm @@ -66,7 +66,7 @@ define STAGE_INSTALL_CMDS mkdir -pv $(BUILDROOT)/usr/lib/ccache for i in gcc g++ cc c++; do \ ln -svf ../../bin/ccache $(BUILDROOT)/usr/lib/ccache/$${i}; \ - ln -svf ../../bin/ccache $(BUILDROOT)/usr/lib/ccache/$(TARGET)-$${i}; \ + ln -svf ../../bin/ccache $(BUILDROOT)/usr/lib/ccache/$(DISTRO_MACHINE)-$${i}; \ done
-mkdir -pv $(BUILDROOT)/etc/profile.d diff --git a/pkgs/core/gcc/gcc.nm b/pkgs/core/gcc/gcc.nm index 8b2b4f4..92d3a5b 100644 --- a/pkgs/core/gcc/gcc.nm +++ b/pkgs/core/gcc/gcc.nm @@ -26,7 +26,7 @@ include $(PKGROOT)/Include
PKG_NAME = gcc PKG_VER = 4.5.2 -PKG_REL = 0 +PKG_REL = 2
PKG_MAINTAINER = Michael Tremer michael.tremer@ipfire.org PKG_GROUP = Development/Compilers @@ -67,7 +67,7 @@ endef # libgcc PKG_PACKAGES += libgcc define PKG_FILES-libgcc - /usr/lib/libgcc*.so.* + /lib/libgcc*.so.* endef
PKG_PACKAGES += libgcc-devel @@ -146,6 +146,7 @@ define STAGE_BUILD TCFLAGS="$(CFLAGS)" \ ../$(THISAPP)/configure \ $(CONFIG_CPU) \ + --build=$(DISTRO_MACHINE) \ --prefix=/usr \ --libexecdir=/usr/lib \ --mandir=/usr/share/man \ @@ -179,6 +180,10 @@ define STAGE_INSTALL ln -sfv ../usr/bin/cpp $(BUILDROOT)/lib/cpp ln -sfv gcc $(BUILDROOT)/usr/bin/cc
+ # Move libgcc_s to /lib + mv -vf $(BUILDROOT)/usr/lib/libgcc_s.so.1 $(BUILDROOT)/lib/ + ln -svf ../../lib/libgcc_s.so.1 $(BUILDROOT)/usr/lib/libgcc_s.so + # Remove some GNU debugger stuff. rm -vf $(BUILDROOT)/usr/lib/lib*.py endef diff --git a/pkgs/core/ncurses/ncurses.nm b/pkgs/core/ncurses/ncurses.nm index 251a8f1..487c899 100644 --- a/pkgs/core/ncurses/ncurses.nm +++ b/pkgs/core/ncurses/ncurses.nm @@ -47,24 +47,16 @@ PKG_TARBALL = $(THISAPP).tar.gz
PKG_PACKAGES += $(PKG_NAME_REAL)-devel
-define STAGE_BUILD - cd $(DIR_APP) && \ - ./configure \ - --prefix=/usr \ - --mandir=/usr/share/man \ - --with-shared \ - --without-debug \ - --enable-widec \ - --disable-static \ - --enable-symlinks \ - --disable-root-environ - - cd $(DIR_APP) && make $(PARALLELISMFLAGS) -endef - -define STAGE_INSTALL - cd $(DIR_APP) && make install DESTDIR=$(BUILDROOT) +CONFIGURE_OPTIONS += \ + --mandir=/usr/share/man \ + --with-shared \ + --without-debug \ + --enable-widec \ + --disable-static \ + --enable-symlinks \ + --disable-root-environ
+define STAGE_INSTALL_CMDS -mkdir -pv $(BUILDROOT)/lib mv -v $(BUILDROOT)/usr/lib/libncursesw.so.5* $(BUILDROOT)/lib ln -sfv ../../lib/libncursesw.so.5 $(BUILDROOT)/usr/lib/libncursesw.so diff --git a/pkgs/core/util-linux-ng/util-linux-ng.nm b/pkgs/core/util-linux-ng/util-linux-ng.nm index 7ae6390..fd803fc 100644 --- a/pkgs/core/util-linux-ng/util-linux-ng.nm +++ b/pkgs/core/util-linux-ng/util-linux-ng.nm @@ -34,8 +34,8 @@ PKG_URL = ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng PKG_LICENSE = GPLv2 and GPLv2+ and BSD with advertising and Public Domain PKG_SUMMARY = A collection of basic system utilities.
-PKG_BUILD_DEPS+= audit-devel gettext libcap-devel libselinux-devel ncurses-devel\ - pam-devel zlib-devel +PKG_BUILD_DEPS+= audit-devel gettext libcap-devel libselinux-devel \ + libsepol-devel ncurses-devel pam-devel zlib-devel
define PKG_DESCRIPTION The util-linux-ng package contains a large variety of low-level system \ diff --git a/pkgs/core/zlib/zlib.nm b/pkgs/core/zlib/zlib.nm index 3771ab5..28ab0f9 100644 --- a/pkgs/core/zlib/zlib.nm +++ b/pkgs/core/zlib/zlib.nm @@ -47,7 +47,8 @@ CFLAGS += -fPIC -DPIC
CONFIGURE_ENVIRONMENT += ac_cv_func_working_mktime=yes
-CONFIGURE_OPTIONS += \ +CONFIGURE_OPTIONS = \ + --prefix=/usr \ --libdir=/lib
PARALLELISMFLAGS = # No parallelism
hooks/post-receive -- IPFire 3.x development tree