Pacman-dev
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- 4 participants
- 7337 discussions
14 Nov '18
tap-driver.sh is added to the build tree by autoreconf, and contains
upstream modifications as such. This results in dirty working trees.
It was originally added in commit 403c175dbc84a8198b92bbe76f66eade613cff48
which made the testsuite use automake, but as far as I can tell, never
served any purpose.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
build-aux/tap-driver.sh | 652 ----------------------------------------
1 file changed, 652 deletions(-)
delete mode 100755 build-aux/tap-driver.sh
diff --git a/build-aux/tap-driver.sh b/build-aux/tap-driver.sh
deleted file mode 100755
index 19aa531d..00000000
--- a/build-aux/tap-driver.sh
+++ /dev/null
@@ -1,652 +0,0 @@
-#! /bin/sh
-# Copyright (C) 2011-2013 Free Software Foundation, Inc.
-#
-# 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 2, 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/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake(a)gnu.org> or send patches to
-# <automake-patches(a)gnu.org>.
-
-scriptversion=2011-12-27.17; # UTC
-
-# Make unconditional expansion of undefined variables an error. This
-# helps a lot in preventing typo-related bugs.
-set -u
-
-me=tap-driver.sh
-
-fatal ()
-{
- echo "$me: fatal: $*" >&2
- exit 1
-}
-
-usage_error ()
-{
- echo "$me: $*" >&2
- print_usage >&2
- exit 2
-}
-
-print_usage ()
-{
- cat <<END
-Usage:
- tap-driver.sh --test-name=NAME --log-file=PATH --trs-file=PATH
- [--expect-failure={yes|no}] [--color-tests={yes|no}]
- [--enable-hard-errors={yes|no}] [--ignore-exit]
- [--diagnostic-string=STRING] [--merge|--no-merge]
- [--comments|--no-comments] [--] TEST-COMMAND
-The \`--test-name', \`--log-file' and \`--trs-file' options are mandatory.
-END
-}
-
-# TODO: better error handling in option parsing (in particular, ensure
-# TODO: $log_file, $trs_file and $test_name are defined).
-test_name= # Used for reporting.
-log_file= # Where to save the result and output of the test script.
-trs_file= # Where to save the metadata of the test run.
-expect_failure=0
-color_tests=0
-merge=0
-ignore_exit=0
-comments=0
-diag_string='#'
-while test $# -gt 0; do
- case $1 in
- --help) print_usage; exit $?;;
- --version) echo "$me $scriptversion"; exit $?;;
- --test-name) test_name=$2; shift;;
- --log-file) log_file=$2; shift;;
- --trs-file) trs_file=$2; shift;;
- --color-tests) color_tests=$2; shift;;
- --expect-failure) expect_failure=$2; shift;;
- --enable-hard-errors) shift;; # No-op.
- --merge) merge=1;;
- --no-merge) merge=0;;
- --ignore-exit) ignore_exit=1;;
- --comments) comments=1;;
- --no-comments) comments=0;;
- --diagnostic-string) diag_string=$2; shift;;
- --) shift; break;;
- -*) usage_error "invalid option: '$1'";;
- esac
- shift
-done
-
-test $# -gt 0 || usage_error "missing test command"
-
-case $expect_failure in
- yes) expect_failure=1;;
- *) expect_failure=0;;
-esac
-
-if test $color_tests = yes; then
- init_colors='
- color_map["red"]="[0;31m" # Red.
- color_map["grn"]="[0;32m" # Green.
- color_map["lgn"]="[1;32m" # Light green.
- color_map["blu"]="[1;34m" # Blue.
- color_map["mgn"]="[0;35m" # Magenta.
- color_map["std"]="[m" # No color.
- color_for_result["ERROR"] = "mgn"
- color_for_result["PASS"] = "grn"
- color_for_result["XPASS"] = "red"
- color_for_result["FAIL"] = "red"
- color_for_result["XFAIL"] = "lgn"
- color_for_result["SKIP"] = "blu"'
-else
- init_colors=''
-fi
-
-# :; is there to work around a bug in bash 3.2 (and earlier) which
-# does not always set '$?' properly on redirection failure.
-# See the Autoconf manual for more details.
-:;{
- (
- # Ignore common signals (in this subshell only!), to avoid potential
- # problems with Korn shells. Some Korn shells are known to propagate
- # to themselves signals that have killed a child process they were
- # waiting for; this is done at least for SIGINT (and usually only for
- # it, in truth). Without the `trap' below, such a behaviour could
- # cause a premature exit in the current subshell, e.g., in case the
- # test command it runs gets terminated by a SIGINT. Thus, the awk
- # script we are piping into would never seen the exit status it
- # expects on its last input line (which is displayed below by the
- # last `echo $?' statement), and would thus die reporting an internal
- # error.
- # For more information, see the Autoconf manual and the threads:
- # <http://lists.gnu.org/archive/html/bug-autoconf/2011-09/msg00004.html>
- # <http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2009-Februa…>
- trap : 1 3 2 13 15
- if test $merge -gt 0; then
- exec 2>&1
- else
- exec 2>&3
- fi
- "$@"
- echo $?
- ) | LC_ALL=C ${AM_TAP_AWK-awk} \
- -v me="$me" \
- -v test_script_name="$test_name" \
- -v log_file="$log_file" \
- -v trs_file="$trs_file" \
- -v expect_failure="$expect_failure" \
- -v merge="$merge" \
- -v ignore_exit="$ignore_exit" \
- -v comments="$comments" \
- -v diag_string="$diag_string" \
-'
-# FIXME: the usages of "cat >&3" below could be optimized when using
-# FIXME: GNU awk, and/on on systems that supports /dev/fd/.
-
-# Implementation note: in what follows, `result_obj` will be an
-# associative array that (partly) simulates a TAP result object
-# from the `TAP::Parser` perl module.
-
-## ----------- ##
-## FUNCTIONS ##
-## ----------- ##
-
-function fatal(msg)
-{
- print me ": " msg | "cat >&2"
- exit 1
-}
-
-function abort(where)
-{
- fatal("internal error " where)
-}
-
-# Convert a boolean to a "yes"/"no" string.
-function yn(bool)
-{
- return bool ? "yes" : "no";
-}
-
-function add_test_result(result)
-{
- if (!test_results_index)
- test_results_index = 0
- test_results_list[test_results_index] = result
- test_results_index += 1
- test_results_seen[result] = 1;
-}
-
-# Whether the test script should be re-run by "make recheck".
-function must_recheck()
-{
- for (k in test_results_seen)
- if (k != "XFAIL" && k != "PASS" && k != "SKIP")
- return 1
- return 0
-}
-
-# Whether the content of the log file associated to this test should
-# be copied into the "global" test-suite.log.
-function copy_in_global_log()
-{
- for (k in test_results_seen)
- if (k != "PASS")
- return 1
- return 0
-}
-
-# FIXME: this can certainly be improved ...
-function get_global_test_result()
-{
- if ("ERROR" in test_results_seen)
- return "ERROR"
- if ("FAIL" in test_results_seen || "XPASS" in test_results_seen)
- return "FAIL"
- all_skipped = 1
- for (k in test_results_seen)
- if (k != "SKIP")
- all_skipped = 0
- if (all_skipped)
- return "SKIP"
- return "PASS";
-}
-
-function stringify_result_obj(result_obj)
-{
- if (result_obj["is_unplanned"] || result_obj["number"] != testno)
- return "ERROR"
-
- if (plan_seen == LATE_PLAN)
- return "ERROR"
-
- if (result_obj["directive"] == "TODO")
- return result_obj["is_ok"] ? "XPASS" : "XFAIL"
-
- if (result_obj["directive"] == "SKIP")
- return result_obj["is_ok"] ? "SKIP" : COOKED_FAIL;
-
- if (length(result_obj["directive"]))
- abort("in function stringify_result_obj()")
-
- return result_obj["is_ok"] ? COOKED_PASS : COOKED_FAIL
-}
-
-function decorate_result(result)
-{
- color_name = color_for_result[result]
- if (color_name)
- return color_map[color_name] "" result "" color_map["std"]
- # If we are not using colorized output, or if we do not know how
- # to colorize the given result, we should return it unchanged.
- return result
-}
-
-function report(result, details)
-{
- if (result ~ /^(X?(PASS|FAIL)|SKIP|ERROR)/)
- {
- msg = ": " test_script_name
- add_test_result(result)
- }
- else if (result == "#")
- {
- msg = " " test_script_name ":"
- }
- else
- {
- abort("in function report()")
- }
- if (length(details))
- msg = msg " " details
- # Output on console might be colorized.
- print decorate_result(result) msg
- # Log the result in the log file too, to help debugging (this is
- # especially true when said result is a TAP error or "Bail out!").
- print result msg | "cat >&3";
-}
-
-function testsuite_error(error_message)
-{
- report("ERROR", "- " error_message)
-}
-
-function handle_tap_result()
-{
- details = result_obj["number"];
- if (length(result_obj["description"]))
- details = details " " result_obj["description"]
-
- if (plan_seen == LATE_PLAN)
- {
- details = details " # AFTER LATE PLAN";
- }
- else if (result_obj["is_unplanned"])
- {
- details = details " # UNPLANNED";
- }
- else if (result_obj["number"] != testno)
- {
- details = sprintf("%s # OUT-OF-ORDER (expecting %d)",
- details, testno);
- }
- else if (result_obj["directive"])
- {
- details = details " # " result_obj["directive"];
- if (length(result_obj["explanation"]))
- details = details " " result_obj["explanation"]
- }
-
- report(stringify_result_obj(result_obj), details)
-}
-
-# `skip_reason` should be empty whenever planned > 0.
-function handle_tap_plan(planned, skip_reason)
-{
- planned += 0 # Avoid getting confused if, say, `planned` is "00"
- if (length(skip_reason) && planned > 0)
- abort("in function handle_tap_plan()")
- if (plan_seen)
- {
- # Error, only one plan per stream is acceptable.
- testsuite_error("multiple test plans")
- return;
- }
- planned_tests = planned
- # The TAP plan can come before or after *all* the TAP results; we speak
- # respectively of an "early" or a "late" plan. If we see the plan line
- # after at least one TAP result has been seen, assume we have a late
- # plan; in this case, any further test result seen after the plan will
- # be flagged as an error.
- plan_seen = (testno >= 1 ? LATE_PLAN : EARLY_PLAN)
- # If testno > 0, we have an error ("too many tests run") that will be
- # automatically dealt with later, so do not worry about it here. If
- # $plan_seen is true, we have an error due to a repeated plan, and that
- # has already been dealt with above. Otherwise, we have a valid "plan
- # with SKIP" specification, and should report it as a particular kind
- # of SKIP result.
- if (planned == 0 && testno == 0)
- {
- if (length(skip_reason))
- skip_reason = "- " skip_reason;
- report("SKIP", skip_reason);
- }
-}
-
-function extract_tap_comment(line)
-{
- if (index(line, diag_string) == 1)
- {
- # Strip leading `diag_string` from `line`.
- line = substr(line, length(diag_string) + 1)
- # And strip any leading and trailing whitespace left.
- sub("^[ \t]*", "", line)
- sub("[ \t]*$", "", line)
- # Return what is left (if any).
- return line;
- }
- return "";
-}
-
-# When this function is called, we know that line is a TAP result line,
-# so that it matches the (perl) RE "^(not )?ok\b".
-function setup_result_obj(line)
-{
- # Get the result, and remove it from the line.
- result_obj["is_ok"] = (substr(line, 1, 2) == "ok" ? 1 : 0)
- sub("^(not )?ok[ \t]*", "", line)
-
- # If the result has an explicit number, get it and strip it; otherwise,
- # automatically assing the next progresive number to it.
- if (line ~ /^[0-9]+$/ || line ~ /^[0-9]+[^a-zA-Z0-9_]/)
- {
- match(line, "^[0-9]+")
- # The final `+ 0` is to normalize numbers with leading zeros.
- result_obj["number"] = substr(line, 1, RLENGTH) + 0
- line = substr(line, RLENGTH + 1)
- }
- else
- {
- result_obj["number"] = testno
- }
-
- if (plan_seen == LATE_PLAN)
- # No further test results are acceptable after a "late" TAP plan
- # has been seen.
- result_obj["is_unplanned"] = 1
- else if (plan_seen && testno > planned_tests)
- result_obj["is_unplanned"] = 1
- else
- result_obj["is_unplanned"] = 0
-
- # Strip trailing and leading whitespace.
- sub("^[ \t]*", "", line)
- sub("[ \t]*$", "", line)
-
- # This will have to be corrected if we have a "TODO"/"SKIP" directive.
- result_obj["description"] = line
- result_obj["directive"] = ""
- result_obj["explanation"] = ""
-
- if (index(line, "#") == 0)
- return # No possible directive, nothing more to do.
-
- # Directives are case-insensitive.
- rx = "[ \t]*#[ \t]*([tT][oO][dD][oO]|[sS][kK][iI][pP])[ \t]*"
-
- # See whether we have the directive, and if yes, where.
- pos = match(line, rx "$")
- if (!pos)
- pos = match(line, rx "[^a-zA-Z0-9_]")
-
- # If there was no TAP directive, we have nothing more to do.
- if (!pos)
- return
-
- # Let`s now see if the TAP directive has been escaped. For example:
- # escaped: ok \# SKIP
- # not escaped: ok \\# SKIP
- # escaped: ok \\\\\# SKIP
- # not escaped: ok \ # SKIP
- if (substr(line, pos, 1) == "#")
- {
- bslash_count = 0
- for (i = pos; i > 1 && substr(line, i - 1, 1) == "\\"; i--)
- bslash_count += 1
- if (bslash_count % 2)
- return # Directive was escaped.
- }
-
- # Strip the directive and its explanation (if any) from the test
- # description.
- result_obj["description"] = substr(line, 1, pos - 1)
- # Now remove the test description from the line, that has been dealt
- # with already.
- line = substr(line, pos)
- # Strip the directive, and save its value (normalized to upper case).
- sub("^[ \t]*#[ \t]*", "", line)
- result_obj["directive"] = toupper(substr(line, 1, 4))
- line = substr(line, 5)
- # Now get the explanation for the directive (if any), with leading
- # and trailing whitespace removed.
- sub("^[ \t]*", "", line)
- sub("[ \t]*$", "", line)
- result_obj["explanation"] = line
-}
-
-function get_test_exit_message(status)
-{
- if (status == 0)
- return ""
- if (status !~ /^[1-9][0-9]*$/)
- abort("getting exit status")
- if (status < 127)
- exit_details = ""
- else if (status == 127)
- exit_details = " (command not found?)"
- else if (status >= 128 && status <= 255)
- exit_details = sprintf(" (terminated by signal %d?)", status - 128)
- else if (status > 256 && status <= 384)
- # We used to report an "abnormal termination" here, but some Korn
- # shells, when a child process die due to signal number n, can leave
- # in $? an exit status of 256+n instead of the more standard 128+n.
- # Apparently, both behaviours are allowed by POSIX (2008), so be
- # prepared to handle them both. See also Austing Group report ID
- # 0000051 <http://www.austingroupbugs.net/view.php?id=51>
- exit_details = sprintf(" (terminated by signal %d?)", status - 256)
- else
- # Never seen in practice.
- exit_details = " (abnormal termination)"
- return sprintf("exited with status %d%s", status, exit_details)
-}
-
-function write_test_results()
-{
- print ":global-test-result: " get_global_test_result() > trs_file
- print ":recheck: " yn(must_recheck()) > trs_file
- print ":copy-in-global-log: " yn(copy_in_global_log()) > trs_file
- for (i = 0; i < test_results_index; i += 1)
- print ":test-result: " test_results_list[i] > trs_file
- close(trs_file);
-}
-
-BEGIN {
-
-## ------- ##
-## SETUP ##
-## ------- ##
-
-'"$init_colors"'
-
-# Properly initialized once the TAP plan is seen.
-planned_tests = 0
-
-COOKED_PASS = expect_failure ? "XPASS": "PASS";
-COOKED_FAIL = expect_failure ? "XFAIL": "FAIL";
-
-# Enumeration-like constants to remember which kind of plan (if any)
-# has been seen. It is important that NO_PLAN evaluates "false" as
-# a boolean.
-NO_PLAN = 0
-EARLY_PLAN = 1
-LATE_PLAN = 2
-
-testno = 0 # Number of test results seen so far.
-bailed_out = 0 # Whether a "Bail out!" directive has been seen.
-
-# Whether the TAP plan has been seen or not, and if yes, which kind
-# it is ("early" is seen before any test result, "late" otherwise).
-plan_seen = NO_PLAN
-
-## --------- ##
-## PARSING ##
-## --------- ##
-
-is_first_read = 1
-
-while (1)
- {
- # Involutions required so that we are able to read the exit status
- # from the last input line.
- st = getline
- if (st < 0) # I/O error.
- fatal("I/O error while reading from input stream")
- else if (st == 0) # End-of-input
- {
- if (is_first_read)
- abort("in input loop: only one input line")
- break
- }
- if (is_first_read)
- {
- is_first_read = 0
- nextline = $0
- continue
- }
- else
- {
- curline = nextline
- nextline = $0
- $0 = curline
- }
- # Copy any input line verbatim into the log file.
- print | "cat >&3"
- # Parsing of TAP input should stop after a "Bail out!" directive.
- if (bailed_out)
- continue
-
- # TAP test result.
- if ($0 ~ /^(not )?ok$/ || $0 ~ /^(not )?ok[^a-zA-Z0-9_]/)
- {
- testno += 1
- setup_result_obj($0)
- handle_tap_result()
- }
- # TAP plan (normal or "SKIP" without explanation).
- else if ($0 ~ /^1\.\.[0-9]+[ \t]*$/)
- {
- # The next two lines will put the number of planned tests in $0.
- sub("^1\\.\\.", "")
- sub("[^0-9]*$", "")
- handle_tap_plan($0, "")
- continue
- }
- # TAP "SKIP" plan, with an explanation.
- else if ($0 ~ /^1\.\.0+[ \t]*#/)
- {
- # The next lines will put the skip explanation in $0, stripping
- # any leading and trailing whitespace. This is a little more
- # tricky in truth, since we want to also strip a potential leading
- # "SKIP" string from the message.
- sub("^[^#]*#[ \t]*(SKIP[: \t][ \t]*)?", "")
- sub("[ \t]*$", "");
- handle_tap_plan(0, $0)
- }
- # "Bail out!" magic.
- # Older versions of prove and TAP::Harness (e.g., 3.17) did not
- # recognize a "Bail out!" directive when preceded by leading
- # whitespace, but more modern versions (e.g., 3.23) do. So we
- # emulate the latter, "more modern" behaviour.
- else if ($0 ~ /^[ \t]*Bail out!/)
- {
- bailed_out = 1
- # Get the bailout message (if any), with leading and trailing
- # whitespace stripped. The message remains stored in `$0`.
- sub("^[ \t]*Bail out![ \t]*", "");
- sub("[ \t]*$", "");
- # Format the error message for the
- bailout_message = "Bail out!"
- if (length($0))
- bailout_message = bailout_message " " $0
- testsuite_error(bailout_message)
- }
- # Maybe we have too look for dianogtic comments too.
- else if (comments != 0)
- {
- comment = extract_tap_comment($0);
- if (length(comment))
- report("#", comment);
- }
- }
-
-## -------- ##
-## FINISH ##
-## -------- ##
-
-# A "Bail out!" directive should cause us to ignore any following TAP
-# error, as well as a non-zero exit status from the TAP producer.
-if (!bailed_out)
- {
- if (!plan_seen)
- {
- testsuite_error("missing test plan")
- }
- else if (planned_tests != testno)
- {
- bad_amount = testno > planned_tests ? "many" : "few"
- testsuite_error(sprintf("too %s tests run (expected %d, got %d)",
- bad_amount, planned_tests, testno))
- }
- if (!ignore_exit)
- {
- # Fetch exit status from the last line.
- exit_message = get_test_exit_message(nextline)
- if (exit_message)
- testsuite_error(exit_message)
- }
- }
-
-write_test_results()
-
-exit 0
-
-} # End of "BEGIN" block.
-'
-
-# TODO: document that we consume the file descriptor 3 :-(
-} 3>"$log_file"
-
-test $? -eq 0 || fatal "I/O or internal error"
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
--
2.19.1
1
9
[pacman-dev] [PATCH] makepkg: if "!buildflags" and "debug" coincide, unset the debug buildflags too
by Eli Schwartz 14 Nov '18
by Eli Schwartz 14 Nov '18
14 Nov '18
If a user has a makepkg.conf policy to enable debug builds, but a
PKGBUILD has disabled buildflags, we would unset the *FLAGS but then
later append the debug *FLAGS anyway, which would result in some *FLAGS
being used, against the wishes of the PKGBUILD author.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/makepkg.sh.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 5705bd69..8b39ca9a 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -383,7 +383,7 @@ source_buildfile() {
prepare_buildenv() {
# clear user-specified buildflags if requested
if check_option "buildflags" "n"; then
- unset CPPFLAGS CFLAGS CXXFLAGS LDFLAGS
+ unset CPPFLAGS CFLAGS DEBUG_CFLAGS CXXFLAGS DEBUG_CXXFLAGS LDFLAGS
fi
if check_option "debug" "y"; then
--
2.19.1
2
1
04 Nov '18
Since commit b5d62d2c91a2caf5c18945921cdf12af6f36b2d4, all scripts
depend on libmakepkg, not just makepkg itself.
Additionally, repo-remove and repo-elephant don't care whether
repo-add.sh.in is updated... but they do require the repo-add target to
be up to date, so use that instead.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/Makefile.am | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index c6b6220e..83d53a51 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -203,19 +203,19 @@ makepkg-template: \
$(AM_V_GEN)$(edit) $< > $@
$(AM_V_at)chmod +x,a-w $@
-pacman-db-upgrade: $(srcdir)/pacman-db-upgrade.sh.in
+pacman-db-upgrade: $(srcdir)/pacman-db-upgrade.sh.in $(LIBMAKEPKG_IN)
-pacman-key: $(srcdir)/pacman-key.sh.in
+pacman-key: $(srcdir)/pacman-key.sh.in $(LIBMAKEPKG_IN)
-pkgdelta: $(srcdir)/pkgdelta.sh.in
+pkgdelta: $(srcdir)/pkgdelta.sh.in $(LIBMAKEPKG_IN)
-repo-add: $(srcdir)/repo-add.sh.in
+repo-add: $(srcdir)/repo-add.sh.in $(LIBMAKEPKG_IN)
-repo-remove: $(srcdir)/repo-add.sh.in
+repo-remove: repo-add
$(AM_V_at)$(RM) repo-remove
$(AM_V_at)$(LN_S) repo-add repo-remove
-repo-elephant: $(srcdir)/repo-add.sh.in
+repo-elephant: repo-add
$(AM_V_at)$(RM) repo-elephant
$(AM_V_at)$(LN_S) repo-add repo-elephant
--
2.19.1
1
0
[pacman-dev] [PATCH 1/2] meson: separate out wrapped from non-wrapped scripts
by Dave Reisner 04 Nov '18
by Dave Reisner 04 Nov '18
04 Nov '18
makepkg-template is a perl script and doesn't get wrapped by our shell
wrapper. It (wrongly) reads from the host machine rather than the build
root, but this is working as implemented.
---
wohoo first bug that affects one buildsys and not the other!
scripts/meson.build | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/scripts/meson.build b/scripts/meson.build
index 535eccba..50b0c34f 100644
--- a/scripts/meson.build
+++ b/scripts/meson.build
@@ -1,5 +1,4 @@
-scripts = [
- 'makepkg-template.pl.in',
+wrapped_scripts = [
'makepkg.sh.in',
'pacman-db-upgrade.sh.in',
'pacman-key.sh.in',
@@ -7,6 +6,10 @@ scripts = [
'repo-add.sh.in'
]
+scripts = [
+ 'makepkg-template.pl.in',
+]
+
library_files = [
'library/human_to_size.sh',
'library/size_to_human.sh',
@@ -26,6 +29,19 @@ m4_edit = generator(
foreach script : scripts
script_shortname = script.split('.')[0]
+ custom_target(
+ script,
+ input : m4_edit.process(script),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@', '0755'],
+ output : script_shortname,
+ depend_files : library_files,
+ install : true,
+ install_dir : get_option('bindir'))
+endforeach
+
+foreach script : wrapped_scripts
+ script_shortname = script.split('.')[0]
+
# Build the script, but don't install it. We want to keep it as a "private"
# artifact that we reference from a wrapper script in order to bootstrap it
# the build directory.
--
2.19.1
1
1
[pacman-dev] [GIT] The official pacman repository branch, master, updated. v5.1.1-57-gde915c4f
by Allan McRae 03 Nov '18
by Allan McRae 03 Nov '18
03 Nov '18
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 "The official pacman repository".
The branch, master has been updated
via de915c4f145d6e985c3c0fdf8fe121b5066d711c (commit)
via 3dfec574a36b6aacc2004df3e122dae9d17a4b0d (commit)
via 635a9c911c419932e4f27eeae349bb265011ca86 (commit)
via d230ec6f17a2b64ed61936013234414c74e7c29f (commit)
via 51db84750ece4de58923d4ce43cb0638ef150f5f (commit)
via dab45f0808951afc2e3146211a1c6d7ebb8bd06d (commit)
from b5d62d2c91a2caf5c18945921cdf12af6f36b2d4 (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 de915c4f145d6e985c3c0fdf8fe121b5066d711c
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Wed Oct 31 13:12:34 2018 -0400
repo-add: print the name of the database when extracting
Currently this prints the following message:
==> Extracting database to a temporary location...
==> Extracting database to a temporary location...
This redundancy is potentially confusing and may cause people to think
something is wrong. Historically, this message came from a time when we
only extracted one database, but repo-add was changed to always create
the files database in commit cb0f2bd0385f447e045e2b2aab9ffa55df3c2d8a
and whole code block with message intact was moved into a for loop and
run (and printed) twice.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 3dfec574a36b6aacc2004df3e122dae9d17a4b0d
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Wed Oct 31 13:12:33 2018 -0400
makepkg: fix .PKGINFO/.BUILDINFO files swallowing status printing
The respective write_* functions are low-level and shouldn't be
outputting statuses; move these to the logic flow where they are used.
This ensures the functions can be used in the future wherever, and also
solves an issue where, as fallout from the message.sh retrofitting in
commit 882e707e40bbade0111cf3bdedbdac4d4b70453b, the statuses got
redirected to the actual files.
The resulting package was technically correct, except that it contained
useless lines which pacman ignored, and repo-add also ignored but at the
same time generated an error message:
/usr/bin/repo-add: line 335: declare: `=-> Generating .PKGINFO file...': not a valid identifier
Thirdparty package tools with stricter parsers may abort with errors,
and "repose" is known to do so.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit 635a9c911c419932e4f27eeae349bb265011ca86
Author: Eli Schwartz <eschwartz(a)archlinux.org>
Date: Sun Oct 21 13:28:41 2018 -0400
pacman-key: just accept one file to verify, and enforce detached sigs
Simply pass options on to gpg the same way gpg uses them -- no looping
through and checking lots of signatures.
This prevents a situation where the signature file to be verified is
manipulated to contain an embedded signature which is valid, but not a
detached signature for the file you are actually trying to verify.
gpg does not offer an option to verify many files at once by naming each
signature/file pair, and there's no reason for us to do so either, since
it would be quite tiresome to do so.
In the event that there is no signature/file pair specified to
pacman-key itself,
- preserve gpg's behavior, *if* the matching file does not exist, by
- assuming the signature is an embedded signature
- deviate from gpg's behavior, by
- offering a security warning about which one is happening
- when there is an embedded signature *and* a matching detached file,
assume the latter is desired
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
Signed-off-by: Allan McRae <allan(a)archlinux.org>
commit d230ec6f17a2b64ed61936013234414c74e7c29f
Author: Dave Reisner <dreisner(a)archlinux.org>
Date: Sun Oct 28 02:42:53 2018 -0400
meson: add a wrapper to bootstrap scripts from within build dir
This doesn't do quite as good of a job of "hiding away" the real script
as we did with autotools, but it satisfies the need for being able to
run scripts which depend on libmakepkg with the local copy within the
repo. We do, however, improve upon the autotools script by ensuring that
the bash path used in configuring pacman is the interpreter used to run
the underlying script.
commit 51db84750ece4de58923d4ce43cb0638ef150f5f
Author: Dave Reisner <dreisner(a)archlinux.org>
Date: Sat Jul 7 10:29:48 2018 -0400
Add meson.build files to build with meson
Provide both build systems in parallel for now, to ensure that we work
out all the differences between the two. Some time from now, we'll give
up on autotools.
Meson tends to be faster and probably easier to read/maintain. On my
machine, the full meson configure+build+install takes a little under
half as long as a similar autotools-based invocation.
Building with meson is a two step process. First, configure the build:
meson build
Then, compile the project:
ninja -C build
There's some mild differences in functionality between meson and
autotools. specifically:
1) No singular update-po target. meson only generates individual
update-po targets for each textdomain (of which we have 3). To make
this easier, there's a build-aux/update-po script which finds all
update-po targets and runs them.
2) No 'make dist' equivalent. Just run 'git archive' to generate a
suitable tarball for distribution.
commit dab45f0808951afc2e3146211a1c6d7ebb8bd06d
Author: Dave Reisner <dreisner(a)archlinux.org>
Date: Sun Oct 21 22:58:23 2018 -0400
Dynamically generate Doxyfile from input
This isn't super interesting for the autotools side, but it's necessary
in order to make things sane for other build systems which we might
introduce in the future.
-----------------------------------------------------------------------
Summary of changes:
.ycm_extra_conf.py | 250 ++++++++++++++
build-aux/edit-script.sh.in | 33 ++
build-aux/meson-install-script.sh | 6 +
build-aux/meson-make-symlink.sh | 12 +
build-aux/script-wrapper.sh.in | 6 +
build-aux/tap-driver.py | 296 ++++++++++++++++
build-aux/update-po | 39 +++
doc/.gitignore | 1 +
doc/{Doxyfile => Doxyfile.in} | 2 +-
doc/Makefile.am | 5 +-
doc/meson.build | 138 ++++++++
doc/pacman-key.8.asciidoc | 8 +-
lib/libalpm/meson.build | 33 ++
lib/libalpm/po/meson.build | 15 +
meson.build | 488 +++++++++++++++++++++++++++
meson_options.txt | 61 ++++
scripts/libmakepkg/integrity/meson.build | 20 ++
scripts/libmakepkg/lint_config/meson.build | 18 +
scripts/libmakepkg/lint_package/meson.build | 20 ++
scripts/libmakepkg/lint_pkgbuild/meson.build | 37 ++
scripts/libmakepkg/meson.build | 31 ++
scripts/libmakepkg/source/meson.build | 22 ++
scripts/libmakepkg/tidy/meson.build | 23 ++
scripts/libmakepkg/util/meson.build | 24 ++
scripts/makepkg.sh.in | 5 +-
scripts/meson.build | 91 +++++
scripts/pacman-key.sh.in | 31 +-
scripts/po/meson.build | 15 +
scripts/repo-add.sh.in | 2 +-
src/common/meson.build | 4 +
src/pacman/meson.build | 23 ++
src/pacman/po/meson.build | 15 +
src/util/meson.build | 3 +
test/pacman/meson.build | 357 ++++++++++++++++++++
test/scripts/meson.build | 15 +
test/util/meson.build | 6 +
36 files changed, 2136 insertions(+), 19 deletions(-)
create mode 100644 .ycm_extra_conf.py
create mode 100644 build-aux/edit-script.sh.in
create mode 100644 build-aux/meson-install-script.sh
create mode 100644 build-aux/meson-make-symlink.sh
create mode 100755 build-aux/script-wrapper.sh.in
create mode 100644 build-aux/tap-driver.py
create mode 100755 build-aux/update-po
rename doc/{Doxyfile => Doxyfile.in} (99%)
create mode 100644 doc/meson.build
create mode 100644 lib/libalpm/meson.build
create mode 100644 lib/libalpm/po/meson.build
create mode 100644 meson.build
create mode 100644 meson_options.txt
create mode 100644 scripts/libmakepkg/integrity/meson.build
create mode 100644 scripts/libmakepkg/lint_config/meson.build
create mode 100644 scripts/libmakepkg/lint_package/meson.build
create mode 100644 scripts/libmakepkg/lint_pkgbuild/meson.build
create mode 100644 scripts/libmakepkg/meson.build
create mode 100644 scripts/libmakepkg/source/meson.build
create mode 100644 scripts/libmakepkg/tidy/meson.build
create mode 100644 scripts/libmakepkg/util/meson.build
create mode 100644 scripts/meson.build
create mode 100644 scripts/po/meson.build
create mode 100644 src/common/meson.build
create mode 100644 src/pacman/meson.build
create mode 100644 src/pacman/po/meson.build
create mode 100644 src/util/meson.build
create mode 100644 test/pacman/meson.build
create mode 100644 test/scripts/meson.build
create mode 100644 test/util/meson.build
hooks/post-receive
--
The official pacman repository
1
0
02 Nov '18
Provide both build systems in parallel for now, to ensure that we work
out all the differences between the two. Some time from now, we'll give
up on autotools.
Meson tends to be faster and probably easier to read/maintain. On my
machine, the full meson configure+build+install takes a little under
half as long as a similar autotools-based invocation.
Building with meson is a two step process. First, configure the build:
meson build
Then, compile the project:
ninja -C build
There's some mild differences in functionality between meson and
autotools. specifically:
1) No singular update-po target. meson only generates individual
update-po targets for each textdomain (of which we have 3). To make
this easier, there's a build-aux/update-po script which finds all
update-po targets and runs them.
2) No doxygen support. Doxygen seems to be terrible and requires that
everything be built through the Doxyfile. Support for out-of-tree builds
(enforced by meson) appears to be nonexistant. I'd suggest just running
doxygen directly since we never package these files and just export them
for the website.
3) No 'make dist' equivalent. Just run 'git archive' to generate a
suitable tarball for distribution.
---
Yes, this is huge. All 330 tests pass, and I've been building/using
pacman from my 'meson' branch for a while now.
Feedback wanted.
.ycm_extra_conf.py | 250 ++++++++++
build-aux/edit-script.sh.in | 33 ++
build-aux/meson-make-symlink.sh | 12 +
build-aux/tap-driver.py | 296 +++++++++++
build-aux/update-po | 39 ++
doc/meson.build | 118 +++++
lib/libalpm/meson.build | 33 ++
lib/libalpm/po/meson.build | 15 +
meson.build | 487 +++++++++++++++++++
meson_options.txt | 58 +++
scripts/libmakepkg/integrity/meson.build | 20 +
scripts/libmakepkg/lint_config/meson.build | 18 +
scripts/libmakepkg/lint_package/meson.build | 20 +
scripts/libmakepkg/lint_pkgbuild/meson.build | 37 ++
scripts/libmakepkg/meson.build | 31 ++
scripts/libmakepkg/source/meson.build | 22 +
scripts/libmakepkg/tidy/meson.build | 23 +
scripts/libmakepkg/util/meson.build | 24 +
scripts/meson.build | 66 +++
scripts/po/meson.build | 15 +
src/common/meson.build | 4 +
src/pacman/meson.build | 23 +
src/pacman/po/meson.build | 15 +
src/util/meson.build | 3 +
test/pacman/meson.build | 357 ++++++++++++++
test/scripts/meson.build | 12 +
test/util/meson.build | 6 +
27 files changed, 2037 insertions(+)
create mode 100644 .ycm_extra_conf.py
create mode 100644 build-aux/edit-script.sh.in
create mode 100644 build-aux/meson-make-symlink.sh
create mode 100644 build-aux/tap-driver.py
create mode 100755 build-aux/update-po
create mode 100644 doc/meson.build
create mode 100644 lib/libalpm/meson.build
create mode 100644 lib/libalpm/po/meson.build
create mode 100644 meson.build
create mode 100644 meson_options.txt
create mode 100644 scripts/libmakepkg/integrity/meson.build
create mode 100644 scripts/libmakepkg/lint_config/meson.build
create mode 100644 scripts/libmakepkg/lint_package/meson.build
create mode 100644 scripts/libmakepkg/lint_pkgbuild/meson.build
create mode 100644 scripts/libmakepkg/meson.build
create mode 100644 scripts/libmakepkg/source/meson.build
create mode 100644 scripts/libmakepkg/tidy/meson.build
create mode 100644 scripts/libmakepkg/util/meson.build
create mode 100644 scripts/meson.build
create mode 100644 scripts/po/meson.build
create mode 100644 src/common/meson.build
create mode 100644 src/pacman/meson.build
create mode 100644 src/pacman/po/meson.build
create mode 100644 src/util/meson.build
create mode 100644 test/pacman/meson.build
create mode 100644 test/scripts/meson.build
create mode 100644 test/util/meson.build
diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
new file mode 100644
index 00000000..f297deef
--- /dev/null
+++ b/.ycm_extra_conf.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python
+
+# SPDX-License-Identifier: Unlicense
+#
+# Based on the template file provided by the 'YCM-Generator' project authored by
+# Reuben D'Netto.
+# Jiahui Xie has re-reformatted and expanded the original script in accordance
+# to the requirements of the PEP 8 style guide and 'systemd' project,
+# respectively.
+#
+# The original license is preserved as it is.
+#
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to <http://unlicense.org/>
+
+"""
+YouCompleteMe configuration file tailored to support the 'meson' build system
+used by the 'systemd' project.
+"""
+
+import glob
+import os
+import ycm_core
+
+
+SOURCE_EXTENSIONS = (".C", ".cpp", ".cxx", ".cc", ".c", ".m", ".mm")
+HEADER_EXTENSIONS = (".H", ".h", ".hxx", ".hpp", ".hh")
+
+
+def DirectoryOfThisScript():
+ """
+ Return the absolute path of the parent directory containing this
+ script.
+ """
+ return os.path.dirname(os.path.abspath(__file__))
+
+
+def GuessBuildDirectory():
+ """
+ Guess the build directory using the following heuristics:
+
+ 1. Returns the current directory of this script plus 'build'
+ subdirectory in absolute path if this subdirectory exists.
+
+ 2. Otherwise, probes whether there exists any directory
+ containing '.ninja_log' file two levels above the current directory;
+ returns this single directory only if there is one candidate.
+ """
+ result = os.path.join(DirectoryOfThisScript(), "build")
+
+ if os.path.exists(result):
+ return result
+
+ result = glob.glob(os.path.join(DirectoryOfThisScript(),
+ "..", "..", "*", ".ninja_log"))
+
+ if not result:
+ return ""
+
+ if 1 != len(result):
+ return ""
+
+ return os.path.split(result[0])[0]
+
+
+def TraverseByDepth(root, include_extensions):
+ """
+ Return a set of child directories of the 'root' containing file
+ extensions specified in 'include_extensions'.
+
+ NOTE:
+ 1. The 'root' directory itself is excluded from the result set.
+ 2. No subdirectories would be excluded if 'include_extensions' is left
+ to 'None'.
+ 3. Each entry in 'include_extensions' must begin with string '.'.
+ """
+ is_root = True
+ result = set()
+ # Perform a depth first top down traverse of the given directory tree.
+ for root_dir, subdirs, file_list in os.walk(root):
+ if not is_root:
+ # print("Relative Root: ", root_dir)
+ # print(subdirs)
+ if include_extensions:
+ get_ext = os.path.splitext
+ subdir_extensions = {
+ get_ext(f)[-1] for f in file_list if get_ext(f)[-1]
+ }
+ if subdir_extensions & include_extensions:
+ result.add(root_dir)
+ else:
+ result.add(root_dir)
+ else:
+ is_root = False
+
+ return result
+
+
+_project_src_dir = os.path.join(DirectoryOfThisScript(), "src")
+_include_dirs_set = TraverseByDepth(_project_src_dir, frozenset({".h"}))
+flags = [
+ "-x",
+ "c"
+ # The following flags are partially redundant due to the existence of
+ # 'compile_commands.json'.
+ # '-Wall',
+ # '-Wextra',
+ # '-Wfloat-equal',
+ # '-Wpointer-arith',
+ # '-Wshadow',
+ # '-std=gnu99',
+]
+
+for include_dir in _include_dirs_set:
+ flags.append("-I" + include_dir)
+
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# You can get CMake to generate this file for you by adding:
+# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
+# to your CMakeLists.txt file.
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = GuessBuildDirectory()
+
+if os.path.exists(compilation_database_folder):
+ database = ycm_core.CompilationDatabase(compilation_database_folder)
+else:
+ database = None
+
+
+def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
+ """
+ Iterate through 'flags' and replace the relative paths prefixed by
+ '-isystem', '-I', '-iquote', '--sysroot=' with absolute paths
+ start with 'working_directory'.
+ """
+ if not working_directory:
+ return list(flags)
+ new_flags = []
+ make_next_absolute = False
+ path_flags = ["-isystem", "-I", "-iquote", "--sysroot="]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith("/"):
+ new_flag = os.path.join(working_directory, flag)
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith(path_flag):
+ path = flag[len(path_flag):]
+ new_flag = path_flag + os.path.join(working_directory, path)
+ break
+
+ if new_flag:
+ new_flags.append(new_flag)
+ return new_flags
+
+
+def IsHeaderFile(filename):
+ """
+ Check whether 'filename' is considered as a header file.
+ """
+ extension = os.path.splitext(filename)[1]
+ return extension in HEADER_EXTENSIONS
+
+
+def GetCompilationInfoForFile(filename):
+ """
+ Helper function to look up compilation info of 'filename' in the 'database'.
+ """
+ # The compilation_commands.json file generated by CMake does not have
+ # entries for header files. So we do our best by asking the db for flags for
+ # a corresponding source file, if any. If one exists, the flags for that
+ # file should be good enough.
+ if not database:
+ return None
+
+ if IsHeaderFile(filename):
+ basename = os.path.splitext(filename)[0]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists(replacement_file):
+ compilation_info = \
+ database.GetCompilationInfoForFile(replacement_file)
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile(filename)
+
+
+def FlagsForFile(filename, **kwargs):
+ """
+ Callback function to be invoked by YouCompleteMe in order to get the
+ information necessary to compile 'filename'.
+
+ It returns a dictionary with a single element 'flags'. This element is a
+ list of compiler flags to pass to libclang for the file 'filename'.
+ """
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = GetCompilationInfoForFile(filename)
+ if not compilation_info:
+ return None
+
+ final_flags = MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_)
+
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to)
+
+ return {
+ "flags": final_flags,
+ "do_cache": True
+ }
diff --git a/build-aux/edit-script.sh.in b/build-aux/edit-script.sh.in
new file mode 100644
index 00000000..3e3a1b6a
--- /dev/null
+++ b/build-aux/edit-script.sh.in
@@ -0,0 +1,33 @@
+#!@BASH@
+
+input=$1
+output=$2
+mode=$3
+
+"@SED@" \
+ -e "s|@rootdir[@]|@ROOTDIR@|g" \
+ -e "s|@localedir[@]|@LOCALEDIR@|g" \
+ -e "s|@sysconfdir[@]|@sysconfdir@|g" \
+ -e "s|@localstatedir[@]|@localstatedir@|g" \
+ -e "s|@libmakepkgdir[@]|@LIBMAKEPKGDIR@|g" \
+ -e "s|@pkgdatadir[@]|@PKGDATADIR@|g" \
+ -e "s|@prefix[@]|@PREFIX@|g" \
+ -e "1s|#!/bin/bash|#!@BASH@|g" \
+ -e "s|@PACKAGE_VERSION[@]|@PACKAGE_VERSION@|g" \
+ -e "s|@PACKAGE_NAME[@]|@PACKAGE_NAME@|g" \
+ -e "s|@BUILDSCRIPT[@]|@BUILDSCRIPT@|g" \
+ -e "s|@TEMPLATE_DIR[@]|@TEMPLATE_DIR@|g" \
+ -e "s|@DEBUGSUFFIX[@]|@DEBUGSUFFIX@|g" \
+ -e "s|@INODECMD[@]|@INODECMD@|g" \
+ -e "s|@OWNERCMD[@]|@OWNERCMD@|g" \
+ -e "s|@MODECMD[@]|@MODECMD@|g" \
+ -e "s|@SEDINPLACEFLAGS[@]|@SEDINPLACEFLAGS@|g" \
+ -e "s|@SEDPATH[@]|@SEDPATH@|g" \
+ -e "s|@DUFLAGS[@]|@DUFLAGS@|g" \
+ -e "s|@DUPATH[@]|@DUPATH@|g" \
+ -e "s|@configure_input[@]|Generated from ${output##*/}.sh.in; do not edit by hand.|g" \
+ "$input" >"$output"
+
+if [[ $mode ]]; then
+ chmod "$mode" "$output"
+fi
diff --git a/build-aux/meson-make-symlink.sh b/build-aux/meson-make-symlink.sh
new file mode 100644
index 00000000..501cd43d
--- /dev/null
+++ b/build-aux/meson-make-symlink.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -eu
+
+# this is needed mostly because $DESTDIR is provided as a variable,
+# and we need to create the target directory...
+
+mkdir -vp "$(dirname "${DESTDIR:-}$2")"
+if [ "$(dirname $1)" = . ]; then
+ ln -vfs -T "$1" "${DESTDIR:-}$2"
+else
+ ln -vfs -T --relative "${DESTDIR:-}$1" "${DESTDIR:-}$2"
+fi
diff --git a/build-aux/tap-driver.py b/build-aux/tap-driver.py
new file mode 100644
index 00000000..c231caec
--- /dev/null
+++ b/build-aux/tap-driver.py
@@ -0,0 +1,296 @@
+#!/usr/bin/env python3
+# Adapted from tappy copyright (c) 2016, Matt Layman
+# MIT license
+# https://github.com/python-tap/tappy
+
+import io
+import re
+import subprocess
+import sys
+
+
+class Directive(object):
+ """A representation of a result line directive."""
+
+ skip_pattern = re.compile(
+ r"""^SKIP\S*
+ (?P<whitespace>\s*) # Optional whitespace.
+ (?P<reason>.*) # Slurp up the rest.""",
+ re.IGNORECASE | re.VERBOSE)
+ todo_pattern = re.compile(
+ r"""^TODO\b # The directive name
+ (?P<whitespace>\s*) # Immediately following must be whitespace.
+ (?P<reason>.*) # Slurp up the rest.""",
+ re.IGNORECASE | re.VERBOSE)
+
+ def __init__(self, text):
+ """Initialize the directive by parsing the text.
+ The text is assumed to be everything after a '#\s*' on a result line.
+ """
+ self._text = text
+ self._skip = False
+ self._todo = False
+ self._reason = None
+
+ match = self.skip_pattern.match(text)
+ if match:
+ self._skip = True
+ self._reason = match.group('reason')
+
+ match = self.todo_pattern.match(text)
+ if match:
+ if match.group('whitespace'):
+ self._todo = True
+ else:
+ # Catch the case where the directive has no descriptive text.
+ if match.group('reason') == '':
+ self._todo = True
+ self._reason = match.group('reason')
+
+ @property
+ def text(self):
+ """Get the entire text."""
+ return self._text
+
+ @property
+ def skip(self):
+ """Check if the directive is a SKIP type."""
+ return self._skip
+
+ @property
+ def todo(self):
+ """Check if the directive is a TODO type."""
+ return self._todo
+
+ @property
+ def reason(self):
+ """Get the reason for the directive."""
+ return self._reason
+
+
+class Parser(object):
+ """A parser for TAP files and lines."""
+
+ # ok and not ok share most of the same characteristics.
+ result_base = r"""
+ \s* # Optional whitespace.
+ (?P<number>\d*) # Optional test number.
+ \s* # Optional whitespace.
+ (?P<description>[^#]*) # Optional description before #.
+ \#? # Optional directive marker.
+ \s* # Optional whitespace.
+ (?P<directive>.*) # Optional directive text.
+ """
+ ok = re.compile(r'^ok' + result_base, re.VERBOSE)
+ not_ok = re.compile(r'^not\ ok' + result_base, re.VERBOSE)
+ plan = re.compile(r"""
+ ^1..(?P<expected>\d+) # Match the plan details.
+ [^#]* # Consume any non-hash character to confirm only
+ # directives appear with the plan details.
+ \#? # Optional directive marker.
+ \s* # Optional whitespace.
+ (?P<directive>.*) # Optional directive text.
+ """, re.VERBOSE)
+ diagnostic = re.compile(r'^#')
+ bail = re.compile(r"""
+ ^Bail\ out!
+ \s* # Optional whitespace.
+ (?P<reason>.*) # Optional reason.
+ """, re.VERBOSE)
+ version = re.compile(r'^TAP version (?P<version>\d+)$')
+
+ TAP_MINIMUM_DECLARED_VERSION = 13
+
+ def parse(self, fh):
+ """Generate tap.line.Line objects, given a file-like object `fh`.
+ `fh` may be any object that implements both the iterator and
+ context management protocol (i.e. it can be used in both a
+ "with" statement and a "for...in" statement.)
+ Trailing whitespace and newline characters will be automatically
+ stripped from the input lines.
+ """
+ with fh:
+ for line in fh:
+ yield self.parse_line(line.rstrip())
+
+ def parse_line(self, text):
+ """Parse a line into whatever TAP category it belongs."""
+ match = self.ok.match(text)
+ if match:
+ return self._parse_result(True, match)
+
+ match = self.not_ok.match(text)
+ if match:
+ return self._parse_result(False, match)
+
+ if self.diagnostic.match(text):
+ return ('diagnostic', text)
+
+ match = self.plan.match(text)
+ if match:
+ return self._parse_plan(match)
+
+ match = self.bail.match(text)
+ if match:
+ return ('bail', match.group('reason'))
+
+ match = self.version.match(text)
+ if match:
+ return self._parse_version(match)
+
+ return ('unknown',)
+
+ def _parse_plan(self, match):
+ """Parse a matching plan line."""
+ expected_tests = int(match.group('expected'))
+ directive = Directive(match.group('directive'))
+
+ # Only SKIP directives are allowed in the plan.
+ if directive.text and not directive.skip:
+ return ('unknown',)
+
+ return ('plan', expected_tests, directive)
+
+ def _parse_result(self, ok, match):
+ """Parse a matching result line into a result instance."""
+ return ('result', ok, match.group('number'),
+ match.group('description').strip(),
+ Directive(match.group('directive')))
+
+ def _parse_version(self, match):
+ version = int(match.group('version'))
+ if version < self.TAP_MINIMUM_DECLARED_VERSION:
+ raise ValueError('It is an error to explicitly specify '
+ 'any version lower than 13.')
+ return ('version', version)
+
+
+class Rules(object):
+
+ def __init__(self):
+ self._lines_seen = {'plan': [], 'test': 0, 'failed': 0, 'version': []}
+ self._errors = []
+
+ def check(self, final_line_count):
+ """Check the status of all provided data and update the suite."""
+ if self._lines_seen['version']:
+ self._process_version_lines()
+ self._process_plan_lines(final_line_count)
+
+ def check_errors(self):
+ if self._lines_seen['failed'] > 0:
+ self._add_error('Tests failed.')
+ if self._errors:
+ for error in self._errors:
+ print(error)
+ return 1
+ return 0
+
+ def _process_version_lines(self):
+ """Process version line rules."""
+ if len(self._lines_seen['version']) > 1:
+ self._add_error('Multiple version lines appeared.')
+ elif self._lines_seen['version'][0] != 1:
+ self._add_error('The version must be on the first line.')
+
+ def _process_plan_lines(self, final_line_count):
+ """Process plan line rules."""
+ if not self._lines_seen['plan']:
+ self._add_error('Missing a plan.')
+ return
+
+ if len(self._lines_seen['plan']) > 1:
+ self._add_error('Only one plan line is permitted per file.')
+ return
+
+ expected_tests, at_line = self._lines_seen['plan'][0]
+ if not self._plan_on_valid_line(at_line, final_line_count):
+ self._add_error(
+ 'A plan must appear at the beginning or end of the file.')
+ return
+
+ if expected_tests != self._lines_seen['test']:
+ self._add_error(
+ 'Expected {expected_count} tests '
+ 'but only {seen_count} ran.'.format(
+ expected_count=expected_tests,
+ seen_count=self._lines_seen['test']))
+
+ def _plan_on_valid_line(self, at_line, final_line_count):
+ """Check if a plan is on a valid line."""
+ # Put the common cases first.
+ if at_line == 1 or at_line == final_line_count:
+ return True
+
+ # The plan may only appear on line 2 if the version is at line 1.
+ after_version = (
+ self._lines_seen['version'] and
+ self._lines_seen['version'][0] == 1 and
+ at_line == 2)
+ if after_version:
+ return True
+
+ return False
+
+ def handle_bail(self, reason):
+ """Handle a bail line."""
+ self._add_error('Bailed: {reason}').format(reason=reason)
+
+ def handle_skipping_plan(self):
+ """Handle a plan that contains a SKIP directive."""
+ sys.exit(77)
+
+ def saw_plan(self, expected_tests, at_line):
+ """Record when a plan line was seen."""
+ self._lines_seen['plan'].append((expected_tests, at_line))
+
+ def saw_test(self, ok):
+ """Record when a test line was seen."""
+ self._lines_seen['test'] += 1
+ if not ok:
+ self._lines_seen['failed'] += 1
+
+ def saw_version_at(self, line_counter):
+ """Record when a version line was seen."""
+ self._lines_seen['version'].append(line_counter)
+
+ def _add_error(self, message):
+ self._errors += [message]
+
+
+if __name__ == '__main__':
+ parser = Parser()
+ rules = Rules()
+
+ try:
+ out = subprocess.check_output(sys.argv[1:], universal_newlines=True)
+ except subprocess.CalledProcessError as e:
+ sys.stdout.write(e.output)
+ raise e
+
+ line_generator = parser.parse(io.StringIO(out))
+ line_counter = 0
+ for line in line_generator:
+ line_counter += 1
+
+ if line[0] == 'unknown':
+ continue
+
+ if line[0] == 'result':
+ rules.saw_test(line[1])
+ print('{okay} {num} {description} {directive}'.format(
+ okay=('' if line[1] else 'not ') + 'ok', num=line[2],
+ description=line[3], directive=line[4].text))
+ elif line[0] == 'plan':
+ if line[2].skip:
+ rules.handle_skipping_plan()
+ rules.saw_plan(line[1], line_counter)
+ elif line[0] == 'bail':
+ rules.handle_bail(line[1])
+ elif line[0] == 'version':
+ rules.saw_version_at(line_counter)
+ elif line[0] == 'diagnostic':
+ print(line[1])
+
+ rules.check(line_counter)
+ sys.exit(rules.check_errors())
diff --git a/build-aux/update-po b/build-aux/update-po
new file mode 100755
index 00000000..ce1ad4be
--- /dev/null
+++ b/build-aux/update-po
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+find_build_directory() {
+ local build_dirs=(*/.ninja_log)
+
+ if [[ ! -e ${build_dirs[0]} ]]; then
+ echo "error: No build directory found. Have you run 'meson build' yet?" >&2
+ return 1
+ elif (( ${#build_dirs[*]} > 1 )); then
+ echo "error: Multiple build directories found. Unable to proceed." >&2
+ return 1
+ fi
+
+ printf '%s\n' "${build_dirs[0]%/*}"
+}
+
+
+filter_targets_by_name() {
+ if command -v jq &>/dev/null; then
+ jq --arg re "$1" -r 'map(.name)[] | select(match($re))'
+ else
+ json_pp | awk -v filter="$1" -F'[:"]' \
+ '$2 == "name" && $(NF - 1) ~ filter { print $(NF - 1) }'
+ fi
+}
+
+# Make things simple and require that we're in the build root rather than
+# trying to chase down the location of this script and the relative build dir.
+if [[ ! -d .git ]]; then
+ echo "This script must be run from the root of the repository" >&2
+ exit 1
+fi
+
+build_dir=$(find_build_directory) || exit 1
+
+mapfile -t targets < \
+ <(meson introspect "$build_dir" --targets | filter_targets_by_name "-update-po$")
+
+ninja -C "$build_dir" "${targets[@]}"
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 00000000..b1ffd793
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,118 @@
+manpages = [
+ { 'name': 'alpm-hooks.5' },
+ { 'name': 'pacman.8' },
+ { 'name': 'makepkg.8' },
+ { 'name': 'makepkg-template.1' },
+ { 'name': 'repo-add.8' },
+ { 'name': 'vercmp.8' },
+ { 'name': 'pkgdelta.8' },
+ { 'name': 'pacman-key.8' },
+ { 'name': 'PKGBUILD.5', 'extra_depends' : [ 'PKGBUILD-example.txt' ] },
+ { 'name': 'makepkg.conf.5' },
+ { 'name': 'pacman.conf.5' },
+ { 'name': 'libalpm.3' },
+ { 'name': 'BUILDINFO.5' },
+]
+
+asciidoc_conf = join_paths(meson.current_source_dir(), 'asciidoc.conf')
+
+asciidoc_opts = [
+ '-f', asciidoc_conf,
+ '-a', 'pacman_version="@0@"'.format(PACKAGE_VERSION),
+ '-a', 'pacman_date=@0@'.format(run_command('date', '+%Y-%m-%d').stdout().strip()),
+ '-a', 'pkgdatadir=@0@'.format(PKGDATADIR),
+ '-a', 'localstatedir=@0@'.format(LOCALSTATEDIR),
+ '-a', 'sysconfdir=@0@'.format(SYSCONFDIR),
+ '-a', 'datarootdir=@0@'.format(DATAROOTDIR),
+]
+
+html_targets = []
+html_files = []
+
+foreach page : manpages
+ manpage = page['name']
+ htmlpage = '@0@.html'.format(manpage)
+ input = '@0@.asciidoc'.format(manpage)
+
+ section = page['name'].split('.')[-1]
+
+ mandirn = join_paths(MANDIR, 'man' + section)
+
+ custom_target(
+ manpage,
+ command : [
+ A2X,
+ '--no-xmllint',
+ '-d', 'manpage',
+ '-f', 'manpage',
+ '--xsltproc-opts', '-param man.endnotes.list.enabled 0 -param man.endnotes.are.numbered 0',
+ '-D', '@OUTDIR@',
+ '--asciidoc-opts', ' '.join(asciidoc_opts),
+ '@INPUT@',
+ ],
+ input : input,
+ output : [manpage],
+ depend_files : [
+ asciidoc_conf,
+ ] + page.get('extra_depends', []),
+ install : true,
+ install_dir : mandirn,
+ )
+
+ html = custom_target(
+ htmlpage,
+ command : [
+ ASCIIDOC,
+ ] + asciidoc_opts + [
+ '-a', 'linkcss',
+ '-a', 'toc',
+ '-a', 'icons',
+ '-a', 'max-width=960px',
+ '-a', 'stylesheet=asciidoc-override.css',
+ '-o', '@OUTPUT@',
+ '@INPUT@',
+ ],
+ input : input,
+ output : [htmlpage],
+ depend_files : [
+ asciidoc_conf,
+ 'asciidoc-override.css',
+ ] + page.get('extra_depends', []),
+ build_by_default : false,
+ install : false,
+ )
+ html_targets += [html]
+ html_files += [htmlpage]
+endforeach
+
+run_target('html',
+ command : ['/bin/true'],
+ depends : html_targets)
+
+custom_target(
+ 'website.tar.gz',
+ command : [
+ 'bsdtar', 'czf', '@OUTPUT@',
+ '-C', meson.current_build_dir(),
+ ] + html_files + [
+ '-C', meson.current_source_dir(),
+ 'submitting-patches.html',
+ 'translation-help.html',
+ 'HACKING.html',
+ 'index.html',
+ 'asciidoc-override.css',
+ '-C', '/etc/asciidoc/stylesheets/',
+ 'asciidoc.css',
+ '-C', '/etc/asciidoc/javascripts/',
+ 'asciidoc.js',
+ '-C', '/etc/asciidoc/',
+ 'images',
+ ],
+ output : ['website.tar.gz'],
+ build_by_default : false,
+ depends : html_targets,
+)
+
+meson.add_install_script(MESON_MAKE_SYMLINK,
+ 'repo-add.8',
+ join_paths(MANDIR, 'man8/repo-remove.8'))
diff --git a/lib/libalpm/meson.build b/lib/libalpm/meson.build
new file mode 100644
index 00000000..84c3dde3
--- /dev/null
+++ b/lib/libalpm/meson.build
@@ -0,0 +1,33 @@
+libalpm_sources = files('''
+ add.h add.c
+ alpm.h alpm.c
+ alpm_list.h alpm_list.c
+ backup.h backup.c
+ base64.h base64.c
+ be_local.c
+ be_package.c
+ be_sync.c
+ conflict.h conflict.c
+ db.h db.c
+ delta.h delta.c
+ deps.h deps.c
+ diskspace.h diskspace.c
+ dload.h dload.c
+ error.c
+ filelist.h filelist.c
+ graph.h graph.c
+ group.h group.c
+ handle.h handle.c
+ hook.h hook.c
+ libarchive-compat.h
+ log.h log.c
+ package.h package.c
+ pkghash.h pkghash.c
+ rawstr.c
+ remove.h remove.c
+ signing.c signing.h
+ sync.h sync.c
+ trans.h trans.c
+ util.h util.c
+ version.c
+'''.split())
diff --git a/lib/libalpm/po/meson.build b/lib/libalpm/po/meson.build
new file mode 100644
index 00000000..cec28a15
--- /dev/null
+++ b/lib/libalpm/po/meson.build
@@ -0,0 +1,15 @@
+i18n.gettext(
+ 'libalpm',
+ args : [
+ '--directory=@0@'.format(meson.current_source_dir()),
+ '--msgid-bugs-address=http://bugs.archlinux.org/index.php?project=3',
+ '--copyright-holder="Pacman Development Team <pacman-dev(a)archlinux.org>"',
+ '--language', 'c',
+
+ '--keyword=_',
+ '--flag=_:1:c-format',
+
+ '--keyword=_n:1,2',
+ '--flag=_n:1:c-format',
+ '--flag=_n:2:c-format',
+ ])
diff --git a/meson.build b/meson.build
new file mode 100644
index 00000000..3f9b2ae0
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,487 @@
+project('pacman',
+ 'c',
+ version : '5.1.0',
+ license : 'GPLv2+',
+ default_options : [
+ 'c_std=gnu99',
+ 'prefix=/usr',
+ 'sysconfdir=/etc',
+ 'localstatedir=/var',
+ ],
+ meson_version : '>= 0.47')
+
+libalpm_version = '11.0.1'
+
+cc = meson.get_compiler('c')
+
+# commandline options
+PREFIX = get_option('prefix')
+DATAROOTDIR = join_paths(PREFIX, get_option('datarootdir'))
+SYSCONFDIR = join_paths(PREFIX, get_option('sysconfdir'))
+LOCALSTATEDIR = join_paths(PREFIX, get_option('localstatedir'))
+LOCALEDIR = join_paths(PREFIX, get_option('localedir'))
+ROOTDIR = get_option('root-dir')
+BINDIR = join_paths(PREFIX, get_option('bindir'))
+MANDIR = join_paths(PREFIX, get_option('mandir'))
+BUILDSCRIPT = get_option('buildscript')
+LIBMAKEPKGDIR = join_paths(PREFIX, DATAROOTDIR, 'makepkg')
+PKGDATADIR = join_paths(PREFIX, DATAROOTDIR, meson.project_name())
+
+PYTHON = find_program('python')
+M4 = find_program('m4')
+SED = find_program('sed')
+DU = find_program('du')
+LDCONFIG = get_option('ldconfig')
+MESON_MAKE_SYMLINK = join_paths(meson.source_root(), 'build-aux/meson-make-symlink.sh')
+
+BASH = find_program('bash4', 'bash')
+if BASH.found()
+ bash_version = run_command(BASH, '-c', 'IFS=.; echo "${BASH_VERSINFO[*]:0:3}"').stdout()
+
+ have_bash = bash_version.version_compare('>= 4.4.0')
+endif
+if not have_bash
+ error('bash >= 4.4.0 is required for pacman scripts.')
+endif
+
+bashcompletion = dependency('bash-completion', required : false)
+if bashcompletion.found()
+ BASHCOMPDIR = bashcompletion.get_pkgconfig_variable('completionsdir')
+else
+ BASHCOMPDIR = join_paths(DATAROOTDIR, 'bash-completion/completions')
+endif
+
+if get_option('use-git-version')
+ PACKAGE_VERSION = run_command(
+ find_program('git'),
+ 'describe',
+ '--abbrev=4',
+ '--dirty').stdout().strip().strip('v')
+else
+ PACKAGE_VERSION = meson.project_version()
+endif
+
+conf = configuration_data()
+conf.set('_GNU_SOURCE', true)
+conf.set_quoted('PACKAGE', meson.project_name())
+conf.set_quoted('PACKAGE_VERSION', PACKAGE_VERSION)
+conf.set_quoted('LOCALEDIR', LOCALEDIR)
+conf.set_quoted('SCRIPTLET_SHELL', get_option('scriptlet-shell'))
+conf.set_quoted('LDCONFIG', LDCONFIG)
+conf.set_quoted('LIB_VERSION', meson.project_version())
+conf.set_quoted('SYSHOOKDIR', join_paths(DATAROOTDIR, 'libalpm/hooks/'))
+conf.set_quoted('CONFFILE', join_paths(SYSCONFDIR, 'pacman.conf'))
+conf.set_quoted('DBPATH', join_paths(LOCALSTATEDIR, 'lib/pacman'))
+conf.set_quoted('GPGDIR', join_paths(SYSCONFDIR, 'pacman.d/gnupg'))
+conf.set_quoted('LOGFILE', join_paths(LOCALSTATEDIR, 'log/pacman.log'))
+conf.set_quoted('CACHEDIR', join_paths(LOCALSTATEDIR, 'cache/pacman/pkg'))
+conf.set_quoted('HOOKDIR', join_paths(SYSCONFDIR, 'pacman.d/hooks/'))
+conf.set_quoted('ROOTDIR', ROOTDIR)
+
+if get_option('i18n')
+ if not cc.has_function('ngettext')
+ error('ngettext not found but NLS support requested')
+ endif
+ conf.set('ENABLE_NLS', 1)
+endif
+
+# dependencies
+libarchive = dependency('libarchive',
+ version : '>=3.0.0',
+ static : get_option('buildstatic'))
+
+libcurl = dependency('libcurl',
+ version : '>=7.32.0',
+ required : get_option('curl'),
+ static : get_option('buildstatic'))
+conf.set('HAVE_LIBCURL', libcurl.found())
+
+want_gpgme = get_option('gpgme')
+gpgme_config = find_program('gpgme-config', required : want_gpgme)
+if not want_gpgme.disabled() and gpgme_config.found()
+ gpgme_version = run_command(gpgme_config, '--version').stdout().strip()
+
+ needed_gpgme_version = '>=1.3.0'
+ have = gpgme_version.version_compare(needed_gpgme_version)
+ if want_gpgme.enabled() and not have
+ error('gpgme @0@ is needed for GPG signature support'.format(needed_gpgme_version))
+ endif
+
+ gpgme_libs = [
+ cc.find_library('gpgme', required : have,
+ dirs : [get_option('gpgme-libdir')]),
+ cc.find_library('gpg-error', required : have,
+ dirs : [get_option('gpgme-libdir')]),
+ cc.find_library('assuan', required : have,
+ dirs : [get_option('gpgme-libdir')]),
+ ]
+
+ conf.set('HAVE_LIBGPGME', have)
+else
+ gpgme_libs = []
+ conf.set('HAVE_LIBGPGME', false)
+endif
+
+want_crypto = get_option('crypto')
+if want_crypto == 'openssl'
+ libcrypto = dependency('libcrypto', static : get_option('buildstatic'))
+ if not libcrypto.found()
+ error('openssl support requested but not found')
+ endif
+ crypto_provider = libcrypto
+ conf.set10('HAVE_LIBSSL', true)
+elif want_crypto == 'nettle'
+ libnettle = dependency('nettle', static : get_option('buildstatic'))
+ if not libnettle.found()
+ error('nettle support requested but not found')
+ endif
+ crypto_provider = libnettle
+ conf.set10('HAVE_LIBNETTLE', true)
+else
+ error('unhandled crypto value @0@'.format(want_crypto))
+endif
+
+foreach header : [
+ 'mntent.h',
+ 'sys/mnttab.h',
+ 'sys/mount.h',
+ 'sys/param.h',
+ 'sys/statvfs.h',
+ 'sys/types.h',
+ 'sys/ucred.h',
+ 'termios.h',
+ ]
+ if cc.has_header(header)
+ conf.set('HAVE_' + header.underscorify().to_upper(), true)
+ endif
+endforeach
+
+foreach sym : [
+ 'dup2',
+ 'fork',
+ 'getcwd',
+ 'getmntent',
+ 'getmntinfo',
+ 'gettimeofday',
+ 'memmove',
+ 'memset',
+ 'mkdir',
+ 'realpath',
+ 'regcomp',
+ 'rmdir',
+ 'setenv',
+ 'setlocale',
+ 'strcasecmp',
+ 'strchr',
+ 'strcspn',
+ 'strdup',
+ 'strerror',
+ 'strndup',
+ 'strnlen',
+ 'strnlen',
+ 'strrchr',
+ 'strsep',
+ 'strsep',
+ 'strstr',
+ 'strtol',
+ 'swprintf',
+ 'tcflush',
+ 'tcflush',
+ 'uname',
+ 'wcwidth',
+ ]
+ have = cc.has_function(sym, args : '-D_GNU_SOURCE')
+ conf.set10('HAVE_' + sym.to_upper(), have)
+endforeach
+
+foreach member : [
+ ['struct stat', 'st_blksize', '''#include <sys/stat.h>'''],
+ ['struct statvfs', 'f_flag', '''#include <sys/statvfs.h>'''],
+ ['struct statfs', 'f_flags', '''#include <sys/param.h>
+ #include <sys/mount.h>'''],
+ ]
+ have = cc.has_member(member[0], member[1], prefix : member[2])
+ conf.set('HAVE_' + '_'.join([member[0], member[1]]).underscorify().to_upper(), have)
+endforeach
+
+if conf.has('HAVE_STRUCT_STATVFS_F_FLAG')
+ conf.set('FSSTATSTYPE', 'struct statvfs')
+elif conf.has('HAVE_STRUCT_STATFS_F_FLAGS')
+ conf.set('FSSTATSTYPE', 'struct statfs')
+endif
+
+if get_option('buildtype') == 'debug'
+ extra_cflags = [
+ '-Wcast-align',
+ '-Wclobbered',
+ '-Wempty-body',
+ '-Wfloat-equal',
+ '-Wformat-nonliteral',
+ '-Wformat-security',
+ '-Wignored-qualifiers',
+ '-Winit-self',
+ '-Wlogical-op',
+ '-Wmissing-declarations',
+ '-Wmissing-field-initializers',
+ '-Wmissing-parameter-type',
+ '-Wmissing-prototypes',
+ '-Wold-style-declaration',
+ '-Woverride-init',
+ '-Wpointer-arith',
+ '-Wredundant-decls',
+ '-Wshadow',
+ '-Wsign-compare',
+ '-Wstrict-aliasing',
+ '-Wstrict-overflow=5',
+ '-Wstrict-prototypes',
+ '-Wtype-limits',
+ '-Wuninitialized',
+ '-Wunused-but-set-parameter',
+ '-Wunused-parameter',
+ '-Wwrite-strings',
+ ]
+ add_project_arguments(cc.get_supported_arguments(extra_cflags), language : 'c')
+
+ conf.set('PACMAN_DEBUG', 1)
+endif
+
+config_h = configure_file(
+ output : 'config.h',
+ configuration : conf)
+add_project_arguments('-include', 'config.h', language : 'c')
+
+default_duflags = ' -sk --apparent-size'
+default_sedinplaceflags = ' --follow-symlinks -i'
+inodecmd = 'stat -c \'%i %n\''
+ownercmd = 'stat -c \'%u:%g\''
+modecmd = 'stat -c \'%a\''
+strip_binaries = '--strip-all'
+strip_shared = '--strip-unneeded'
+strip_static = '--strip-debug'
+
+os = host_machine.system()
+if os.startswith('darwin')
+ inodecmd = '/usr/bin/stat -f \'%i %n\''
+ ownercmd = '/usr/bin/stat -f \'%u:%g\''
+ modecmd = '/usr/bin/stat -f \'%lp\''
+ default_sedinplaceflags = ' -i \'\''
+ default_duflags = ' -sk'
+ strip_binaries = ''
+ strip_shared = '-s'
+ strip_static = '-s'
+elif os.contains('bsd') or os == 'dragonfly'
+ inodecmd = 'stat -f \'%i %n\''
+ ownercmd = 'stat -f \'%u:%g\''
+ modecmd = 'stat -f \'%lp\''
+ default_sedinplaceflags = ' -i \'\''
+ default_duflags = ' -sk'
+endif
+
+duflags = get_option('duflags')
+if duflags == 'autodetect'
+ duflags = default_duflags
+endif
+
+sedinplaceflags = get_option('sedinplaceflags')
+if sedinplaceflags == 'auto'
+ sedinplaceflags = default_sedinplaceflags
+endif
+
+chost = run_command(cc, '-dumpmachine').stdout().strip()
+carch = chost.split('-')[0]
+
+# annoyingly, we have to maintain two sets of configuration_data which is
+# largely identical, but which distinguishes between quoting needs.
+substs = configuration_data()
+substs.set('SED', SED.path())
+substs.set('M4', M4.path())
+substs.set('CARCH', carch)
+substs.set('CHOST', chost)
+substs.set('PKGEXT', get_option('pkg-ext'))
+substs.set('SRCEXT', get_option('src-ext'))
+substs.set('ROOTDIR', ROOTDIR)
+substs.set('LOCALEDIR', LOCALEDIR)
+substs.set('sysconfdir', SYSCONFDIR)
+substs.set('localstatedir', LOCALSTATEDIR)
+substs.set('PKGDATADIR', PKGDATADIR)
+substs.set('PREFIX', PREFIX)
+substs.set('BASH', BASH.path())
+substs.set('PACKAGE_VERSION', PACKAGE_VERSION)
+substs.set('PACKAGE_NAME', meson.project_name())
+substs.set('BUILDSCRIPT', BUILDSCRIPT)
+substs.set('TEMPLATE_DIR', get_option('makepkg-template-dir'))
+substs.set('DEBUGSUFFIX', get_option('debug-suffix'))
+substs.set('INODECMD', inodecmd)
+substs.set('OWNERCMD', ownercmd)
+substs.set('MODECMD', modecmd)
+substs.set('SEDINPLACEFLAGS', sedinplaceflags)
+substs.set('SEDPATH', SED.path())
+substs.set('DUFLAGS', duflags)
+substs.set('DUPATH', DU.path())
+substs.set('LIBMAKEPKGDIR', LIBMAKEPKGDIR)
+substs.set('STRIP_BINARIES', strip_binaries)
+substs.set('STRIP_SHARED', strip_shared)
+substs.set('STRIP_STATIC', strip_static)
+
+subdir('lib/libalpm')
+subdir('src/common')
+subdir('src/pacman')
+subdir('src/util')
+subdir('scripts')
+
+# Internationalization
+if get_option('i18n')
+ i18n = import('i18n')
+ subdir('lib/libalpm/po')
+ subdir('src/pacman/po')
+ subdir('scripts/po')
+endif
+
+want_doc = get_option('doc')
+ASCIIDOC = find_program('asciidoc', required : want_doc)
+A2X = find_program('a2x', required : want_doc)
+build_doc = A2X.found() and not want_doc.disabled()
+if build_doc
+ subdir('doc')
+endif
+
+libcommon = static_library(
+ 'common',
+ libcommon_sources,
+ install : false)
+
+includes = include_directories('src/common', 'lib/libalpm')
+
+libalpm = library(
+ 'alpm',
+ libalpm_sources,
+ version : libalpm_version,
+ include_directories : includes,
+ dependencies : [crypto_provider, libarchive, libcurl] + gpgme_libs,
+ link_with : [libcommon],
+ install : true)
+
+install_headers(
+ 'lib/libalpm/alpm.h',
+ 'lib/libalpm/alpm_list.h')
+
+# TODO: this is lacking libs.private
+pkgconfig = import('pkgconfig')
+pkgconfig.generate(
+ libalpm,
+ name : 'libalpm',
+ description : 'Arch Linux package management library',
+ version : libalpm_version,
+ url : 'http://www.archlinux.org/pacman/',
+ requires_private : [crypto_provider, libcurl, libarchive])
+
+pacman_bin = executable(
+ 'pacman',
+ pacman_sources,
+ include_directories : includes,
+ link_with : [libalpm, libcommon],
+ dependencies : [libarchive],
+ install : true,
+)
+
+executable(
+ 'pacman-conf',
+ pacman_conf_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+executable(
+ 'cleanupdelta',
+ cleanupdelta_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+executable(
+ 'testpkg',
+ testpkg_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+executable(
+ 'vercmp',
+ vercmp_sources,
+ include_directories : includes,
+ link_with : [libalpm],
+ install : true,
+)
+
+configure_file(
+ input : 'etc/makepkg.conf.in',
+ output : 'makepkg.conf',
+ configuration : substs,
+ install_dir : SYSCONFDIR)
+
+configure_file(
+ input : 'etc/pacman.conf.in',
+ output : 'pacman.conf',
+ configuration : substs,
+ install_dir : SYSCONFDIR)
+
+install_data(
+ 'proto/PKGBUILD-split.proto',
+ 'proto/PKGBUILD-vcs.proto',
+ 'proto/PKGBUILD.proto',
+ 'proto/proto.install',
+ install_dir : join_paths(DATAROOTDIR, 'pacman'))
+
+TEST_ENV = environment()
+TEST_ENV.set('PMTEST_SCRIPTLIB_DIR', join_paths(meson.source_root(), 'scripts/library/'))
+TEST_ENV.set('PMTEST_LIBMAKEPKG_DIR', join_paths(meson.build_root(), 'scripts/libmakepkg/'))
+TEST_ENV.set('PMTEST_UTIL_DIR', meson.build_root() + '/')
+TEST_ENV.set('PMTEST_SCRIPT_DIR', join_paths(meson.build_root(), 'scripts/'))
+
+subdir('test/pacman')
+subdir('test/scripts')
+subdir('test/util')
+
+message('\n '.join([
+ '@0@ @1@'.format(meson.project_name(), meson.project_version()),
+ 'Build information:',
+ ' prefix : @0@'.format(PREFIX),
+ ' sysconfdir : @0@'.format(SYSCONFDIR),
+ ' conf file : @0@'.format(join_paths(SYSCONFDIR, 'pacman.conf')),
+ ' localstatedir : @0@'.format(LOCALSTATEDIR),
+ ' database dir : @0@'.format(join_paths(LOCALSTATEDIR, 'lib/pacman/')),
+ ' cache dir : @0@'.format(join_paths(LOCALSTATEDIR, 'cache/pacman/pkg/')),
+ ' compiler : @0@ @1@'.format(cc.get_id(), cc.version()),
+ '',
+ ' Architecture : @0@'.format(carch),
+ ' Host Type : @0@'.format(chost),
+ ' File inode command : @0@'.format(inodecmd),
+ ' File owner command : @0@'.format(ownercmd),
+ ' File mode command : @0@'.format(modecmd),
+ ' Directory size command : @0@ @1@'.format(DU.path(), duflags),
+ ' In-place sed command : @0@ @1@'.format(SED.path(), sedinplaceflags),
+ ' libalpm version : @0@'.format(libalpm_version),
+ ' pacman version : @0@'.format(PACKAGE_VERSION),
+ '',
+ 'Directory and file information:',
+ ' root working directory : @0@'.format(ROOTDIR),
+ ' package extension : @0@'.format(get_option('pkg-ext')),
+ ' source pkg extension : @0@'.format(get_option('src-ext')),
+ ' build script name : @0@'.format(BUILDSCRIPT),
+ ' template directory : @0@'.format(get_option('makepkg-template-dir')),
+ '',
+ 'Compilation options:',
+ ' i18n support : @0@'.format(get_option('i18n')),
+ ' Build docs : @0@'.format(build_doc),
+ ' debug build : @0@'.format(get_option('buildtype') == 'debug'),
+ ' Use libcurl : @0@'.format(conf.get('HAVE_LIBCURL')),
+ ' Use GPGME : @0@'.format(conf.get('HAVE_LIBGPGME')),
+ ' Use OpenSSL : @0@'.format(conf.has('HAVE_LIBSSL') and
+ conf.get('HAVE_LIBSSL') == 1),
+ ' Use nettle : @0@'.format(conf.has('HAVE_LIBNETTLE') and
+ conf.get('HAVE_LIBNETTLE') == 1),
+ '',
+]))
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 00000000..9e6e527e
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,58 @@
+# build behavior
+option('use-git-version', type : 'boolean', value : false,
+ description : 'take version information from git')
+option('buildstatic', type : 'boolean', value : false,
+ description : 'if true, build staticly linked binaries')
+
+# directories and filenames
+option('root-dir', type : 'string', value : '/',
+ description : 'set the location of the root operating directory')
+
+option('pkg-ext', type : 'string', value : '.pkg.tar.gz',
+ description : 'set the file extension used by packages')
+
+option('src-ext', type : 'string', value : '.src.tar.gz',
+ description : 'set the file extension used by source packages')
+
+option('scriptlet-shell', type : 'string', value : '/bin/sh',
+ description : 'The full path of the shell used to run install scriptlets')
+
+option('ldconfig', type : 'string', value : '/sbin/ldconfig',
+ description : 'set the full path to ldconfig')
+
+option('buildscript', type : 'string', value : 'PKGBUILD',
+ description : 'set the build script name used by makepkg')
+
+option('datarootdir', type : 'string', value : 'share',
+ description : 'FIXME')
+
+option('makepkg-template-dir', type : 'string', value : '/usr/share/makepkg-template',
+ description : 'template dir used by makepkg-template')
+
+option('debug-suffix', type : 'string', value : 'debug',
+ description : 'suffix for split debugging symbol packages used by makepkg')
+
+# dependencies, features
+option('doc', type : 'feature', value : 'auto',
+ description : 'generate docs and manpages')
+
+option('curl', type : 'feature', value : 'auto',
+ description : 'use curl to download files')
+
+option('crypto', type : 'combo', choices : ['openssl', 'nettle'],
+ description : 'select crypto implementation')
+
+option('gpgme', type : 'feature', value : 'auto',
+ description : 'use GPGME for PGP signature verification')
+option('gpgme-libdir', type : 'string', value : '/usr/lib',
+ description : 'search directory for gpgme libraries.')
+
+option('i18n', type : 'boolean', value : true,
+ description : 'enable localization of pacman, libalpm and scripts')
+
+# tools
+option('duflags', type : 'string', value : 'autodetect',
+ description : 'flags to pass to du to measure file size')
+
+option('sedinplaceflags', type : 'string', value : 'auto',
+ description : 'flags to pass to sed to edit a file in-place')
diff --git a/scripts/libmakepkg/integrity/meson.build b/scripts/libmakepkg/integrity/meson.build
new file mode 100644
index 00000000..9aa9061c
--- /dev/null
+++ b/scripts/libmakepkg/integrity/meson.build
@@ -0,0 +1,20 @@
+libmakepkg_module = 'integrity'
+
+sources = [
+ 'generate_checksum.sh.in',
+ 'generate_signature.sh.in',
+ 'verify_checksum.sh.in',
+ 'verify_signature.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/lint_config/meson.build b/scripts/libmakepkg/lint_config/meson.build
new file mode 100644
index 00000000..884d63d7
--- /dev/null
+++ b/scripts/libmakepkg/lint_config/meson.build
@@ -0,0 +1,18 @@
+libmakepkg_module = 'lint_config'
+
+sources = [
+ 'paths.sh.in',
+ 'variable.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/lint_package/meson.build b/scripts/libmakepkg/lint_package/meson.build
new file mode 100644
index 00000000..8eb1aaf7
--- /dev/null
+++ b/scripts/libmakepkg/lint_package/meson.build
@@ -0,0 +1,20 @@
+libmakepkg_module = 'lint_package'
+
+sources = [
+ 'build_references.sh.in',
+ 'dotfiles.sh.in',
+ 'file_names.sh.in',
+ 'missing_backup.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/lint_pkgbuild/meson.build b/scripts/libmakepkg/lint_pkgbuild/meson.build
new file mode 100644
index 00000000..9067c9d6
--- /dev/null
+++ b/scripts/libmakepkg/lint_pkgbuild/meson.build
@@ -0,0 +1,37 @@
+libmakepkg_module = 'lint_pkgbuild'
+
+sources = [
+ 'arch.sh.in',
+ 'backup.sh.in',
+ 'changelog.sh.in',
+ 'checkdepends.sh.in',
+ 'conflicts.sh.in',
+ 'depends.sh.in',
+ 'epoch.sh.in',
+ 'install.sh.in',
+ 'makedepends.sh.in',
+ 'optdepends.sh.in',
+ 'options.sh.in',
+ 'package_function.sh.in',
+ 'pkgbase.sh.in',
+ 'pkglist.sh.in',
+ 'pkgname.sh.in',
+ 'pkgrel.sh.in',
+ 'pkgver.sh.in',
+ 'provides.sh.in',
+ 'source.sh.in',
+ 'util.sh.in',
+ 'variable.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/meson.build b/scripts/libmakepkg/meson.build
new file mode 100644
index 00000000..07475b4d
--- /dev/null
+++ b/scripts/libmakepkg/meson.build
@@ -0,0 +1,31 @@
+libmakepkg_modules = [
+ { 'name' : 'integrity', 'has_subdir' : true },
+ { 'name' : 'lint_config', 'has_subdir' : true },
+ { 'name' : 'lint_package', 'has_subdir' : true },
+ { 'name' : 'lint_pkgbuild', 'has_subdir' : true },
+ { 'name' : 'source', 'has_subdir' : true },
+ { 'name' : 'srcinfo', },
+ { 'name' : 'tidy', 'has_subdir' : true },
+ { 'name' : 'util', 'has_subdir' : true },
+]
+
+mkdir_p = 'mkdir -p $DESTDIR/@0@'
+
+foreach module : libmakepkg_modules
+ custom_target(
+ 'libmakepkg_@0@'.format(module['name']),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : '@0@.sh.in'.format(module['name']),
+ output : '@BASENAME@',
+ install : true,
+ install_dir : join_paths(get_option('datadir'), 'makepkg'))
+
+ if module.get('has_subdir', false)
+ subdir(module['name'])
+ path = join_paths(get_option('prefix'),
+ get_option('datadir'),
+ 'makepkg',
+ module['name'])
+ meson.add_install_script('sh', '-c', mkdir_p.format(path))
+ endif
+endforeach
diff --git a/scripts/libmakepkg/source/meson.build b/scripts/libmakepkg/source/meson.build
new file mode 100644
index 00000000..59326133
--- /dev/null
+++ b/scripts/libmakepkg/source/meson.build
@@ -0,0 +1,22 @@
+libmakepkg_module = 'source'
+
+sources = [
+ 'bzr.sh.in',
+ 'file.sh.in',
+ 'git.sh.in',
+ 'hg.sh.in',
+ 'local.sh.in',
+ 'svn.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/tidy/meson.build b/scripts/libmakepkg/tidy/meson.build
new file mode 100644
index 00000000..052ac7a2
--- /dev/null
+++ b/scripts/libmakepkg/tidy/meson.build
@@ -0,0 +1,23 @@
+libmakepkg_module = 'tidy'
+
+sources = [
+ 'docs.sh.in',
+ 'emptydirs.sh.in',
+ 'libtool.sh.in',
+ 'purge.sh.in',
+ 'staticlibs.sh.in',
+ 'strip.sh.in',
+ 'zipman.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/libmakepkg/util/meson.build b/scripts/libmakepkg/util/meson.build
new file mode 100644
index 00000000..b0e829c4
--- /dev/null
+++ b/scripts/libmakepkg/util/meson.build
@@ -0,0 +1,24 @@
+libmakepkg_module = 'util'
+
+sources = [
+ 'compress.sh.in',
+ 'error.sh.in',
+ 'message.sh.in',
+ 'option.sh.in',
+ 'parseopts.sh.in',
+ 'pkgbuild.sh.in',
+ 'source.sh.in',
+ 'util.sh.in',
+]
+
+foreach src : sources
+ output_dir = join_paths(get_option('datadir'), 'makepkg', libmakepkg_module)
+
+ custom_target(
+ libmakepkg_module + '_' + src.underscorify(),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : src,
+ output : '@BASENAME@',
+ install : true,
+ install_dir : output_dir)
+endforeach
diff --git a/scripts/meson.build b/scripts/meson.build
new file mode 100644
index 00000000..1fe3fb78
--- /dev/null
+++ b/scripts/meson.build
@@ -0,0 +1,66 @@
+scripts = [
+ 'makepkg-template.pl.in',
+ 'makepkg.sh.in',
+ 'pacman-db-upgrade.sh.in',
+ 'pacman-key.sh.in',
+ 'pkgdelta.sh.in',
+ 'repo-add.sh.in'
+]
+
+library_files = [
+ 'library/human_to_size.sh',
+ 'library/size_to_human.sh',
+]
+
+SCRIPT_EDITOR = find_program(configure_file(
+ input : join_paths(meson.source_root(), 'build-aux/edit-script.sh.in'),
+ output : 'edit-script.sh',
+ configuration : substs))
+
+m4_edit = generator(
+ M4,
+ arguments : ['-P', '-I', meson.current_source_dir(), '@INPUT@'],
+ output : '@PLAINNAME@',
+ capture : true)
+
+foreach script : scripts
+ custom_target(
+ script,
+ input : m4_edit.process(script),
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@', '0755'],
+ output : script.split('.')[0],
+ depend_files : library_files,
+ install : true,
+ install_dir : get_option('bindir'))
+endforeach
+
+foreach symlink : ['repo-remove', 'repo-elephant']
+ meson.add_install_script(MESON_MAKE_SYMLINK,
+ 'repo-add',
+ join_paths(BINDIR, symlink))
+endforeach
+
+subdir('libmakepkg')
+
+custom_target(
+ 'bash_completion',
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : 'completion/bash_completion.in',
+ output : 'pacman',
+ install : true,
+ install_dir : BASHCOMPDIR)
+
+foreach symlink : ['pacman-key', 'makepkg']
+ meson.add_install_script(MESON_MAKE_SYMLINK,
+ 'pacman',
+ join_paths(BASHCOMPDIR, symlink))
+endforeach
+
+zsh_completion_dir = join_paths(DATAROOTDIR, 'zsh/site-functions')
+custom_target(
+ 'zsh_completion',
+ command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@' ],
+ input : 'completion/zsh_completion.in',
+ output : '_pacman',
+ install : true,
+ install_dir : zsh_completion_dir)
diff --git a/scripts/po/meson.build b/scripts/po/meson.build
new file mode 100644
index 00000000..d8b8c51c
--- /dev/null
+++ b/scripts/po/meson.build
@@ -0,0 +1,15 @@
+i18n.gettext(
+ 'pacman-scripts',
+ args : [
+ '--directory=@0@'.format(meson.current_source_dir()),
+ '--msgid-bugs-address=http://bugs.archlinux.org/index.php?project=3',
+ '--copyright-holder="Pacman Development Team <pacman-dev(a)archlinux.org>"',
+ '--language', 'shell',
+
+ '--keyword=_',
+ '--flag=_:1:c-format',
+
+ '--keyword=_n:1,2',
+ '--flag=_n:1:c-format',
+ '--flag=_n:2:c-format',
+ ])
diff --git a/src/common/meson.build b/src/common/meson.build
new file mode 100644
index 00000000..1443be3b
--- /dev/null
+++ b/src/common/meson.build
@@ -0,0 +1,4 @@
+libcommon_sources = files('''
+ ini.c ini.h
+ util-common.c util-common.h
+'''.split())
diff --git a/src/pacman/meson.build b/src/pacman/meson.build
new file mode 100644
index 00000000..6926f676
--- /dev/null
+++ b/src/pacman/meson.build
@@ -0,0 +1,23 @@
+pacman_sources = files('''
+ check.h check.c
+ conf.h conf.c
+ database.c
+ deptest.c
+ files.c
+ package.h package.c
+ pacman.h pacman.c
+ query.c
+ remove.c
+ sighandler.h sighandler.c
+ sync.c
+ callback.h callback.c
+ upgrade.c
+ util.h util.c
+'''.split())
+
+pacman_conf_sources = files('''
+ pacman-conf.c
+ util.h util.c
+ callback.h callback.c
+ conf.h conf.c
+'''.split())
diff --git a/src/pacman/po/meson.build b/src/pacman/po/meson.build
new file mode 100644
index 00000000..eb45fa1c
--- /dev/null
+++ b/src/pacman/po/meson.build
@@ -0,0 +1,15 @@
+i18n.gettext(
+ 'pacman',
+ args : [
+ '--directory=@0@'.format(meson.current_source_dir()),
+ '--msgid-bugs-address=http://bugs.archlinux.org/index.php?project=3',
+ '--copyright-holder="Pacman Development Team <pacman-dev(a)archlinux.org>"',
+ '--language', 'c',
+
+ '--keyword=_',
+ '--flag=_:1:c-format',
+
+ '--keyword=_n:1,2',
+ '--flag=_n:1:c-format',
+ '--flag=_n:2:c-format',
+ ])
diff --git a/src/util/meson.build b/src/util/meson.build
new file mode 100644
index 00000000..cc219670
--- /dev/null
+++ b/src/util/meson.build
@@ -0,0 +1,3 @@
+cleanupdelta_sources = files('cleanupdelta.c')
+testpkg_sources = files('testpkg.c')
+vercmp_sources = files('vercmp.c')
diff --git a/test/pacman/meson.build b/test/pacman/meson.build
new file mode 100644
index 00000000..dbdb429e
--- /dev/null
+++ b/test/pacman/meson.build
@@ -0,0 +1,357 @@
+pacman_tests = [
+ { 'name': 'tests/backup001.py' },
+ { 'name': 'tests/clean001.py' },
+ { 'name': 'tests/clean002.py' },
+ { 'name': 'tests/clean003.py' },
+ { 'name': 'tests/clean004.py' },
+ { 'name': 'tests/clean005.py' },
+ { 'name': 'tests/config001.py' },
+ { 'name': 'tests/config002.py' },
+ { 'name': 'tests/database001.py' },
+ { 'name': 'tests/database002.py' },
+ { 'name': 'tests/database010.py' },
+ { 'name': 'tests/database011.py' },
+ { 'name': 'tests/database012.py' },
+ { 'name': 'tests/dbonly-extracted-files.py' },
+ { 'name': 'tests/depconflict100.py' },
+ { 'name': 'tests/depconflict110.py' },
+ { 'name': 'tests/depconflict111.py' },
+ { 'name': 'tests/depconflict120.py' },
+ { 'name': 'tests/dependency-cycle-fixed-by-upgrade.py' },
+ { 'name': 'tests/deprange001.py',
+ 'should_fail': true },
+ { 'name': 'tests/deptest001.py' },
+ { 'name': 'tests/dummy001.py' },
+ { 'name': 'tests/epoch001.py' },
+ { 'name': 'tests/epoch002.py' },
+ { 'name': 'tests/epoch003.py' },
+ { 'name': 'tests/epoch004.py' },
+ { 'name': 'tests/epoch005.py' },
+ { 'name': 'tests/epoch010.py' },
+ { 'name': 'tests/epoch011.py' },
+ { 'name': 'tests/epoch012.py' },
+ { 'name': 'tests/file-conflict-with-installed-pkg.py' },
+ { 'name': 'tests/fileconflict001.py' },
+ { 'name': 'tests/fileconflict002.py' },
+ { 'name': 'tests/fileconflict003.py' },
+ { 'name': 'tests/fileconflict004.py' },
+ { 'name': 'tests/fileconflict005.py' },
+ { 'name': 'tests/fileconflict006.py' },
+ { 'name': 'tests/fileconflict007.py' },
+ { 'name': 'tests/fileconflict008.py' },
+ { 'name': 'tests/fileconflict009.py' },
+ { 'name': 'tests/fileconflict010.py' },
+ { 'name': 'tests/fileconflict011.py' },
+ { 'name': 'tests/fileconflict012.py' },
+ { 'name': 'tests/fileconflict013.py' },
+ { 'name': 'tests/fileconflict015.py' },
+ { 'name': 'tests/fileconflict016.py' },
+ { 'name': 'tests/fileconflict017.py' },
+ { 'name': 'tests/fileconflict020.py' },
+ { 'name': 'tests/fileconflict021.py' },
+ { 'name': 'tests/fileconflict022.py' },
+ { 'name': 'tests/fileconflict023.py' },
+ { 'name': 'tests/fileconflict024.py' },
+ { 'name': 'tests/fileconflict025.py' },
+ { 'name': 'tests/fileconflict030.py' },
+ { 'name': 'tests/fileconflict031.py' },
+ { 'name': 'tests/fileconflict032.py' },
+ { 'name': 'tests/hook-abortonfail.py' },
+ { 'name': 'tests/hook-description-reused.py' },
+ { 'name': 'tests/hook-exec-reused.py' },
+ { 'name': 'tests/hook-exec-with-arguments.py' },
+ { 'name': 'tests/hook-file-change-packages.py' },
+ { 'name': 'tests/hook-file-remove-trigger-match.py' },
+ { 'name': 'tests/hook-file-upgrade-nomatch.py' },
+ { 'name': 'tests/hook-invalid-trigger.py' },
+ { 'name': 'tests/hook-pkg-install-trigger-match.py' },
+ { 'name': 'tests/hook-pkg-postinstall-trigger-match.py' },
+ { 'name': 'tests/hook-pkg-remove-trigger-match.py' },
+ { 'name': 'tests/hook-pkg-upgrade-trigger-match.py' },
+ { 'name': 'tests/hook-target-list.py' },
+ { 'name': 'tests/hook-type-reused.py' },
+ { 'name': 'tests/hook-upgrade-trigger-no-match.py' },
+ { 'name': 'tests/hook-when-reused.py' },
+ { 'name': 'tests/ignore001.py' },
+ { 'name': 'tests/ignore002.py' },
+ { 'name': 'tests/ignore003.py' },
+ { 'name': 'tests/ignore004.py' },
+ { 'name': 'tests/ignore005.py' },
+ { 'name': 'tests/ignore006.py' },
+ { 'name': 'tests/ignore007.py' },
+ { 'name': 'tests/ignore008.py' },
+ { 'name': 'tests/ldconfig001.py' },
+ { 'name': 'tests/ldconfig002.py' },
+ { 'name': 'tests/ldconfig003.py' },
+ { 'name': 'tests/mode001.py' },
+ { 'name': 'tests/mode002.py' },
+ { 'name': 'tests/mode003.py' },
+ { 'name': 'tests/noupgrade-inverted.py' },
+ { 'name': 'tests/overwrite-files-match-negated.py' },
+ { 'name': 'tests/overwrite-files-match.py' },
+ { 'name': 'tests/overwrite-files-nonmatch.py' },
+ { 'name': 'tests/pacman001.py' },
+ { 'name': 'tests/pacman002.py' },
+ { 'name': 'tests/pacman003.py' },
+ { 'name': 'tests/pacman004.py' },
+ { 'name': 'tests/pacman005.py' },
+ { 'name': 'tests/provision001.py' },
+ { 'name': 'tests/provision002.py' },
+ { 'name': 'tests/provision003.py' },
+ { 'name': 'tests/provision004.py' },
+ { 'name': 'tests/provision010.py' },
+ { 'name': 'tests/provision011.py' },
+ { 'name': 'tests/provision012.py' },
+ { 'name': 'tests/provision020.py' },
+ { 'name': 'tests/provision021.py' },
+ { 'name': 'tests/provision022.py' },
+ { 'name': 'tests/query001.py' },
+ { 'name': 'tests/query002.py' },
+ { 'name': 'tests/query003.py' },
+ { 'name': 'tests/query004.py' },
+ { 'name': 'tests/query005.py' },
+ { 'name': 'tests/query006.py',
+ # expect failure on 32 bit machines
+ 'should_fail': cc.sizeof('ssize_t') < 8 },
+ { 'name': 'tests/query007.py' },
+ { 'name': 'tests/query010.py' },
+ { 'name': 'tests/query011.py' },
+ { 'name': 'tests/query012.py' },
+ { 'name': 'tests/querycheck001.py' },
+ { 'name': 'tests/querycheck002.py' },
+ { 'name': 'tests/querycheck_fast_file_type.py' },
+ { 'name': 'tests/reason001.py' },
+ { 'name': 'tests/remove-assumeinstalled.py' },
+ { 'name': 'tests/remove-directory-replaced-with-symlink.py' },
+ { 'name': 'tests/remove-optdepend-of-installed-package.py' },
+ { 'name': 'tests/remove-recursive-cycle.py' },
+ { 'name': 'tests/remove001.py' },
+ { 'name': 'tests/remove002.py' },
+ { 'name': 'tests/remove010.py' },
+ { 'name': 'tests/remove011.py' },
+ { 'name': 'tests/remove012.py' },
+ { 'name': 'tests/remove020.py' },
+ { 'name': 'tests/remove021.py' },
+ { 'name': 'tests/remove030.py' },
+ { 'name': 'tests/remove031.py' },
+ { 'name': 'tests/remove040.py' },
+ { 'name': 'tests/remove041.py' },
+ { 'name': 'tests/remove042.py' },
+ { 'name': 'tests/remove043.py' },
+ { 'name': 'tests/remove044.py' },
+ { 'name': 'tests/remove045.py' },
+ { 'name': 'tests/remove047.py' },
+ { 'name': 'tests/remove049.py' },
+ { 'name': 'tests/remove050.py' },
+ { 'name': 'tests/remove051.py' },
+ { 'name': 'tests/remove052.py' },
+ { 'name': 'tests/remove060.py' },
+ { 'name': 'tests/remove070.py' },
+ { 'name': 'tests/remove071.py' },
+ { 'name': 'tests/replace100.py' },
+ { 'name': 'tests/replace101.py' },
+ { 'name': 'tests/replace102.py' },
+ { 'name': 'tests/replace103.py' },
+ { 'name': 'tests/replace104.py' },
+ { 'name': 'tests/replace110.py',
+ 'should_fail': true },
+ { 'name': 'tests/scriptlet001.py' },
+ { 'name': 'tests/scriptlet002.py' },
+ { 'name': 'tests/sign001.py' },
+ { 'name': 'tests/sign002.py' },
+ { 'name': 'tests/skip-remove-with-glob-chars.py' },
+ { 'name': 'tests/smoke001.py' },
+ { 'name': 'tests/smoke002.py' },
+ { 'name': 'tests/smoke003.py' },
+ { 'name': 'tests/smoke004.py' },
+ { 'name': 'tests/symlink-replace-with-dir.py' },
+ { 'name': 'tests/symlink001.py' },
+ { 'name': 'tests/symlink002.py' },
+ { 'name': 'tests/symlink010.py' },
+ { 'name': 'tests/symlink011.py' },
+ { 'name': 'tests/symlink012.py' },
+ { 'name': 'tests/symlink020.py' },
+ { 'name': 'tests/symlink021.py' },
+ { 'name': 'tests/sync-install-assumeinstalled.py' },
+ { 'name': 'tests/sync-nodepversion01.py' },
+ { 'name': 'tests/sync-nodepversion02.py' },
+ { 'name': 'tests/sync-nodepversion03.py' },
+ { 'name': 'tests/sync-nodepversion04.py' },
+ { 'name': 'tests/sync-nodepversion05.py' },
+ { 'name': 'tests/sync-nodepversion06.py' },
+ { 'name': 'tests/sync-sysupgrade-print-replaced-packages.py' },
+ { 'name': 'tests/sync-update-assumeinstalled.py' },
+ { 'name': 'tests/sync-update-package-removing-required-provides.py',
+ 'should_fail': true },
+ { 'name': 'tests/sync001.py' },
+ { 'name': 'tests/sync002.py' },
+ { 'name': 'tests/sync003.py' },
+ { 'name': 'tests/sync009.py' },
+ { 'name': 'tests/sync010.py' },
+ { 'name': 'tests/sync011.py' },
+ { 'name': 'tests/sync012.py' },
+ { 'name': 'tests/sync020.py' },
+ { 'name': 'tests/sync021.py' },
+ { 'name': 'tests/sync022.py' },
+ { 'name': 'tests/sync023.py' },
+ { 'name': 'tests/sync024.py' },
+ { 'name': 'tests/sync030.py' },
+ { 'name': 'tests/sync031.py' },
+ { 'name': 'tests/sync040.py' },
+ { 'name': 'tests/sync041.py' },
+ { 'name': 'tests/sync042.py' },
+ { 'name': 'tests/sync043.py' },
+ { 'name': 'tests/sync044.py' },
+ { 'name': 'tests/sync045.py' },
+ { 'name': 'tests/sync046.py' },
+ { 'name': 'tests/sync050.py' },
+ { 'name': 'tests/sync051.py' },
+ { 'name': 'tests/sync052.py' },
+ { 'name': 'tests/sync100.py' },
+ { 'name': 'tests/sync1000.py' },
+ { 'name': 'tests/sync1003.py' },
+ { 'name': 'tests/sync1004.py' },
+ { 'name': 'tests/sync1008.py' },
+ { 'name': 'tests/sync101.py' },
+ { 'name': 'tests/sync102.py' },
+ { 'name': 'tests/sync103.py' },
+ { 'name': 'tests/sync104.py' },
+ { 'name': 'tests/sync110.py' },
+ { 'name': 'tests/sync1100.py' },
+ { 'name': 'tests/sync1101.py' },
+ { 'name': 'tests/sync1102.py' },
+ { 'name': 'tests/sync1103.py' },
+ { 'name': 'tests/sync1104.py' },
+ { 'name': 'tests/sync1105.py' },
+ { 'name': 'tests/sync120.py' },
+ { 'name': 'tests/sync130.py' },
+ { 'name': 'tests/sync131.py' },
+ { 'name': 'tests/sync132.py' },
+ { 'name': 'tests/sync133.py' },
+ { 'name': 'tests/sync134.py' },
+ { 'name': 'tests/sync135.py' },
+ { 'name': 'tests/sync136.py' },
+ { 'name': 'tests/sync137.py' },
+ { 'name': 'tests/sync138.py' },
+ { 'name': 'tests/sync139.py' },
+ { 'name': 'tests/sync140.py' },
+ { 'name': 'tests/sync141.py' },
+ { 'name': 'tests/sync150.py' },
+ { 'name': 'tests/sync200.py' },
+ { 'name': 'tests/sync300.py' },
+ { 'name': 'tests/sync306.py' },
+ { 'name': 'tests/sync400.py' },
+ { 'name': 'tests/sync401.py' },
+ { 'name': 'tests/sync402.py' },
+ { 'name': 'tests/sync403.py',
+ 'should_fail': true },
+ { 'name': 'tests/sync404.py' },
+ { 'name': 'tests/sync405.py' },
+ { 'name': 'tests/sync406.py',
+ 'should_fail': true },
+ { 'name': 'tests/sync407.py' },
+ { 'name': 'tests/sync500.py' },
+ { 'name': 'tests/sync501.py' },
+ { 'name': 'tests/sync502.py' },
+ { 'name': 'tests/sync503.py' },
+ { 'name': 'tests/sync600.py' },
+ { 'name': 'tests/sync700.py' },
+ { 'name': 'tests/sync701.py' },
+ { 'name': 'tests/sync702.py' },
+ { 'name': 'tests/sync890.py' },
+ { 'name': 'tests/sync891.py' },
+ { 'name': 'tests/sync892.py' },
+ { 'name': 'tests/sync893.py' },
+ { 'name': 'tests/sync895.py' },
+ { 'name': 'tests/sync896.py' },
+ { 'name': 'tests/sync897.py' },
+ { 'name': 'tests/sync898.py' },
+ { 'name': 'tests/sync899.py' },
+ { 'name': 'tests/sync900.py' },
+ { 'name': 'tests/sync901.py' },
+ { 'name': 'tests/sync990.py' },
+ { 'name': 'tests/sync992.py' },
+ { 'name': 'tests/sync993.py' },
+ { 'name': 'tests/sync999.py' },
+ { 'name': 'tests/trans001.py' },
+ { 'name': 'tests/type001.py' },
+ { 'name': 'tests/unresolvable001.py' },
+ { 'name': 'tests/upgrade001.py' },
+ { 'name': 'tests/upgrade002.py' },
+ { 'name': 'tests/upgrade003.py' },
+ { 'name': 'tests/upgrade004.py' },
+ { 'name': 'tests/upgrade005.py' },
+ { 'name': 'tests/upgrade006.py' },
+ { 'name': 'tests/upgrade010.py' },
+ { 'name': 'tests/upgrade011.py' },
+ { 'name': 'tests/upgrade013.py' },
+ { 'name': 'tests/upgrade020.py' },
+ { 'name': 'tests/upgrade021.py' },
+ { 'name': 'tests/upgrade022.py' },
+ { 'name': 'tests/upgrade023.py' },
+ { 'name': 'tests/upgrade024.py' },
+ { 'name': 'tests/upgrade025.py' },
+ { 'name': 'tests/upgrade026.py' },
+ { 'name': 'tests/upgrade027.py' },
+ { 'name': 'tests/upgrade028.py' },
+ { 'name': 'tests/upgrade029.py' },
+ { 'name': 'tests/upgrade030.py' },
+ { 'name': 'tests/upgrade031.py' },
+ { 'name': 'tests/upgrade032.py' },
+ { 'name': 'tests/upgrade040.py' },
+ { 'name': 'tests/upgrade041.py' },
+ { 'name': 'tests/upgrade042.py' },
+ { 'name': 'tests/upgrade043.py' },
+ { 'name': 'tests/upgrade045.py' },
+ { 'name': 'tests/upgrade050.py' },
+ { 'name': 'tests/upgrade051.py' },
+ { 'name': 'tests/upgrade052.py' },
+ { 'name': 'tests/upgrade053.py' },
+ { 'name': 'tests/upgrade054.py' },
+ { 'name': 'tests/upgrade055.py' },
+ { 'name': 'tests/upgrade056.py' },
+ { 'name': 'tests/upgrade057.py' },
+ { 'name': 'tests/upgrade058.py' },
+ { 'name': 'tests/upgrade059.py' },
+ { 'name': 'tests/upgrade060.py' },
+ { 'name': 'tests/upgrade061.py' },
+ { 'name': 'tests/upgrade070.py' },
+ { 'name': 'tests/upgrade071.py' },
+ { 'name': 'tests/upgrade072.py' },
+ { 'name': 'tests/upgrade073.py' },
+ { 'name': 'tests/upgrade074.py' },
+ { 'name': 'tests/upgrade075.py' },
+ { 'name': 'tests/upgrade076.py' },
+ { 'name': 'tests/upgrade077.py' },
+ { 'name': 'tests/upgrade078.py',
+ 'should_fail': true },
+ { 'name': 'tests/upgrade080.py' },
+ { 'name': 'tests/upgrade081.py' },
+ { 'name': 'tests/upgrade082.py' },
+ { 'name': 'tests/upgrade083.py' },
+ { 'name': 'tests/upgrade084.py' },
+ { 'name': 'tests/upgrade090.py' },
+ { 'name': 'tests/upgrade100.py' },
+ { 'name': 'tests/xfercommand001.py' },
+]
+
+foreach testobj : pacman_tests
+ input = testobj.get('name')
+ test_name = input.split('/')[1]
+ should_fail = testobj.get('should_fail', false)
+
+ test(
+ test_name,
+ PYTHON,
+ args : [
+ join_paths(meson.source_root(), 'build-aux/tap-driver.py'),
+ join_paths(meson.current_source_dir(), 'pactest.py'),
+ '--scriptlet-shell', get_option('scriptlet-shell'),
+ '--bindir', meson.build_root(),
+ '--ldconfig', LDCONFIG,
+ '--verbose',
+ join_paths(meson.current_source_dir(), input)
+ ],
+ depends : [pacman_bin],
+ should_fail : should_fail)
+endforeach
diff --git a/test/scripts/meson.build b/test/scripts/meson.build
new file mode 100644
index 00000000..6d6194dd
--- /dev/null
+++ b/test/scripts/meson.build
@@ -0,0 +1,12 @@
+tests = [
+ 'parseopts_test.sh',
+ 'makepkg-template_test.sh',
+ 'human_to_size_test.sh',
+]
+
+foreach tst : tests
+ test(tst,
+ BASH,
+ env : TEST_ENV,
+ args : [join_paths(meson.current_source_dir(), tst)])
+endforeach
diff --git a/test/util/meson.build b/test/util/meson.build
new file mode 100644
index 00000000..07b29e5c
--- /dev/null
+++ b/test/util/meson.build
@@ -0,0 +1,6 @@
+test('vercmptest',
+ BASH,
+ env : TEST_ENV,
+ args : [
+ join_paths(meson.current_source_dir(), 'vercmptest.sh')
+ ])
--
2.19.1
5
17
[pacman-dev] [PATCH 1/2] makepkg: fix .PKGINFO/.BUILDINFO files swallowing status printing
by Eli Schwartz 31 Oct '18
by Eli Schwartz 31 Oct '18
31 Oct '18
The respective write_* functions are low-level and shouldn't be
outputting statuses; move these to the logic flow where they are used.
This ensures the functions can be used in the future wherever, and also
solves an issue where, as fallout from the message.sh retrofitting in
commit 882e707e40bbade0111cf3bdedbdac4d4b70453b, the statuses got
redirected to the actual files.
The resulting package was technically correct, except that it contained
useless lines which pacman ignored, and repo-add also ignored but at the
same time generated an error message:
/usr/bin/repo-add: line 335: declare: `=-> Generating .PKGINFO file...': not a valid identifier
Thirdparty package tools with stricter parsers may abort with errors,
and "repose" is known to do so.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/makepkg.sh.in | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index 87253883..3ac03d11 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -634,7 +634,6 @@ write_pkginfo() {
merge_arch_attrs
- msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
printf "# Generated by makepkg %s\n" "$makepkg_version"
printf "# using %s\n" "$(fakeroot -v)"
@@ -672,8 +671,6 @@ write_pkginfo() {
}
write_buildinfo() {
- msg2 "$(gettext "Generating %s file...")" ".BUILDINFO"
-
write_kv_pair "format" "1"
write_kv_pair "pkgname" "$pkgname"
@@ -728,7 +725,9 @@ create_package() {
msg "$(gettext "Creating package \"%s\"...")" "$pkgname"
pkgarch=$(get_pkg_arch)
+ msg2 "$(gettext "Generating %s file...")" ".PKGINFO"
write_pkginfo > .PKGINFO
+ msg2 "$(gettext "Generating %s file...")" ".BUILDINFO"
write_buildinfo > .BUILDINFO
# check for changelog/install files
--
2.19.1
1
1
[pacman-dev] [PATCH] meson: add a wrapper to bootstrap scripts from within build dir
by Dave Reisner 29 Oct '18
by Dave Reisner 29 Oct '18
29 Oct '18
This doesn't do quite as good of a job of "hiding away" the real script
as we did with autotools, but it satisfies the need for being able to
run scripts which depend on libmakepkg with the local copy within the
repo. We do, however, improve upon the autotools script by ensuring that
the bash path used in configuring pacman is the interpreter used to run
the underlying script.
---
Naturally, this applies on top of my previous meson patch.
build-aux/meson-install-script.sh | 6 ++++++
build-aux/script-wrapper.sh.in | 6 ++++++
meson.build | 1 +
scripts/meson.build | 33 +++++++++++++++++++++++++++----
4 files changed, 42 insertions(+), 4 deletions(-)
create mode 100644 build-aux/meson-install-script.sh
create mode 100755 build-aux/script-wrapper.sh.in
diff --git a/build-aux/meson-install-script.sh b/build-aux/meson-install-script.sh
new file mode 100644
index 00000000..f5a42fca
--- /dev/null
+++ b/build-aux/meson-install-script.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+built_script=$1
+dest_path=$2
+
+install -Dm755 "$built_script" "$DESTDIR/$dest_path"
diff --git a/build-aux/script-wrapper.sh.in b/build-aux/script-wrapper.sh.in
new file mode 100755
index 00000000..f87ae6f0
--- /dev/null
+++ b/build-aux/script-wrapper.sh.in
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# This script serves as a trampoline for running scripts which depend on
+# libmakepkg with the libmakepkg within the build tree.
+
+LIBRARY=@BUILDDIR@/libmakepkg exec @BASH@ -$- @REAL_PROGPATH@ "$@"
diff --git a/meson.build b/meson.build
index d81c86b7..1ec63a56 100644
--- a/meson.build
+++ b/meson.build
@@ -33,6 +33,7 @@ SED = find_program('sed')
DU = find_program('du')
LDCONFIG = get_option('ldconfig')
MESON_MAKE_SYMLINK = join_paths(meson.source_root(), 'build-aux/meson-make-symlink.sh')
+MESON_INSTALL_SCRIPT = join_paths(meson.source_root(), 'build-aux/meson-install-script.sh')
BASH = find_program('bash4', 'bash')
if BASH.found()
diff --git a/scripts/meson.build b/scripts/meson.build
index 1fe3fb78..535eccba 100644
--- a/scripts/meson.build
+++ b/scripts/meson.build
@@ -24,14 +24,39 @@ m4_edit = generator(
capture : true)
foreach script : scripts
- custom_target(
+ script_shortname = script.split('.')[0]
+
+ # Build the script, but don't install it. We want to keep it as a "private"
+ # artifact that we reference from a wrapper script in order to bootstrap it
+ # the build directory.
+ internal_script = custom_target(
script,
input : m4_edit.process(script),
command : [ SCRIPT_EDITOR, '@INPUT@', '@OUTPUT@', '0755'],
- output : script.split('.')[0],
+ output : script,
depend_files : library_files,
- install : true,
- install_dir : get_option('bindir'))
+ build_by_default : true)
+
+ # Create a wrapper script that bootstraps the real script within the build
+ # directory.
+ custom_target(
+ 'wrap_@0@'.format(script_shortname),
+ input : join_paths(meson.source_root(), 'build-aux', 'script-wrapper.sh.in'),
+ output : script_shortname,
+ build_by_default : true,
+ command : [
+ SED,
+ '-e', 's,@BASH@,"@0@",'.format(BASH.path()),
+ '-e', 's,@BUILDDIR@,"@0@",'.format(meson.current_build_dir()),
+ '-e', 's,@REAL_PROGPATH@,"@0@",'.format(internal_script.full_path()),
+ '@INPUT@',
+ ],
+ capture : true)
+
+ # Install the real script
+ meson.add_install_script(MESON_INSTALL_SCRIPT,
+ internal_script.full_path(),
+ join_paths(BINDIR, script_shortname))
endforeach
foreach symlink : ['repo-remove', 'repo-elephant']
--
2.19.1
1
0
[pacman-dev] [PATCH] pacman-key: just accept one file to verify, and enforce detached sigs
by Eli Schwartz 21 Oct '18
by Eli Schwartz 21 Oct '18
21 Oct '18
Simply pass options on to gpg the same way gpg uses them -- no looping
through and checking lots of signatures.
This prevents a situation where the signature file to be verified is
manipulated to contain a complete signature which is valid, but not a
detached signature for the file you are actually trying to verify.
gpg does not offer an option to verify many files at once by naming each
signature/file pair, and there's no reason for us to do so either, since
it would be quite tiresome to do so.
Signed-off-by: Eli Schwartz <eschwartz(a)archlinux.org>
---
scripts/pacman-key.sh.in | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/scripts/pacman-key.sh.in b/scripts/pacman-key.sh.in
index 0f1630a9..0573e92f 100644
--- a/scripts/pacman-key.sh.in
+++ b/scripts/pacman-key.sh.in
@@ -486,18 +486,19 @@ refresh_keys() {
}
verify_sig() {
- local ret=0
- for sig; do
- msg "Checking %s..." "$sig"
- if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then
- error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig"
- return 1
- fi
- if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then
- error "$(gettext "The signature identified by %s could not be verified.")" "$sig"
- ret=1
- fi
- done
+ local ret=0 sig=$1 file=$2
+ if [[ -z $file ]]; then
+ file=${sig%.*}
+ fi
+ msg "Checking %s..." "$sig"
+ if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then
+ error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig"
+ exit 1
+ fi
+ if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "$sig" "$file" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then
+ error "$(gettext "The signature identified by %s could not be verified.")" "$sig"
+ ret=1
+ fi
exit $ret
}
--
2.17.0
2
3
21 Oct '18
[[ ${array[@]} ]] will resolve to false if array only contains empty
strings. This means that values such as "depends=('')" can be inserted
into a pkgbuild and bypass the linting.
This causes makepkg to successfully build the package while pacman
refuses to install it because of the unmet dependency on ''.
Instead check the length of the array.
Signed-off-by: morganamilo <morganamilo(a)gmail.com>
diff --git a/scripts/libmakepkg/util/pkgbuild.sh.in b/scripts/libmakepkg/util/pkgbuild.sh.in
index c6f8a82d..b29229a3 100644
--- a/scripts/libmakepkg/util/pkgbuild.sh.in
+++ b/scripts/libmakepkg/util/pkgbuild.sh.in
@@ -60,7 +60,7 @@ extract_global_variable() {
if (( isarray )); then
array_build ref "$attr"
- [[ ${ref[@]} ]] && array_build "$outputvar" "$attr"
+ (( ${#ref[@]} )) && array_build "$outputvar" "$attr"
else
[[ ${!attr} ]] && printf -v "$outputvar" %s "${!attr}"
fi
@@ -144,7 +144,7 @@ get_pkgbuild_all_split_attributes() {
done
done
- [[ ${all_list[@]} ]] && array_build "$outputvar" all_list
+ (( ${#all_list[@]} )) && array_build "$outputvar" all_list
}
##
--
2.19.1
3
4