From 6dae51f4d2b1f32aee025dabe26ee5f75aa64608 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sun, 3 Feb 2019 01:14:51 -0500 Subject: [PATCH 01/13] Experimental new redoconf C/C++ build/autoconfiguration system. To test it out, try this: ./do -j10 build cd docs/cookbook/c redo -j10 test It should detect all the compilers on your system and make three separate builds for each one: normal, debug, and optimized. Then it tries to run a test program under each one. If there are windows cross compilers and you also have 'wine' installed, it'll try running the test program under wine as well. redoconf currently has no documentation other than the example program. We'll fix that later. --- docs/cookbook/all.do | 2 +- docs/cookbook/c/.gitignore | 6 + docs/cookbook/c/all.do | 1 + docs/cookbook/c/all.h | 4 + docs/cookbook/c/all.hpp | 4 + docs/cookbook/c/all.od | 1 + docs/cookbook/c/all.rc.od | 23 +++ docs/cookbook/c/allconfig.do | 27 +++ docs/cookbook/c/arches.do | 14 ++ docs/cookbook/c/clean.od | 6 + docs/cookbook/c/configure | 3 + docs/cookbook/c/configure.help | 17 ++ docs/cookbook/c/default.each.do | 10 + docs/cookbook/c/flagtest.c | 10 + docs/cookbook/c/flagtest.o.od | 9 + docs/cookbook/c/hello world.list.od | 30 +++ docs/cookbook/c/libhello/hello.c | 6 + docs/cookbook/c/libhello/hello.h | 6 + docs/cookbook/c/libhello/lib hello.list | 1 + docs/cookbook/c/libhello/lib hello.ver | 1 + docs/cookbook/c/main.c | 22 ++ docs/cookbook/c/main.h | 19 ++ docs/cookbook/c/monotime.c | 58 ++++++ docs/cookbook/c/monotime.h | 6 + docs/cookbook/c/rc/extra.rc.od | 5 + docs/cookbook/c/rc/posix.rc.od | 16 ++ docs/cookbook/c/rc/printf_lld.rc.od | 16 ++ docs/cookbook/c/redoconf | 1 + docs/cookbook/c/slow.cc | 10 + docs/cookbook/c/test.do | 1 + docs/cookbook/c/test.od | 16 ++ docs/cookbook/c/when.c.do | 7 + redoconf/_all.rc.od | 51 +++++ redoconf/_compile.od | 14 ++ redoconf/compile.od | 51 +++++ redoconf/configure.sh | 200 ++++++++++++++++++ redoconf/default.do.sh | 181 ++++++++++++++++ redoconf/default.precompile.od | 31 +++ redoconf/link-shlib.od | 36 ++++ redoconf/link.od | 22 ++ redoconf/rc.sh | 240 ++++++++++++++++++++++ redoconf/rc/CC.rc.od | 68 ++++++ redoconf/rc/CXX.rc.od | 35 ++++ redoconf/rc/Wall.rc.od | 9 + redoconf/rc/Wextra.rc.od | 9 + redoconf/rc/_init.rc.od | 8 + redoconf/rc/default.autolib.rc.od | 18 ++ redoconf/rc/default.func.rc.od | 13 ++ redoconf/rc/default.h.precompiled.rc.od | 23 +++ redoconf/rc/default.h.rc.od | 13 ++ redoconf/rc/default.hpp.precompiled.rc.od | 23 +++ redoconf/rc/libgl.rc.od | 12 ++ redoconf/rc/libgtk2.rc.od | 12 ++ redoconf/rc/libm.rc.od | 25 +++ redoconf/rc/libpng.rc.od | 12 ++ redoconf/rc/libqt4.rc.od | 10 + redoconf/rc/libsdl.rc.od | 12 ++ redoconf/rc/libx11.rc.od | 12 ++ redoconf/rc/pkg-config.rc.od | 17 ++ redoconf/rc/run.rc.od | 27 +++ redoconf/rc/shlib.rc.od | 21 ++ redoconf/rc/zdefs.rc.od | 11 + redoconf/rc_vars.od | 25 +++ redoconf/redoconf.h.od | 34 +++ redoconf/run.od | 16 ++ redoconf/trycompile | 71 +++++++ redoconf/utils.sh | 58 ++++++ 67 files changed, 1777 insertions(+), 1 deletion(-) create mode 100644 docs/cookbook/c/.gitignore create mode 100644 docs/cookbook/c/all.do create mode 100644 docs/cookbook/c/all.h create mode 100644 docs/cookbook/c/all.hpp create mode 100644 docs/cookbook/c/all.od create mode 100644 docs/cookbook/c/all.rc.od create mode 100644 docs/cookbook/c/allconfig.do create mode 100644 docs/cookbook/c/arches.do create mode 100644 docs/cookbook/c/clean.od create mode 100755 docs/cookbook/c/configure create mode 100644 docs/cookbook/c/configure.help create mode 100644 docs/cookbook/c/default.each.do create mode 100644 docs/cookbook/c/flagtest.c create mode 100644 docs/cookbook/c/flagtest.o.od create mode 100644 docs/cookbook/c/hello world.list.od create mode 100644 docs/cookbook/c/libhello/hello.c create mode 100644 docs/cookbook/c/libhello/hello.h create mode 100644 docs/cookbook/c/libhello/lib hello.list create mode 100644 docs/cookbook/c/libhello/lib hello.ver create mode 100644 docs/cookbook/c/main.c create mode 100644 docs/cookbook/c/main.h create mode 100644 docs/cookbook/c/monotime.c create mode 100644 docs/cookbook/c/monotime.h create mode 100644 docs/cookbook/c/rc/extra.rc.od create mode 100644 docs/cookbook/c/rc/posix.rc.od create mode 100644 docs/cookbook/c/rc/printf_lld.rc.od create mode 120000 docs/cookbook/c/redoconf create mode 100644 docs/cookbook/c/slow.cc create mode 100644 docs/cookbook/c/test.do create mode 100644 docs/cookbook/c/test.od create mode 100644 docs/cookbook/c/when.c.do create mode 100644 redoconf/_all.rc.od create mode 100644 redoconf/_compile.od create mode 100644 redoconf/compile.od create mode 100644 redoconf/configure.sh create mode 100644 redoconf/default.do.sh create mode 100644 redoconf/default.precompile.od create mode 100644 redoconf/link-shlib.od create mode 100644 redoconf/link.od create mode 100644 redoconf/rc.sh create mode 100644 redoconf/rc/CC.rc.od create mode 100644 redoconf/rc/CXX.rc.od create mode 100644 redoconf/rc/Wall.rc.od create mode 100644 redoconf/rc/Wextra.rc.od create mode 100644 redoconf/rc/_init.rc.od create mode 100644 redoconf/rc/default.autolib.rc.od create mode 100644 redoconf/rc/default.func.rc.od create mode 100644 redoconf/rc/default.h.precompiled.rc.od create mode 100644 redoconf/rc/default.h.rc.od create mode 100644 redoconf/rc/default.hpp.precompiled.rc.od create mode 100644 redoconf/rc/libgl.rc.od create mode 100644 redoconf/rc/libgtk2.rc.od create mode 100644 redoconf/rc/libm.rc.od create mode 100644 redoconf/rc/libpng.rc.od create mode 100644 redoconf/rc/libqt4.rc.od create mode 100644 redoconf/rc/libsdl.rc.od create mode 100644 redoconf/rc/libx11.rc.od create mode 100644 redoconf/rc/pkg-config.rc.od create mode 100644 redoconf/rc/run.rc.od create mode 100644 redoconf/rc/shlib.rc.od create mode 100644 redoconf/rc/zdefs.rc.od create mode 100644 redoconf/rc_vars.od create mode 100644 redoconf/redoconf.h.od create mode 100644 redoconf/run.od create mode 100644 redoconf/trycompile create mode 100644 redoconf/utils.sh diff --git a/docs/cookbook/all.do b/docs/cookbook/all.do index 7d12d02..6bd494d 100644 --- a/docs/cookbook/all.do +++ b/docs/cookbook/all.do @@ -1,4 +1,4 @@ export NO_SLOW_TESTS=1 -for d in */all.do; do +for d in */all.do */test.do; do echo "${d%.do}" done | xargs redo-ifchange diff --git a/docs/cookbook/c/.gitignore b/docs/cookbook/c/.gitignore new file mode 100644 index 0000000..0703d8b --- /dev/null +++ b/docs/cookbook/c/.gitignore @@ -0,0 +1,6 @@ +hello +/when.c +/allconfig +/arches +/out +/out.* diff --git a/docs/cookbook/c/all.do b/docs/cookbook/c/all.do new file mode 100644 index 0000000..c359ac3 --- /dev/null +++ b/docs/cookbook/c/all.do @@ -0,0 +1 @@ +redo-ifchange all.each diff --git a/docs/cookbook/c/all.h b/docs/cookbook/c/all.h new file mode 100644 index 0000000..d5fdaa0 --- /dev/null +++ b/docs/cookbook/c/all.h @@ -0,0 +1,4 @@ +#include "main.h" +#include "libhello/hello.h" +#include "monotime.h" +#include diff --git a/docs/cookbook/c/all.hpp b/docs/cookbook/c/all.hpp new file mode 100644 index 0000000..8979800 --- /dev/null +++ b/docs/cookbook/c/all.hpp @@ -0,0 +1,4 @@ +#include +#include +#include +#include diff --git a/docs/cookbook/c/all.od b/docs/cookbook/c/all.od new file mode 100644 index 0000000..94f4a47 --- /dev/null +++ b/docs/cookbook/c/all.od @@ -0,0 +1 @@ +redo-ifchange "hello world" diff --git a/docs/cookbook/c/all.rc.od b/docs/cookbook/c/all.rc.od new file mode 100644 index 0000000..179fc92 --- /dev/null +++ b/docs/cookbook/c/all.rc.od @@ -0,0 +1,23 @@ +. ./redoconf.rc +rc_include \ + rc/CC.rc \ + rc/CXX.rc \ + rc/libqt4.rc \ + rc/libgtk2.rc \ + rc/Wextra.rc \ + rc/Wall.rc \ + rc/libm.rc \ + rc/rt.autolib.rc \ + rc/libpng.rc \ + rc/clock_gettime.func.rc \ + rc/mach_time.h.rc \ + rc/windows.h.rc \ + rc/posix.rc \ + rc/printf_lld.rc \ + rc/extra.rc \ + rc/all.h.precompiled.rc \ + rc/all.hpp.precompiled.rc + +rc_appendln LIBS "$LIBRT" +rc_appendln LIBS "$LIBM" +rc_save diff --git a/docs/cookbook/c/allconfig.do b/docs/cookbook/c/allconfig.do new file mode 100644 index 0000000..c659d30 --- /dev/null +++ b/docs/cookbook/c/allconfig.do @@ -0,0 +1,27 @@ +redo-ifchange arches configure redoconf/utils.sh + +config() { + local dir="$1" arch="$2" + shift + shift + [ -d "$dir" ] || mkdir "$dir" + ( + cd "$dir" && + ../configure --host="$arch" "$@" && + redo-ifchange rc/CC.rc && + echo "$dir" + ) || : +} + +for d in $(cat arches); do + if [ "$d" = "native" ]; then + arch="" + else + arch="$d" + fi + config "out.$d" "$arch" & + config "out.$d.static" "$arch" "--enable-static" & + config "out.$d.opt" "$arch" "--enable-optimization" & +done + +wait diff --git a/docs/cookbook/c/arches.do b/docs/cookbook/c/arches.do new file mode 100644 index 0000000..a779ebb --- /dev/null +++ b/docs/cookbook/c/arches.do @@ -0,0 +1,14 @@ +IFS=: +echo native >$3 +if [ -z "$NO_SLOW_TESTS" ]; then + for dir in $PATH; do + for d in "$dir"/*-cc "$dir"/*-gcc; do + base=${d##*/} + arch=${base%-*} + if [ -x "$d" ]; then echo "$arch"; fi + done + done >>$3 +fi + +redo-always +redo-stamp <$3 diff --git a/docs/cookbook/c/clean.od b/docs/cookbook/c/clean.od new file mode 100644 index 0000000..70a02f2 --- /dev/null +++ b/docs/cookbook/c/clean.od @@ -0,0 +1,6 @@ +# runs from the output directory +rm -f *~ .*~ *.rc *.log *.gch *.stamp \ + *.[oa] *.deps \ + *.so *.so.* *.ver \ + *.exe *.list \ + hello diff --git a/docs/cookbook/c/configure b/docs/cookbook/c/configure new file mode 100755 index 0000000..736916f --- /dev/null +++ b/docs/cookbook/c/configure @@ -0,0 +1,3 @@ +#!/bin/sh +S="$(dirname "$0")" +. "$S/redoconf/configure.sh" diff --git a/docs/cookbook/c/configure.help b/docs/cookbook/c/configure.help new file mode 100644 index 0000000..ca36761 --- /dev/null +++ b/docs/cookbook/c/configure.help @@ -0,0 +1,17 @@ +# Automatically generated by redoconf/_all.rc.od - do not edit +ARCH Architecture prefix for output (eg. i686-w64-mingw32-) +CC C compiler name (cc) +CPPFLAGS Extra C preprocessor flags (eg. -I... -D...) +CFLAGS Extra C compiler flags (eg. -O2 -g) +OPTFLAGS C/C++ compiler flag overrides (eg. -g0) +LINK Linker name (cc) +LDFLAGS Extra linker options (eg. -s -static) +LIBS Extra libraries to always link against (eg. -lsocket) +STATIC Link libraries and binaries statically +CXX C++ compiler name (c++) +CXXFLAGS Extra C++ compiler flags (eg. -O2 -g) +LIBQT4 Extra linker options for 'QtCore' +LIBGTK2 Extra linker options for 'gtk+-2.0 gio-2.0 gdk-2.0 gdk-pixbuf-2.0' +LIBM Extra linker options for 'libm' +LIBPNG Extra linker options for 'libpng' +PREFIX Change installation prefix (usually /usr/local) diff --git a/docs/cookbook/c/default.each.do b/docs/cookbook/c/default.each.do new file mode 100644 index 0000000..0738694 --- /dev/null +++ b/docs/cookbook/c/default.each.do @@ -0,0 +1,10 @@ +# redo $2 in each of the registered output dirs. +# This way you can run commands or depend on targets like: +# redo clean.each.do +# redo all.each.do +# etc. +redo-ifchange allconfig + +for dir in $(cat allconfig); do + echo "$dir/$2" +done | xargs redo-ifchange diff --git a/docs/cookbook/c/flagtest.c b/docs/cookbook/c/flagtest.c new file mode 100644 index 0000000..34f9453 --- /dev/null +++ b/docs/cookbook/c/flagtest.c @@ -0,0 +1,10 @@ +#include "main.h" +#include + +#ifdef EXTRA_RC_INCLUDED +#error "rc/extra.rc should not be included when compiling flagtest.c" +#endif + +void flag_test(void) { + printf("flagtest included\n"); +} diff --git a/docs/cookbook/c/flagtest.o.od b/docs/cookbook/c/flagtest.o.od new file mode 100644 index 0000000..67b5c88 --- /dev/null +++ b/docs/cookbook/c/flagtest.o.od @@ -0,0 +1,9 @@ +# Demonstrate how to compile .o files using nonstandard +# compiler flags. You could also do this for a whole +# directory using default.o.od. +. ./redoconf.rc +rc_include all.rc + +src="$S/${1%.o}.c" +redo-ifchange "_compile" "$src" +CC="$CC" CPPFLAGS="-DFLAGTEST_SET=42" ./_compile "$3" "$1.deps" "$src" diff --git a/docs/cookbook/c/hello world.list.od b/docs/cookbook/c/hello world.list.od new file mode 100644 index 0000000..d9f5200 --- /dev/null +++ b/docs/cookbook/c/hello world.list.od @@ -0,0 +1,30 @@ +# This script is run from the output dir, +# which contains a src/ symlink to the source dir. + +. ./redoconf.rc +rc_include all.rc + +( + cd "$S" + echo "main.c" + echo "monotime.c" + echo "when.c" # auto-generated source + echo "flagtest.c" # source with different compiler flags + + if [ -n "$CXX" ]; then + echo "slow.cc" + fi + + # This is unnecessarily fancy. + # We're just using it as an example of + # how to dynamically generate a .list + # file. + for d in lib*/*.list lib*/*.list.od; do + [ -e "$d" ] && echo "${d%%.*}.so" + done | uniq + + printf '%s\n' "$LIBGTK2" "$LIBQT4" +) >$3 + +redo-always +redo-stamp <$3 diff --git a/docs/cookbook/c/libhello/hello.c b/docs/cookbook/c/libhello/hello.c new file mode 100644 index 0000000..5a88be9 --- /dev/null +++ b/docs/cookbook/c/libhello/hello.c @@ -0,0 +1,6 @@ +#include "hello.h" +#include + +void hello(void) { + printf("Hello, world!\n"); +} \ No newline at end of file diff --git a/docs/cookbook/c/libhello/hello.h b/docs/cookbook/c/libhello/hello.h new file mode 100644 index 0000000..94dbff4 --- /dev/null +++ b/docs/cookbook/c/libhello/hello.h @@ -0,0 +1,6 @@ +#ifndef __HELLO_H +#define __HELLO_H + +void hello(void); + +#endif /* __HELLO_H */ \ No newline at end of file diff --git a/docs/cookbook/c/libhello/lib hello.list b/docs/cookbook/c/libhello/lib hello.list new file mode 100644 index 0000000..9c36258 --- /dev/null +++ b/docs/cookbook/c/libhello/lib hello.list @@ -0,0 +1 @@ +hello.c diff --git a/docs/cookbook/c/libhello/lib hello.ver b/docs/cookbook/c/libhello/lib hello.ver new file mode 100644 index 0000000..c813fe1 --- /dev/null +++ b/docs/cookbook/c/libhello/lib hello.ver @@ -0,0 +1 @@ +1.2.5 diff --git a/docs/cookbook/c/main.c b/docs/cookbook/c/main.c new file mode 100644 index 0000000..6fc2d28 --- /dev/null +++ b/docs/cookbook/c/main.c @@ -0,0 +1,22 @@ +#include "main.h" +#include "libhello/hello.h" +#include "monotime.h" +#include "redoconf.h" +#include + +#if EXTRA_RC_INCLUDED != 1 +#error "EXTRA_RC was not included!" +#endif + +int main() { + hello(); + printf("Timestamp: %s\n", stamp_time()); + printf("Monotime: %lld\n", monotime()); +#ifdef CXX + printf("Length of 'hello world': %d\n", cpp_test()); +#else + printf("No C++ compiler found.\n"); +#endif + flag_test(); + return 0; +} diff --git a/docs/cookbook/c/main.h b/docs/cookbook/c/main.h new file mode 100644 index 0000000..d2d07e4 --- /dev/null +++ b/docs/cookbook/c/main.h @@ -0,0 +1,19 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +#define CDEF extern "C" +#else +#define CDEF +#endif + +/* when.c */ +CDEF const char *stamp_time(void); + +/* slow.cc */ +CDEF int cpp_test(void); + +/* flagtest.c */ +CDEF void flag_test(void); + +#endif /* __MAIN_H */ \ No newline at end of file diff --git a/docs/cookbook/c/monotime.c b/docs/cookbook/c/monotime.c new file mode 100644 index 0000000..784f577 --- /dev/null +++ b/docs/cookbook/c/monotime.c @@ -0,0 +1,58 @@ +#define __GNU_SOURCE +/* + * Returns the kernel monotonic timestamp in microseconds. + * This function never returns the value 0; it returns 1 instead, so that + * 0 can be used as a magic value. + */ +#include "monotime.h" +#include "redoconf.h" + +#if HAVE_CLOCK_GETTIME + +#include +#include +#include + +long long monotime(void) { + struct timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { + perror("clock_gettime"); + exit(98); /* really should never happen, so don't try to recover */ + } + long long result = ts.tv_sec * 1000000LL + ts.tv_nsec / 1000; + return !result ? 1 : result; +} + +#elif HAVE_MACH_TIME_H + +#include +#include + +long long monotime(void) { + static mach_timebase_info_data_t timebase; + if (!timebase.denom) mach_timebase_info(&timebase); + long long result = (mach_absolute_time() * timebase.numer / + timebase.denom / 1000); + return !result ? 1 : result; +} + +#elif HAVE_WINDOWS_H + +#include + +/* WARNING: Not carefully tested. It might wrap around unexpectedly. + * Based on suggestions from: + * https://stackoverflow.com/questions/211257/windows-monotonic-clock + */ +long long monotime(void) { + LARGE_INTEGER tps, t; + QueryPerformanceFrequency(&tps); + QueryPerformanceCounter(&t); + return t.QuadPart * 1000000LL / tps.QuadPart; +} + +#else + +#error "No monotonic time function is available" + +#endif diff --git a/docs/cookbook/c/monotime.h b/docs/cookbook/c/monotime.h new file mode 100644 index 0000000..fca38e7 --- /dev/null +++ b/docs/cookbook/c/monotime.h @@ -0,0 +1,6 @@ +#ifndef __MONOTIME_H +#define __MONOTIME_H + +long long monotime(void); + +#endif /* __MONOTIME_H */ diff --git a/docs/cookbook/c/rc/extra.rc.od b/docs/cookbook/c/rc/extra.rc.od new file mode 100644 index 0000000..1075a71 --- /dev/null +++ b/docs/cookbook/c/rc/extra.rc.od @@ -0,0 +1,5 @@ +. ./redoconf.rc +rc_include + +rc_appendln CPPFLAGS "-DEXTRA_RC_INCLUDED=1" +rc_save diff --git a/docs/cookbook/c/rc/posix.rc.od b/docs/cookbook/c/rc/posix.rc.od new file mode 100644 index 0000000..546fc8a --- /dev/null +++ b/docs/cookbook/c/rc/posix.rc.od @@ -0,0 +1,16 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +prog=' +#include + +struct timespec x; +' + +x= +if ! rc_compile cc link "$prog"; then + x="-D_XOPEN_SOURCE=500" + rc_appendln CPPFLAGS "$x" + rc_compile cc link "$prog" +fi +rc_save diff --git a/docs/cookbook/c/rc/printf_lld.rc.od b/docs/cookbook/c/rc/printf_lld.rc.od new file mode 100644 index 0000000..dd1650e --- /dev/null +++ b/docs/cookbook/c/rc/printf_lld.rc.od @@ -0,0 +1,16 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/windows.h.rc rc/Wall.rc + +appendln CPPFLAGS "-Werror" # abort if any warnings +prog=' +#include +void test() { printf("%lld", (long long)1); } +' + +x= +if ! rc_compile cc link "$prog"; then + x="-D__USE_MINGW_ANSI_STDIO=1" + rc_appendln CPPFLAGS "$x" + rc_compile cc link "$prog" +fi +rc_save diff --git a/docs/cookbook/c/redoconf b/docs/cookbook/c/redoconf new file mode 120000 index 0000000..f0a8b6b --- /dev/null +++ b/docs/cookbook/c/redoconf @@ -0,0 +1 @@ +../../../redoconf \ No newline at end of file diff --git a/docs/cookbook/c/slow.cc b/docs/cookbook/c/slow.cc new file mode 100644 index 0000000..d854f9d --- /dev/null +++ b/docs/cookbook/c/slow.cc @@ -0,0 +1,10 @@ +#include +#include +#include +#include +#include "main.h" + +int cpp_test() { + std::string a = "hello ", b = "world"; + return a.length() + b.length(); +} diff --git a/docs/cookbook/c/test.do b/docs/cookbook/c/test.do new file mode 100644 index 0000000..54ef47b --- /dev/null +++ b/docs/cookbook/c/test.do @@ -0,0 +1 @@ +redo-ifchange test.each diff --git a/docs/cookbook/c/test.od b/docs/cookbook/c/test.od new file mode 100644 index 0000000..f128358 --- /dev/null +++ b/docs/cookbook/c/test.od @@ -0,0 +1,16 @@ +exec >&2 +redo-always +redo-ifchange all run +if [ -x ./run ]; then + echo "Running: ./run ./hello\\ world" + ./run './hello world' >"$1.out" 2>&1 + cat "$1.out" + if grep -F -q 'Hello, world!' "$1.out"; then + echo "-- Test successful." + else + echo "-- Test failed." + exit 1 + fi +else + echo "Non-native platform: test skipped." +fi diff --git a/docs/cookbook/c/when.c.do b/docs/cookbook/c/when.c.do new file mode 100644 index 0000000..dafe985 --- /dev/null +++ b/docs/cookbook/c/when.c.do @@ -0,0 +1,7 @@ +cat >$3 <<-EOF + const char *stamp_time(void) { + return "$(date +%Y-%m-%d)"; + } +EOF +redo-always +redo-stamp <$3 diff --git a/redoconf/_all.rc.od b/redoconf/_all.rc.od new file mode 100644 index 0000000..71a73f5 --- /dev/null +++ b/redoconf/_all.rc.od @@ -0,0 +1,51 @@ +. ./redoconf.rc + +# replace the placeholder for this function with +# one that will save help messages for later. +HELP="configure.help.new" +rm -f "$HELP" +echo '# Automatically generated by redoconf/_all.rc.od - do not edit' >"$HELP" +helpmsg() { + printf '%-11s %s\n' "$1" "$2" >>"$HELP" + rc_hook "$1" +} + +# Remember initial set of keys provided by ./configure +orig_keys="" +rc_hook() { + contains_line "$orig_keys" "$1" || orig_keys="$orig_keys$NL$1" +} + +# Include the rest of the necessary .rc files +keys="" +rc_hook() { + contains_line "$new_keys" "$1" || new_keys="$new_keys$NL$1" +} +allrc= +if [ -e "$S/all.rc.od" ]; then + allrc=all.rc +else + allrc= + redo-ifcreate "$S/all.rc.od" +fi +rc_include rc/_init.rc rc/CC.rc rc/zdefs.rc $allrc + +rc_helpmsg PREFIX "Change installation prefix (usually /usr/local)" + +IFS="$NL" +unused= +for d in $orig_keys; do + if ! contains_line "$new_keys" "$d"; then + unused=1 + xecho "Error: '$d' was given to ./configure but not used." >&2 + fi +done +[ -z "$unused" ] || exit 1 + +rc_save + +# Now that all the rc files have run, update $S/configure.help with the +# newly-generated help text, so it's available to new users. +# Even if multiple output dirs are building at once, this replaces the +# file atomically, so it should be safe. +mv "$HELP" "$S/configure.help" diff --git a/redoconf/_compile.od b/redoconf/_compile.od new file mode 100644 index 0000000..4a237b9 --- /dev/null +++ b/redoconf/_compile.od @@ -0,0 +1,14 @@ +# See compile.od for more explanation. +cat >$3 <<-EOF + #!/bin/sh -e + # Run the C/C++ compiler. + # Assumes config variables (CFLAGS, etc) are already set. + t="\$1" d="\$2" i="\$3" + IFS="$NL" + set -f + \$CC -o "\$t" -c "\$i" \\ + -MMD -MF "\$d" \\ + \$CPPFLAGS \$CFLAGS \$CXXFLAGS \$FLAGS_PCH \$xCFLAGS \$OPTFLAGS +EOF +chmod a+x "$3" +redo-stamp <$3 diff --git a/redoconf/compile.od b/redoconf/compile.od new file mode 100644 index 0000000..f379ad8 --- /dev/null +++ b/redoconf/compile.od @@ -0,0 +1,51 @@ +. ./redoconf.rc +rc_include _all.rc +redo-ifchange _compile + +# Subtle: +# - un-backslashed $ expansions ($foo, $(cmd)) are +# done *now*, while writing the script contents. +# - backslashed $ expansions (\$foo) are written +# verbatim into the script, to be interpreted at +# the time the script is run. +# +# We want to insert the variable contents into the +# script near the top, making sure they are not +# split or interpreted at that point (hence the +# $(shquote)). +# +# Further down, we want to disable wildcard expansion +# (set -f) and split on $NL (so we change $IFS), +# so we use backslash escapes but *not* quoting. + +cat >$3 <<-EOF + #!/bin/sh -e + # Run the C/++ compiler. + t="\$1" d="\$2" i="\$3" + CPPFLAGS=$(shquote "$CPPFLAGS") + OPTFLAGS=$(shquote "$OPTFLAGS") + case \$i in + *.c|*.h) + CC=$(shquote "$CC") + CFLAGS=$(shquote "$CFLAGS") + CXXFLAGS= + PCH1=$(shquote "$CFLAGS_PCH") + PCH2=$(shquote "$CFLAGS_PCH_FPIC") + ;; + *) + CC=$(shquote "$CXX") + [ -n "\$CC" ] || (echo "No C++ compiler available." >&2; exit 1) + CFLAGS= + CXXFLAGS=$(shquote "$CXXFLAGS") + PCH1=$(shquote "$CXXFLAGS_PCH") + PCH2=$(shquote "$CXXFLAGS_PCH_FPIC") + ;; + esac + case \$PCH in + 1) FLAGS_PCH=\$PCH1 ;; + 2) FLAGS_PCH=\$PCH2 ;; + esac + . ./_compile +EOF +chmod a+x "$3" +redo-stamp <$3 diff --git a/redoconf/configure.sh b/redoconf/configure.sh new file mode 100644 index 0000000..83d77a1 --- /dev/null +++ b/redoconf/configure.sh @@ -0,0 +1,200 @@ +#!/bin/sh -e +if [ -z "$S" ]; then + exec >&2 + echo "configure.sh: must include this from a 'configure' script" + exit 99 +fi +if [ -e "configure" ] || [ -e "rc.sh" ]; then + exec >&2 + echo "$0: run this script from an empty output directory." + echo " For example:" + echo " (mkdir out && cd out && ../configure && redo -j10)" + exit 99 +fi + +S="$(dirname "$0")" +rm -f src Makefile +echo "$S" >src + +# Don't regenerate these files unless they're missing. Otherwise redo +# will treat it as a changed dependency and rebuild a bunch of files +# unnecessarily. +[ -e redoconf.rc ] || cat >redoconf.rc <<-EOF + # Automatically generated by $0 + read -r S Makefile <<'EOF' +# A wrapper for people who like to type 'make' instead of 'redo' +all $(filter-out all,$(MAKECMDGOALS)): + +redo "$@" +.PHONY: $(MAKECMDGOALS) all +EOF + +# Don't include rc.sh here, because that might call redo-ifchange, +# and we're not ready for that yet. +. "$S/redoconf/utils.sh" + +usage() { + exec >&2 + printf 'Usage: %s %s' "$0" \ +'[options...] [KEY=value] [--with-key=value] + + --prefix= Change installation prefix (usually /usr/local) + --host= Architecture prefix for output (eg. i686-w64-mingw32-) + --enable-static Link libraries and binaries statically + --{dis,en}able-optimization Disable/enable optimization for C/C++ + --{dis,en}able-debug Disable/enable debugging flags for C/C++ + -h, --help This help message +' + if [ -e "$S/configure.help" ]; then + printf '\nProject-specific flags:\n' + sort "$S/configure.help" | + while read k msg; do + # skip blanks and comments + [ -n "${k%%\#*}" ] || continue + # skip options with syntax already explained above + [ "$k" != "ARCH" ] || continue + [ "$k" != "PREFIX" ] || continue + [ "$k" != "STATIC" ] || continue + printf ' %-15s %s\n' "$k=..." "$msg" + done + else + printf '\nNo extra help yet: configure.help is missing.\n' + fi + exit 1 +} + +upper() { + xecho "$1" | tr 'a-z' 'A-Z' | sed 's/[^A-Z0-9]/_/g' +} + +lower() { + xecho "$1" | tr 'A-Z' 'a-z' | sed 's/[^a-z0-9]/-/g' +} + +emit() { + xecho "replaceln" "$1" "$(shquote "$(rc_splitwords "$2")")" +} + +emit_append() { + xecho "appendln" "$1" "$(shquote "$(rc_splitwords "$2")")" +} + +for k in ARCH CC CXX CPPFLAGS CFLAGS CXXFLAGS \ + OPTFLAGS LINK LDFLAGS LIBS xCFLAGS; do + eval v=\$$k + if [ -n "$v" ]; then + echo "$0: Fatal: '$k' environment variable is set." >&2 + echo " This can cause inconsistent builds." >&2 + echo " Pass variables as arguments to $0 instead." >&2 + echo " Example: $0 $k=$(shquote "$v")" >&2 + exit 4 + fi +done + +rm -f _flags.tmp +echo "# Auto-generated by $0" >_flags.tmp +for d in "$@"; do + case $d in + --help|-h|-\?) + usage + ;; + --host=*) + v="${d#*=}" + emit "ARCH" "$v" + ;; + --enable-static) + emit "STATIC" "1" + ;; + --enable-optimization) + emit_append OPTFLAGS "-O2" + ;; + --disable-optimization) + emit_append OPTFLAGS "-O0" + ;; + --enable-debug) + emit_append OPTFLAGS "-g" + ;; + --disable-debug) + emit_append OPTFLAGS "-g0" + ;; + --prefix=*) + v="${d#*=}" + emit "PREFIX" "$v" + ;; + --with-[A-Za-z]*) + if [ "$d" = "${d%%=*}" ]; then + xecho "$0: in $(shquote "$d"):" \ + "must supply '--with-='" >&2 + exit 3 + fi + k="${d%%=*}" + k="${k#--with-}" + v="${d#*=}" + kl=$(lower "$k") + if [ "$k" != "$kl" ]; then + xecho "$0: in $(shquote "--with-$k=..."):" \ + "must be all lowercase and dashes" >&2 + exit 3 + fi + ku=$(upper "$k") + emit "$ku" "$v" + ;; + --without-[A-Za-z]*) + if [ "$d" != "${d%%=*}" ]; then + xecho "$0: in $(shquote "$d"):" \ + "do not supply '=...' with --without" >&2 + exit 3 + fi + k="${d#--without-}" + kl=$(lower "$k") + if [ "$k" != "$kl" ]; then + xecho "$0: in $(shquote "$d"):" \ + "must be all lowercase and dashes" >&2 + exit 3 + fi + ku=$(upper "$k") + # This causes tests to try to link using an extra + # option "NONE", which will fail, thus making the + # package appear missing. + emit "$ku" "NONE" + ;; + [A-Za-z_]*=*) + k="${d%%=*}" + v="${d#*=}" + ku=$(upper "$k") + if [ "$k" != "$ku" ]; then + xecho "$0: in $(shquote "$d"):" \ + "invalid KEY=value;" \ + "must be all caps and underscores" >&2 + exit 3 + fi + emit "$ku" "$v" + ;; + *) + xecho "$0: in $(shquote "$d"):" \ + "invalid option; use --help for help." >&2 + exit 2 + ;; + esac +done >>_flags.tmp + +# Avoid replacing the file if it's identical, so we don't trigger +# unnecessary rebuilds. redo-stamp can do this for a redo target, +# but _flags is being generated by this configure script, which is +# not a redo target. +if [ -e _flags ] && cmp _flags.tmp _flags >/dev/null; then + rm -f _flags.tmp +else + rm -f _flags + mv _flags.tmp _flags +fi diff --git a/redoconf/default.do.sh b/redoconf/default.do.sh new file mode 100644 index 0000000..6c4de48 --- /dev/null +++ b/redoconf/default.do.sh @@ -0,0 +1,181 @@ +# This script starts with $PWD=output dir, $S=input dir. +read -r S &2 + exit 99 +fi + +NL=" +" + +_mkdir_of() { + local dir="${1%/*}" + [ "$dir" = "$1" ] || + [ -z "$dir" ] || + [ -d "$dir" ] || + mkdir -p "$dir" +} + +# Delegate to .od files specifically for this target, if any. +_base1=${1##*/} +_dir1=${1%"$_base1"} +_missing="" +for d in "$S/$1.od" \ + "$S/${_dir1}default.${_base1#*.}.od" \ + "$REDOCONF/$1.od" \ + "$REDOCONF/${_dir1}default.${_base1#*.}.od"; do + if [ -e "$d" ]; then + redo-ifchange "$d" + _mkdir_of "$3" + ( PS4="$PS4[$d] "; . "$d" ) + exit + else + missing="$missing$NL$d" + fi +done + +_add_missing() { + [ -n "$missing" ] && (IFS="$NL"; set -f; redo-ifcreate $missing) + missing= +} + +_pick_src() { + # Look for the source file corresponding to a given .o file. + # If the source file is missing, we can also build it from + # eg. a .c.do script. + # + # Returns the matching source file in $src, the compiler + # mode in $lang, and appends any redo-ifcreate targets to + # $missing. + lang=cc + for src in "$1.c"; do + [ -e "$src" ] && return + [ -e "$src.do" ] && return + missing="$missing$NL$src" + done + lang=cxx + for src in "$1.cc" "$1.cpp" "$1.cxx" "$1.C" "$1.c++"; do + [ -e "$src" ] && return + [ -e "$src.do" ] && return + missing="$missing$NL$src" + done + echo "default.do.sh: _pick_src: no source file found for '$1.*'" >&2 + return 1 +} + +_objlist() { + local suffix="$1" list="$2" base="${2##*/}" + local dir="${2%"$base"}" + sed -Ee 's/\.(c|cc|cpp|cxx|C|c\+\+)$/'"$suffix/" <"$2" | + while read -r d; do + [ "$d" = "${d#-}" ] || continue + echo "$dir$d" + done +} + +_flaglist() { + while read -r d; do + [ "$d" != "${d#-}" ] || continue + echo "$d" + done <"$1" +} + +compile() { + redo-ifchange compile "$src" $dep + rm -f "$1.deps" + _mkdir_of "$3" + xCFLAGS="$xCFLAGS" PCH="$PCH" ./compile "$3" "$1.deps" "$src" + # TODO: make work with dependency filenames containing whitespace. + # gcc writes whitespace-containing filenames with spaces + # prefixed by backslash. read (without -r) will remove the + # backslashes but still use spaces for word splitting, so + # it loses the distinction. rc_splitwords() is the right + # function, but currently has a max word limit. + read deps <"$2.deps" + redo-ifchange ${deps#*:} +} + +case $1 in + *.fpic.o) + _pick_src "$S/${1%.fpic.o}" + _add_missing + xCFLAGS="-fPIC" PCH="2" dep="$lang-fpic.precompile" compile "$@" + exit # fast path: exit as early as possible + ;; + *.o) + _pick_src "$S/${1%.o}" + _add_missing + xCFLAGS="" PCH="1" dep="$lang.precompile" compile "$@" + exit # fast path: exit as early as possible + ;; + *.h.fpic.gch|*.hpp.fpic.gch) + src="$S/${1%.fpic.gch}" + xCFLAGS="-fPIC" PCH="" dep="" compile "$@" + # precompiled header is "unchanged" if its component + # headers are unchanged. + cat ${deps#*:} | tee $1.stamp | redo-stamp + ;; + *.h.gch|*.hpp.gch) + src="$S/${1%.gch}" + xCFLAGS="" PCH="" dep="" compile "$@" + # precompiled header is "unchanged" if its component + # headers are unchanged. + cat ${deps#*:} | tee $1.stamp | redo-stamp + ;; + *.a) + listf="${1%.a}.list" + redo-ifchange "$listf" + files=$(_objlist .o "$listf") + IFS="$NL" + redo-ifchange $files + ar q "$3" $files + ;; + *.so) + verf="${1%.so}.ver" + listf="${1%.so}.list" + redo-ifchange link-shlib "$verf" "$listf" + read ver <"$verf" + files=$(_objlist .fpic.o "$listf") + xLIBS=$(_flaglist "$listf") + IFS="$NL" + redo-ifchange $files + xLIBS="$xLIBS" ./link-shlib "$1.$ver" $files + ln -s "$(basename "$1.$ver")" "$3" + ln -sf "$1.$ver" . + ;; + *.list|*.ver) + if [ -e "$S/$1" ]; then + redo-ifchange "$S/$1" + _mkdir_of "$3" + cp "$S/$1" "$3" + else + echo "default.do.sh: no rule to build '$1'" >&2 + exit 99 + fi + ;; + *) + # In unix, binary names typically don't have any special filename + # pattern, so we have to handle them in a catch-all here. + # We detect that it's intended as a binary, and not just a typo, + # by the existence of a .list or .list.od file with the same name, + # defining the list of input files. + # + # Some people like to name their binaries *.exe, eg. on Windows, + # even though that doesn't matter anymore, even on Windows. + # So use the same rules for generating a .exe as a non-.exe. + bin="${1%.exe}" + if [ -e "$S/$bin.list" -o -e "$S/$bin.list.od" ]; then + # a final program binary + redo-ifchange link "$bin.list" + files=$(_objlist .o "$bin.list") + xLIBS=$(_flaglist "$bin.list") + IFS="$NL" + redo-ifchange $files + xLIBS="$xLIBS" ./link "$3" $files + else + echo "default.do.sh: no rule to build '$1' or '$1.list'" >&2 + exit 99 + fi + ;; +esac diff --git a/redoconf/default.precompile.od b/redoconf/default.precompile.od new file mode 100644 index 0000000..b52eb24 --- /dev/null +++ b/redoconf/default.precompile.od @@ -0,0 +1,31 @@ +# Run the extra steps necessary before compiling +# C/C++ programs of the specified type. +# +# Notably, we have to precompile any precompiled +# headers. We also generate redoconf.h in case +# programs want to include it. +. ./redoconf.rc +rc_include _all.rc + +case ${1%.precompile} in + cc) pch_files="$PRE_CC_TARGETS" ;; + cc-fpic) pch_files="$PRE_CC_TARGETS_FPIC" ;; + cxx) pch_files="$PRE_CXX_TARGETS" ;; + cxx-fpic) pch_files="$PRE_CXX_TARGETS_FPIC" ;; + *) exit 42 ;; +esac + +IFS="$NL" +set -f +redo-ifchange "redoconf.h" $pch_files + +# Subtle: +# Don't consider this target to have changed unless +# the precompiled header's stamp has changed. +# We generate redoconf.h, in case +# a C program wants to include it, but we +# don't care if it has changed, because the C program +# will have its own dependency on that file. +for d in $t; do + cat "$d.stamp" +done | redo-stamp diff --git a/redoconf/link-shlib.od b/redoconf/link-shlib.od new file mode 100644 index 0000000..e3cb976 --- /dev/null +++ b/redoconf/link-shlib.od @@ -0,0 +1,36 @@ +. ./redoconf.rc +rc_include _all.rc rc/shlib.rc + +# Tricky quoting: see _compile.od for details. +if [ "$HAVE_SHLIB" = 1 ]; then + cat >$3 <<-EOF + #!/bin/sh -e + LINK=$(shquote "$LINK") + LDFLAGS=$(shquote "$LDFLAGS") + OPTFLAGS=$(shquote "$OPTFLAGS") + LIBS=$(shquote "$LIBS") + o="\$1" + ob="\${o#*/}" + shift + IFS="$NL" + set -f + \$LINK -shared -o "\$o" \\ + -Wl,-soname,"\$ob" \\ + \$LDFLAGS \$OPTFLAGS \\ + "\$@" \\ + \$LIBS + EOF +else + # If no shared library support and we try to build one, + # compensate by building a static library instead in the + # same place. + cat >$3 <<-EOF + #!/bin/sh -e + o="\$1" + shift + rm -f "\$o" + ar q "\$o" "\$@" + EOF +fi +chmod a+x "$3" +redo-stamp <$3 diff --git a/redoconf/link.od b/redoconf/link.od new file mode 100644 index 0000000..e416539 --- /dev/null +++ b/redoconf/link.od @@ -0,0 +1,22 @@ +. ./redoconf.rc +rc_include _all.rc + +# Tricky quoting: see _compile.od for details. +cat >$3 <<-EOF + #!/bin/sh -e + LINK=$(shquote "$LINK") + LDFLAGS=$(shquote "$LDFLAGS") + OPTFLAGS=$(shquote "$OPTFLAGS") + LIBS=$(shquote "$LIBS") + o="\$1" + shift + IFS="$NL" + set -f + \$LINK -o "\$o" \\ + -Wl,-rpath,'\$ORIGIN' \\ + \$LDFLAGS \$OPTFLAGS \\ + "\$@" \\ + \$LIBS +EOF +chmod a+x "$3" +redo-stamp <$3 diff --git a/redoconf/rc.sh b/redoconf/rc.sh new file mode 100644 index 0000000..a5a3cd6 --- /dev/null +++ b/redoconf/rc.sh @@ -0,0 +1,240 @@ +# This script starts with $PWD=output dir, $S=input dir. +REDOCONF="$S/redoconf" +if [ ! -d "$S" ] || [ ! -f "$REDOCONF/default.do.sh" ]; then + echo "default.do.sh: \$S is not set correctly." >&2 + exit 99 +fi +. "$REDOCONF/utils.sh" +RC_TARGET="$1" +rm -f "$RC_TARGET.log" + +redo-ifchange "$REDOCONF/rc.sh" "$REDOCONF/utils.sh" + +_rc_exit_check() { + if [ -z "$RC_INCLUDE_RAN" ]; then + echo "Fatal: used redoconf/rc.sh but didn't call rc_include." >&2 + exit 99 + elif [ -n "$RC_QUEUE" ]; then + echo "Fatal: must call rc_save or rc_undo before ending." >&2 + exit 99 + fi +} +trap _rc_exit_check EXIT + +rc_hook() { + # nothing by default; can be overridden + : +} + +# Declare that a variable *named* $1 is used +# as input for the current script, and provide +# a help message in $2 for use with +# configure --help-flags. +helpmsg() { + # Nothing to do by default + rc_hook "$1" +} + +# Assign the string $2 to the global variable +# *named* by $1. +replaceln() { + rc_hook "$1" + eval $1=\$2 +} + +# If $2 is nonempty, append a newline and $2 to +# the global variable *named* by $1 +appendln() { + rc_hook "$1" + eval local tmp=\"\$$1\$NL\$2\" + eval $1='${tmp#$NL}' +} + +# Write a command line that calls "uses $1", +# including proper sh-escaping. +rc_helpmsg() { + local cmd="helpmsg" + cmd="helpmsg $1 $(shquote "$2")" + eval "$cmd" + appendln RC_HELP_QUEUE "$cmd" +} + +_rc_record() { + if ! contains_line "$RC_CHANGED" "$1"; then + local oldv= + eval oldv="\$$1" + eval "old$1=\$oldv" + RC_CHANGED="$RC_CHANGED$NL$1" + fi +} + +# Write a command line that calls "appendln $1 $2", +# including properly sh-escaping $2. +rc_appendln() { + RC_LOG="$RC_LOG $1 += $(shquote "$2")$NL" + _rc_record "$1" + local cmd="appendln $1 $(shquote "$2")" + eval "$cmd" + appendln RC_QUEUE "$cmd" +} + +# Write a command line that replaces $1 with $2, +# including properly sh-escaping $2. +# This is good for variables like CC and CXX, where +# appending isn't what we want. +rc_replaceln() { + RC_LOG="$RC_LOG $1 = $(shquote "$2")$NL" + _rc_record "$1" + local cmd="replaceln $1 $(shquote "$2")" + eval "$cmd" + appendln RC_QUEUE "$cmd" +} + +# Read compiler variables from _init.rc and the listed .rc files. +# Runs redo-ifchange to generate the .rc files as needed. +rc_include() { + local d="" want="" target="$RC_TARGET" ops4="$PS4" + RC_INCLUDE_RAN=1 + for d in rc/_init.rc "$@"; do + if [ "$d" = "${d%.rc}" ]; then + xecho "$0: rc_include: '$d' must end in .rc" >&2 + exit 99 + fi + if ! contains_line "$RC_INCLUDES" "$d"; then + want="$want$NL$d" + RC_INCLUDES="$RC_INCLUDES$NL$d" + fi + done + want="${want#$NL}" + if [ -n "$want" ]; then + xIFS="$IFS" + IFS="$NL" + set -f + redo-ifchange $want + for d in $want; do + IFS="$xIFS" + set +f + RC_TARGET="$d" + PS4="$PS4[$d] " + [ ! -e "$d" ] || { :; . "./$d"; } + PS4="$ops4" + done + IFS="$xIFS" + set +f + fi + unset RC_QUEUE + PS4="$ops4" + RC_TARGET="$target" +} + +# Undo the currently enqueued rc_appendln and rc_replaceln +# actions, restoring the affected variables back to their +# original values. +rc_undo() { + local xIFS="$IFS" v= + IFS="$NL" + for k in $RC_CHANGED; do + eval v="\$old$k" + eval "$k=\$v" + done + unset RC_CHANGED + unset RC_QUEUE + unset RC_LOG +} + +# Write the currently active rc_include, +# rc_replaceln, and rc_appendln commands to stdout, +# to produce the final .rc file. +rc_save() { + printf '%s' "${RC_LOG}" >&2 + if [ -n "$RC_INCLUDES" ]; then + ( + xIFS="$IFS" + IFS="$NL" + printf 'rc_include ' + for d in $RC_INCLUDES; do + printf '%s ' "$d" + done + printf '\n' + ) + fi + xecho "$RC_HELP_QUEUE" + xecho "$RC_QUEUE" + unset RC_QUEUE + unset RC_CHANGED +} + +rc_compile() { + redo-ifchange "$REDOCONF/trycompile" + ( . "$REDOCONF/trycompile" "$@" ) >>"$RC_TARGET.log" 2>&1 +} + +_pkg_config() { + ( + IFS="$NL" + set -f + $PKG_CONFIG $PKG_CONFIG_FLAGS "$@" + ) +} + +_rc_pkg_add() { + local var="$1" vvar= want= + shift + if [ -n "$HAVE_PKG_CONFIG" ]; then + for d in "$@"; do + if _pkg_config --exists "$d"; then + want="$want $d" + fi + done + if [ -n "$want" ]; then + rc_appendln CPPFLAGS \ + "$(rc_splitwords \ + "$(_pkg_config --cflags $want)")" + vvar="$(rc_splitwords \ + "$(_pkg_config --libs $want)")" + rc_appendln "$var" "$vvar" + fi + else + echo "(pkg-config is missing)" >&2 + fi +} + +# Determine whether packages listed in $2 all exists and are functional, +# by finding them using pkg-config and running the command in $3..$n. +# +# If the package works: +# HAVE_$1 is set to 1 +# CPPFLAGS and the variable named by $1 are updated with compiler and +# linker flags, respectively. +# else: +# HAVE_$1 is set to blank. +# +# Returns success in either case. Check detection results in the +# HAVE_$1 variable if needed. +rc_pkg_detect() { + if ! contains_line "$RC_INCLUDES" rc/pkg-config.rc; then + echo "Error: include pkg-config.rc before using rc_pkg_*" >&2 + return 1 + fi + if [ "$#" -lt 3 ]; then + echo "Error: rc_pkg_detect needs a command to test." >&2 + return 1 + fi + local var="$1" vvar="" pkgs="$2" + shift + shift + eval vvar="\$$var" + rc_helpmsg "$var" "Extra linker options for '$pkgs'" + if [ -z "$vvar" ]; then + _rc_pkg_add "$var" $pkgs + eval vvar="\$$var" + fi + appendln LIBS "$vvar" + if ("$@"); then + rc_replaceln "HAVE_$var" 1 + else + rc_undo + rc_replaceln "HAVE_$var" "" + rc_replaceln "$var" "" + fi +} diff --git a/redoconf/rc/CC.rc.od b/redoconf/rc/CC.rc.od new file mode 100644 index 0000000..505ee6e --- /dev/null +++ b/redoconf/rc/CC.rc.od @@ -0,0 +1,68 @@ +. ./redoconf.rc +rc_include + +rc_helpmsg ARCH "Architecture prefix for output (eg. i686-w64-mingw32-)" +rc_helpmsg CC "C compiler name (cc)" +rc_helpmsg CPPFLAGS "Extra C preprocessor flags (eg. -I... -D...)" +rc_helpmsg CFLAGS "Extra C compiler flags (eg. -O2 -g)" +rc_helpmsg OPTFLAGS "C/C++ compiler flag overrides (eg. -g0)" +rc_helpmsg LINK "Linker name (cc)" +rc_helpmsg LDFLAGS "Extra linker options (eg. -s -static)" +rc_helpmsg LIBS "Extra libraries to always link against (eg. -lsocket)" +rc_helpmsg STATIC "Link libraries and binaries statically" + +if [ -n "$CC" ]; then + set -- "$CC" +else + if [ -n "$ARCH" ] && [ "$ARCH" = "${ARCH%-}" ]; then + # Make sure arch name includes trailing dash if nonempty + ARCH="$ARCH-" + fi + set -- \ + "${ARCH}cc" "${ARCH}gcc" \ + "${ARCH}clang" "/usr/bin/${ARCH}clang"-[0-9]* \ + "${ARCH}c++" "${ARCH}g++" \ + "${ARCH}clang++" "/usr/bin/${ARCH}clang++"-[0-9]* +fi + +rc_appendln CPPFLAGS "-I." +[ -n "$STATIC" ] && rc_appendln LDFLAGS "-static" + +for d in "$@"; do + echo "Trying C compiler: '$d'" >&2 + if CC="$d" CXX="" LINK="$d" rc_compile cc link 'extern int i;'; then + rc_replaceln CC "$d" + rc_replaceln LINK "$d" + + # mingw32 (not mingw64) generates binaries that need + # a dynamic libgcc at runtime for certain operations + # (like 64-bit integer division), which is non-obvious. + # Include it statically if possible, but only on Windows, + # which we'll detect by whether windows.h exists. + # + # If adding the option fails, maybe it's some + # compiler other than gcc, so that's fine. + x="-static-libgcc$NL-static-libstdc++" + appendln LDFLAGS "$x" + prog='#include ' + if CC="$d" LINK="$d" rc_compile cc link "$prog"; then + rc_appendln LDFLAGS "$x" + fi + + # Set ARCH= to the right compiler prefix, either empty + # (use native compiler) or something like "i686-w64-mingw32-" + # (terminating dash), based on the compiler name. + x="-${CC##*/}" + x="${x%-*}" + x="${x#-}" + [ -n "$x" ] && x="$x-" + rc_replaceln ARCH "$x" + + rc_save + exit 0 + fi +done + +echo "Can't find a working C compiler." >&2 +rc_undo +exit 1 diff --git a/redoconf/rc/CXX.rc.od b/redoconf/rc/CXX.rc.od new file mode 100644 index 0000000..4859244 --- /dev/null +++ b/redoconf/rc/CXX.rc.od @@ -0,0 +1,35 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +rc_helpmsg CXX "C++ compiler name (c++)" +rc_helpmsg CXXFLAGS "Extra C++ compiler flags (eg. -O2 -g)" + +if [ -n "$CXX" ]; then + set -- "$CXX" +else + # Note: $ARCH has already been set correctly by CC.rc + set -- \ + "${ARCH}c++" "${ARCH}g++" \ + "${ARCH}clang++" "/usr/bin/${ARCH}clang++"-[0-9]* +fi + +for d in "$@"; do + [ -n "$d" ] || continue + echo "Trying C++ compiler: '$d'" >&2 + if CC="" CXX="$d" LINK="$d" rc_compile cxx link 'class A {};'; then + rc_replaceln CXX "$d" + # If the project activates CXX.rc, then we + # replace the C linker with C++. This causes + # it to include -lstdc++, etc. + # A future .rc could override this again. + rc_replaceln LINK "$d" + rc_save + exit 0 + fi +done + +echo "Warning: Can't find a working C++ compiler." >&2 +rc_undo +rc_replaceln CXX "" +rc_save +exit 0 diff --git a/redoconf/rc/Wall.rc.od b/redoconf/rc/Wall.rc.od new file mode 100644 index 0000000..35d3b36 --- /dev/null +++ b/redoconf/rc/Wall.rc.od @@ -0,0 +1,9 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +rc_appendln CPPFLAGS "-Wall" +if rc_compile cc nolink; then + rc_save +else + rc_undo +fi diff --git a/redoconf/rc/Wextra.rc.od b/redoconf/rc/Wextra.rc.od new file mode 100644 index 0000000..ec6cd3e --- /dev/null +++ b/redoconf/rc/Wextra.rc.od @@ -0,0 +1,9 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +rc_appendln CPPFLAGS "-Wextra" +if rc_compile cc nolink; then + rc_save +else + rc_undo +fi diff --git a/redoconf/rc/_init.rc.od b/redoconf/rc/_init.rc.od new file mode 100644 index 0000000..f197b14 --- /dev/null +++ b/redoconf/rc/_init.rc.od @@ -0,0 +1,8 @@ +if [ -e _flags ]; then + redo-ifchange _flags + cat _flags >$3 + redo-stamp <_flags +else + redo-ifcreate _flags + redo-stamp &2 + rc_undo +fi diff --git a/redoconf/rc/default.h.rc.od b/redoconf/rc/default.h.rc.od new file mode 100644 index 0000000..0057d77 --- /dev/null +++ b/redoconf/rc/default.h.rc.od @@ -0,0 +1,13 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +base="${1#*/}" +h="${base%.rc}" +H=$(echo "$h" | tr 'a-z.' 'A-Z_') + +if rc_compile cc nolink "#include <$h>"; then + rc_replaceln "HAVE_$H" 1 +else + rc_replaceln "HAVE_$H" "" +fi +rc_save diff --git a/redoconf/rc/default.hpp.precompiled.rc.od b/redoconf/rc/default.hpp.precompiled.rc.od new file mode 100644 index 0000000..41fc712 --- /dev/null +++ b/redoconf/rc/default.hpp.precompiled.rc.od @@ -0,0 +1,23 @@ +. ./redoconf.rc +rc_include rc/CXX.rc + +base="${1#rc/}" +src="${base%.hpp.precompiled.rc}" + +# The existence of the specific gcc warning about +# precompiled headers is a pretty good indicator +# that they are supported in the way we expect. +appendln CXXFLAGS "-Winvalid-pch" +if rc_compile cxx nolink; then + rc_appendln CXXFLAGS "$x" + + rc_appendln CXXFLAGS_PCH "-include$NL$src.hpp" + rc_appendln CXXFLAGS_PCH_FPIC "-include$NL$src.hpp.fpic" + + rc_appendln PRE_CXX_TARGETS "$src.hpp.gch" + rc_appendln PRE_CXX_TARGETS_FPIC "$src.hpp.fpic.gch" + rc_save +else + echo "Precompiled C++ headers not supported." >&2 + rc_undo +fi diff --git a/redoconf/rc/libgl.rc.od b/redoconf/rc/libgl.rc.od new file mode 100644 index 0000000..5a98829 --- /dev/null +++ b/redoconf/rc/libgl.rc.od @@ -0,0 +1,12 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=' +#include +int x = GL_VERSION_1_1; +void f() { glPopMatrix(); } +' + +rc_pkg_detect LIBGL "gl" \ + rc_compile cc link "$prog" +rc_save diff --git a/redoconf/rc/libgtk2.rc.od b/redoconf/rc/libgtk2.rc.od new file mode 100644 index 0000000..f8f55e1 --- /dev/null +++ b/redoconf/rc/libgtk2.rc.od @@ -0,0 +1,12 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=' +#include +int x = GTK_MAJOR_VERSION; +void f() { gtk_widget_child_focus(0, 0); } +' + +rc_pkg_detect LIBGTK2 "gtk+-2.0 gio-2.0 gdk-2.0 gdk-pixbuf-2.0" \ + rc_compile cc link "$prog" +rc_save diff --git a/redoconf/rc/libm.rc.od b/redoconf/rc/libm.rc.od new file mode 100644 index 0000000..87cc3ed --- /dev/null +++ b/redoconf/rc/libm.rc.od @@ -0,0 +1,25 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=' +#include +int x = FP_NORMAL; +volatile float y; +void f() { y = sin(y); } +' + +rc_pkg_detect LIBM libm \ + rc_compile cc link "$prog" +if [ -z "$HAVE_LIBM" ]; then + rc_undo + rc_replaceln HAVE_LIBM 1 + rc_appendln LIBM "-lm" + appendln LIBS "$LIBM" + if ! rc_compile cc link "$prog"; then + rc_undo + rc_replaceln HAVE_LIBM "" + rc_replaceln LIBM "" + fi +fi + +rc_save diff --git a/redoconf/rc/libpng.rc.od b/redoconf/rc/libpng.rc.od new file mode 100644 index 0000000..43a11c6 --- /dev/null +++ b/redoconf/rc/libpng.rc.od @@ -0,0 +1,12 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=' +#include +const char *x = PNG_LIBPNG_VER_STRING; +void f() { png_access_version_number(); } +' + +rc_pkg_detect LIBPNG libpng \ + rc_compile cc link "$prog" +rc_save diff --git a/redoconf/rc/libqt4.rc.od b/redoconf/rc/libqt4.rc.od new file mode 100644 index 0000000..e7a02eb --- /dev/null +++ b/redoconf/rc/libqt4.rc.od @@ -0,0 +1,10 @@ +. ./redoconf.rc +rc_include rc/CXX.rc rc/pkg-config.rc + +prog=' +#include +' + +rc_pkg_detect LIBQT4 QtCore \ + rc_compile cxx link "$prog" +rc_save diff --git a/redoconf/rc/libsdl.rc.od b/redoconf/rc/libsdl.rc.od new file mode 100644 index 0000000..1494d07 --- /dev/null +++ b/redoconf/rc/libsdl.rc.od @@ -0,0 +1,12 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=' +#include +int x = SDL_INIT_TIMER; +void f() { SDL_Init(0); } +' + +rc_pkg_detect LIBSDL "sdl" \ + rc_compile cc link "$prog" +rc_save diff --git a/redoconf/rc/libx11.rc.od b/redoconf/rc/libx11.rc.od new file mode 100644 index 0000000..7450467 --- /dev/null +++ b/redoconf/rc/libx11.rc.od @@ -0,0 +1,12 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=' +#include +int x = XYBitmap; +void f() { XCreateRegion(); } +' + +rc_pkg_detect LIBX11 "x11" \ + rc_compile cc link "$prog" +rc_save diff --git a/redoconf/rc/pkg-config.rc.od b/redoconf/rc/pkg-config.rc.od new file mode 100644 index 0000000..6c3f0cc --- /dev/null +++ b/redoconf/rc/pkg-config.rc.od @@ -0,0 +1,17 @@ +. ./redoconf.rc +rc_include + +for d in "$PKG_CONFIG" pkg-config; do + rc_undo + if "$d" --version >/dev/null 2>&1; then + rc_replaceln PKG_CONFIG "$d" + rc_replaceln HAVE_PKG_CONFIG 1 + rc_save + exit 0 + fi +done + +# Failed +rc_replaceln HAVE_PKG_CONFIG "" +rc_replaceln PKG_CONFIG "" +rc_save diff --git a/redoconf/rc/run.rc.od b/redoconf/rc/run.rc.od new file mode 100644 index 0000000..6f3f82f --- /dev/null +++ b/redoconf/rc/run.rc.od @@ -0,0 +1,27 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/windows.h.rc + +consider() { + echo "Considering RUN=$(shquote "$1")" >&2 + if [ -z "$1" ] || type "$1" >/dev/null 2>&1; then + rc_undo + rc_replaceln RUN "$1" + if RUN="$RUN" rc_compile cc run ""; then + rc_replaceln CAN_RUN 1 + rc_save + exit 0 + fi + fi +} + +consider "" +if [ -n "$HAVE_WINDOWS_H" ]; then + consider "wine64" + consider "wine" + consider "wine32" +fi + +rc_undo +rc_replaceln RUN "" +rc_replaceln CAN_RUN "" +rc_save diff --git a/redoconf/rc/shlib.rc.od b/redoconf/rc/shlib.rc.od new file mode 100644 index 0000000..35c938f --- /dev/null +++ b/redoconf/rc/shlib.rc.od @@ -0,0 +1,21 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +appendln CFLAGS "-fPIC" +appendln LDFLAGS "-shared" + +prog=' +#include +void f() { atoi(""); } +' + +if [ -n "$STATIC" ]; then + echo "--enable-static specified; not building shared libraries." >&2 + rc_replaceln HAVE_SHLIB "" +elif RCC_NO_MAIN=1 rc_compile cc link "$prog"; then + rc_replaceln HAVE_SHLIB 1 +else + echo "Not building shared libraries on this platform." >&2 + rc_replaceln HAVE_SHLIB "" +fi +rc_save diff --git a/redoconf/rc/zdefs.rc.od b/redoconf/rc/zdefs.rc.od new file mode 100644 index 0000000..7684a5f --- /dev/null +++ b/redoconf/rc/zdefs.rc.od @@ -0,0 +1,11 @@ +. ./redoconf.rc +rc_include rc/CC.rc + +x="-Wl,-z,defs" +rc_appendln LDFLAGS "$x" +if rc_compile cc link; then + rc_save +else + echo "'$x' doesn't work on this platform; skipped." >&2 + rc_undo +fi diff --git a/redoconf/rc_vars.od b/redoconf/rc_vars.od new file mode 100644 index 0000000..c6cf4b3 --- /dev/null +++ b/redoconf/rc_vars.od @@ -0,0 +1,25 @@ +. ./redoconf.rc + +# this is called by each call to replaceln() and appendln(). +RC_KEYS="RC_KEYS" +rc_hook() { + contains_line "$RC_KEYS" "$1" || RC_KEYS="$RC_KEYS$NL$1" +} +rc_include _all.rc + +# Escape double-quote and backslash so they can +# be included as a C-style double-quoted string. +cquote() { + local v="$(xecho "$1" | sed -e 's,[\"\\],\\&,g' -e 's,$, \\,')" + printf '"%s"' "${v% \\}" +} + +( + echo "# Automatically generated by autovars.od" + for k in $(echo "$RC_KEYS" | sort); do + [ "$k" != "RC_INCLUDES" ] || continue + eval v=\$$k + echo "$k=$(shquote "$v")" + done +) >$3 +redo-stamp <$3 diff --git a/redoconf/redoconf.h.od b/redoconf/redoconf.h.od new file mode 100644 index 0000000..197a21e --- /dev/null +++ b/redoconf/redoconf.h.od @@ -0,0 +1,34 @@ +redo-ifchange rc_vars +. ./rc_vars + +NL=" +" + +# Escape double-quote and backslash so they can +# be included as a C-style double-quoted string. +cquote() { + local v="$(printf '%s' "$1" | sed -e 's,[\"\\],\\&,g' -e 's,$, \\,')" + printf '"%s"' "${v% \\}" +} + +is_number() { + expr "$1" + 1 >/dev/null 2>&1 +} + +( + echo "/* Automatically generated by redoconf.h.od */" + IFS="$NL" + for k in $RC_KEYS; do + [ "$k" != "RC_KEYS" ] || continue + [ "$k" != "RC_INCLUDES" ] || continue + eval v=\$$k + if [ -z "$v" ]; then + echo "#undef $k" + elif is_number "$v"; then + echo "#define $k $v" + else + echo "#define $k $(cquote "$v")" + fi + done +) >$3 +redo-stamp <$3 diff --git a/redoconf/run.od b/redoconf/run.od new file mode 100644 index 0000000..104b0c1 --- /dev/null +++ b/redoconf/run.od @@ -0,0 +1,16 @@ +. ./redoconf.rc +rc_include rc/run.rc + +if [ -n "$CAN_RUN" ]; then + cat >$3 <<-EOF + #!/bin/sh -e + # Run the given program, possibly under an emulator. + [ -n "\$1" ] + unset DISPLAY + exec $RUN "\$@" + EOF + chmod a+x "$3" + redo-stamp <$3 +else + echo "Cannot run programs; not creating run script." >&2 +fi diff --git a/redoconf/trycompile b/redoconf/trycompile new file mode 100644 index 0000000..b36ac10 --- /dev/null +++ b/redoconf/trycompile @@ -0,0 +1,71 @@ +#!/bin/sh -e +die() { + echo "$0: trycompile: $*" >&2 + exit 99 +} + +ctype=$1 +linktype=$2 +code=$3 +case $ctype in + cc) + [ -n "$CC" ] || die 'must set $CC first.' + useCC="$CC" + useCF="$CFLAGS" + useExt=".c" + ;; + cxx) + [ -n "$CXX" ] || die 'must set $CXX first.' + useCC="$CXX" + useCF="$CXXFLAGS" + useExt=".cc" + ;; + *) + die "unknown compile type '$ctype'" + ;; +esac +case $linktype in + link|run) + [ -n "$LINK" ] || die 'must set $LINK first.' + ;; + nolink) + ;; + *) + die "unknown link type '$linktype'" + ;; +esac +base="try.$$.tmp" +out="$base.o" +out2="$base.exe" +src="$base$useExt" +rm -f "$src" "$out" "$out2" +set -x +: "[trycompile]" "$@" +main= +[ -n "$RCC_NO_MAIN" ] || main="int main() { return 0; }" +printf '%s' " + $code + + $main +" >"$src" +NL=" +" +IFS="$NL" +set +e +set -f +# We intentionally want to split the variables here, +# splitting on $NL, so we don't quote them. +# 'set -f' prevents interpreting wildcards, which +# we don't want to treat as special. +( + $useCC $CPPFLAGS $useCF -o "$out" -c "$src" || exit + if [ "$linktype" = "link" -o "$linktype" = "run" ]; then + $LINK $LDFLAGS -o "$out2" "$out" $LIBS || exit + fi + if [ "$linktype" = "run" ]; then + $RUN "./$out2" || exit + fi +) +rv=$? +rm -f "$src" "$out" "$out2" +exit "$rv" diff --git a/redoconf/utils.sh b/redoconf/utils.sh new file mode 100644 index 0000000..9dcedeb --- /dev/null +++ b/redoconf/utils.sh @@ -0,0 +1,58 @@ +NL=" +" + +# Like 'echo', but never processes backslash escapes. +# (Some shells' builtin echo do, and some don't, so this +# is safer.) +xecho() { + printf '%s\n' "$*" +} + +# Returns true if string $1 contains the line $2. +# Lines are delimited by $NL. +contains_line() { + case "$NL$1$NL" in + *"$NL$2$NL"*) return 0 ;; + *) return 1 ;; + esac +} + +# Split the first (up to) 20 words from $1, +# returning a string where the words are separated +# by $NL instead. +# +# To allow words including whitespace, you can backslash +# escape the whitespace (eg. hello\ world). Backslashes +# will be removed from the output string. +# +# We can use this to read pkg-config output, among other +# things. +# +# TODO: find a POSIX sh way to eliminate the word limit. +# I couldn't find an easy way to split on non-backslashed +# whitespace without a fork-exec, which is too slow. +# If we resorted to bashisms, we could use 'read -a', +# but that's not portable. +rc_splitwords() { + xecho "$1" | ( + read v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 \ + v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 \ + x + if [ -n "$x" ]; then + echo "rc_splitwords: too many words" >&2 + exit 97 + fi + for d in "$v0" "$v1" "$v2" "$v3" "$v4" \ + "$v5" "$v6" "$v7" "$v8" "$v9" \ + "$v10" "$v11" "$v12" "$v13" "$v14" \ + "$v15" "$v16" "$v17" "$v18" "$v19"; do + [ -z "$d" ] || xecho "$d" + done + ) +} + +# Escape single-quote characters so they can +# be included as a sh-style single-quoted string. +shquote() { + printf "'%s'" "$(xecho "$1" | sed -e "s,','\\\\'',g")" +} From ea6a7135f12fef6444458dc2f2c5c6c308e063be Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 23 Feb 2019 15:44:46 -0500 Subject: [PATCH 02/13] redoconf: avoid sed -E in _objlist(). Turns out there's a less confusing way to do it using 'case' wildcards instead. Reported-by: Wayne Scott --- redoconf/default.do.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/redoconf/default.do.sh b/redoconf/default.do.sh index 6c4de48..76cb10d 100644 --- a/redoconf/default.do.sh +++ b/redoconf/default.do.sh @@ -65,13 +65,18 @@ _pick_src() { } _objlist() { - local suffix="$1" list="$2" base="${2##*/}" + local suffix="$1" list="$2" + local base="${2##*/}" local dir="${2%"$base"}" - sed -Ee 's/\.(c|cc|cpp|cxx|C|c\+\+)$/'"$suffix/" <"$2" | while read -r d; do - [ "$d" = "${d#-}" ] || continue - echo "$dir$d" - done + case $d in + -*) ;; + *.c|*.cc|*.cpp|*.cxx|*.C|*.c++) + echo "$dir${d%.*}$suffix" + ;; + *) echo "$dir$d" ;; + esac + done <"$list" } _flaglist() { From 337e026ce30fcf958da7043a661d2ea862fb4b03 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 23 Feb 2019 15:51:30 -0500 Subject: [PATCH 03/13] redoconf: clock_gettime() detection needs to depend on -lrt. More generally, default.func.rc.od wasn't super useful because you couldn't specify either a header file or library dependencies. Drop it and make an explicit clock_gettime.rc.od. As a bonus, this also checks that CLOCK_MONOTONIC exists as expected. Reported-by: Wayne Scott --- docs/cookbook/c/all.rc.od | 2 +- docs/cookbook/c/rc/clock_gettime.rc.od | 17 +++++++++++++++++ redoconf/rc/default.func.rc.od | 13 ------------- 3 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 docs/cookbook/c/rc/clock_gettime.rc.od delete mode 100644 redoconf/rc/default.func.rc.od diff --git a/docs/cookbook/c/all.rc.od b/docs/cookbook/c/all.rc.od index 179fc92..5b050d2 100644 --- a/docs/cookbook/c/all.rc.od +++ b/docs/cookbook/c/all.rc.od @@ -9,7 +9,7 @@ rc_include \ rc/libm.rc \ rc/rt.autolib.rc \ rc/libpng.rc \ - rc/clock_gettime.func.rc \ + rc/clock_gettime.rc \ rc/mach_time.h.rc \ rc/windows.h.rc \ rc/posix.rc \ diff --git a/docs/cookbook/c/rc/clock_gettime.rc.od b/docs/cookbook/c/rc/clock_gettime.rc.od new file mode 100644 index 0000000..85a3307 --- /dev/null +++ b/docs/cookbook/c/rc/clock_gettime.rc.od @@ -0,0 +1,17 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/rt.autolib.rc rc/posix.rc + +prog=" +#include + +void test() { clock_gettime(CLOCK_MONOTONIC, NULL); } +" + +rc_appendln LIBS "$LIBRT" +if rc_compile cc link "$prog"; then + rc_replaceln "HAVE_CLOCK_GETTIME" 1 +else + rc_undo + rc_replaceln "HAVE_CLOCK_GETTIME" "" +fi +rc_save diff --git a/redoconf/rc/default.func.rc.od b/redoconf/rc/default.func.rc.od deleted file mode 100644 index 2fcf87a..0000000 --- a/redoconf/rc/default.func.rc.od +++ /dev/null @@ -1,13 +0,0 @@ -. ./redoconf.rc -rc_include rc/CC.rc - -base="${1#*/}" -f="${base%.func.rc}" -F=$(echo "$f" | tr 'a-z.' 'A-Z_') - -if rc_compile cc link "void $f(); void test() { $f(); }"; then - rc_replaceln "HAVE_$F" 1 -else - rc_replaceln "HAVE_$F" "" -fi -rc_save From bdb8d8a27d5907262fd895897a70c28e843f00d8 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 23 Feb 2019 16:45:08 -0500 Subject: [PATCH 04/13] redoconf: better handling of required vs optional detectors. CC.rc was the only "mandatory" detection, which was weird and inconsistent. Instead, make it optional like the others, and have it set a HAVE_CC variable appropriately (and have CXX.rc work the same way). Then, add a default.required.rc.od that checks the HAVE_* for any variable and aborts if it is not available. This allows us to fix confusing behaviour in allconfig.do, which would try every compiler on the system, but redo would print a (non-fatal) error message (and prevent redo-stamp optimization) when CC.rc failed for any non-working compilers. Now CC.rc just politely reports that it didn't find a compiler. Then we change all.rc.od to make CC.rc mandatory. Reported-by: Nathaniel Filardo --- docs/cookbook/c/.gitignore | 1 + docs/cookbook/c/all.rc.od | 2 +- docs/cookbook/c/allconfig.do | 10 +++++++--- docs/cookbook/c/arches.do | 24 +++++++++++++----------- docs/cookbook/c/hello world.list.od | 7 +++---- docs/cookbook/c/sources.do | 12 ++++++++++++ redoconf/rc.sh | 4 ++-- redoconf/rc/CC.rc.od | 5 +++-- redoconf/rc/CXX.rc.od | 2 +- redoconf/rc/default.required.rc.od | 13 +++++++++++++ 10 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 docs/cookbook/c/sources.do create mode 100644 redoconf/rc/default.required.rc.od diff --git a/docs/cookbook/c/.gitignore b/docs/cookbook/c/.gitignore index 0703d8b..210b4a3 100644 --- a/docs/cookbook/c/.gitignore +++ b/docs/cookbook/c/.gitignore @@ -4,3 +4,4 @@ hello /arches /out /out.* +/sources diff --git a/docs/cookbook/c/all.rc.od b/docs/cookbook/c/all.rc.od index 5b050d2..1ff6a57 100644 --- a/docs/cookbook/c/all.rc.od +++ b/docs/cookbook/c/all.rc.od @@ -1,6 +1,6 @@ . ./redoconf.rc rc_include \ - rc/CC.rc \ + rc/CC.required.rc \ rc/CXX.rc \ rc/libqt4.rc \ rc/libgtk2.rc \ diff --git a/docs/cookbook/c/allconfig.do b/docs/cookbook/c/allconfig.do index c659d30..807a1c9 100644 --- a/docs/cookbook/c/allconfig.do +++ b/docs/cookbook/c/allconfig.do @@ -8,9 +8,13 @@ config() { ( cd "$dir" && ../configure --host="$arch" "$@" && - redo-ifchange rc/CC.rc && + ( set --; + . ./redoconf.rc && + rc_include rc/CC.rc && + [ -n "$HAVE_CC" ] + ) && echo "$dir" - ) || : + ) || (echo "Skipping arch '$arch' $*" >&2) } for d in $(cat arches); do @@ -22,6 +26,6 @@ for d in $(cat arches); do config "out.$d" "$arch" & config "out.$d.static" "$arch" "--enable-static" & config "out.$d.opt" "$arch" "--enable-optimization" & -done +done >$3 wait diff --git a/docs/cookbook/c/arches.do b/docs/cookbook/c/arches.do index a779ebb..cb48e0a 100644 --- a/docs/cookbook/c/arches.do +++ b/docs/cookbook/c/arches.do @@ -1,14 +1,16 @@ -IFS=: -echo native >$3 -if [ -z "$NO_SLOW_TESTS" ]; then - for dir in $PATH; do - for d in "$dir"/*-cc "$dir"/*-gcc; do - base=${d##*/} - arch=${base%-*} - if [ -x "$d" ]; then echo "$arch"; fi +( + echo native + echo fake-always-fails + if [ -z "$NO_SLOW_TESTS" ]; then + IFS=: + for dir in $PATH; do + for d in "$dir"/*-cc "$dir"/*-gcc; do + base=${d##*/} + arch=${base%-*} + if [ -x "$d" ]; then echo "$arch"; fi + done done - done >>$3 -fi - + fi +) >$3 redo-always redo-stamp <$3 diff --git a/docs/cookbook/c/hello world.list.od b/docs/cookbook/c/hello world.list.od index d9f5200..cb5548b 100644 --- a/docs/cookbook/c/hello world.list.od +++ b/docs/cookbook/c/hello world.list.od @@ -1,8 +1,8 @@ -# This script is run from the output dir, -# which contains a src/ symlink to the source dir. - +# This script is run from the output dir. +# The source dir is at $S. . ./redoconf.rc rc_include all.rc +redo-ifchange "$S/sources" ( cd "$S" @@ -26,5 +26,4 @@ rc_include all.rc printf '%s\n' "$LIBGTK2" "$LIBQT4" ) >$3 -redo-always redo-stamp <$3 diff --git a/docs/cookbook/c/sources.do b/docs/cookbook/c/sources.do new file mode 100644 index 0000000..81559c6 --- /dev/null +++ b/docs/cookbook/c/sources.do @@ -0,0 +1,12 @@ +# This file changes when the list of source files changes. +# If you depend on it, you can make a target that gets +# rebuilt only when it might need to reconsider the +# list of available source files. +find . -name '*.[ch]' -o \ + -name '*.cc' -o \ + -name '*.od' -o \ + -name '*.list' | +grep -v '^\./out\.' | +sort >$3 +redo-always +redo-stamp <$3 diff --git a/redoconf/rc.sh b/redoconf/rc.sh index a5a3cd6..bc2fa4d 100644 --- a/redoconf/rc.sh +++ b/redoconf/rc.sh @@ -13,10 +13,10 @@ redo-ifchange "$REDOCONF/rc.sh" "$REDOCONF/utils.sh" _rc_exit_check() { if [ -z "$RC_INCLUDE_RAN" ]; then echo "Fatal: used redoconf/rc.sh but didn't call rc_include." >&2 - exit 99 + exit 91 elif [ -n "$RC_QUEUE" ]; then echo "Fatal: must call rc_save or rc_undo before ending." >&2 - exit 99 + exit 92 fi } trap _rc_exit_check EXIT diff --git a/redoconf/rc/CC.rc.od b/redoconf/rc/CC.rc.od index 505ee6e..03605cd 100644 --- a/redoconf/rc/CC.rc.od +++ b/redoconf/rc/CC.rc.od @@ -57,7 +57,7 @@ for d in "$@"; do x="${x#-}" [ -n "$x" ] && x="$x-" rc_replaceln ARCH "$x" - + rc_replaceln HAVE_CC 1 rc_save exit 0 fi @@ -65,4 +65,5 @@ done echo "Can't find a working C compiler." >&2 rc_undo -exit 1 +rc_replaceln CC "" +rc_save diff --git a/redoconf/rc/CXX.rc.od b/redoconf/rc/CXX.rc.od index 4859244..c6875c9 100644 --- a/redoconf/rc/CXX.rc.od +++ b/redoconf/rc/CXX.rc.od @@ -23,6 +23,7 @@ for d in "$@"; do # it to include -lstdc++, etc. # A future .rc could override this again. rc_replaceln LINK "$d" + rc_replaceln HAVE_CXX 1 rc_save exit 0 fi @@ -32,4 +33,3 @@ echo "Warning: Can't find a working C++ compiler." >&2 rc_undo rc_replaceln CXX "" rc_save -exit 0 diff --git a/redoconf/rc/default.required.rc.od b/redoconf/rc/default.required.rc.od new file mode 100644 index 0000000..157aee8 --- /dev/null +++ b/redoconf/rc/default.required.rc.od @@ -0,0 +1,13 @@ +. ./redoconf.rc + +base=${1%.required.rc} +name=${base#*/} +NAME=$(echo "$name" | tr 'a-z.' 'A-Z_') + +rc_include "$base.rc" + +eval v="\$$NAME" +if [ -z "$v" ]; then + echo "$NAME is required in order to build." >&2 + exit 1 +fi From 017997c035e69bd2f8d882cf63fba81844a31aeb Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 23 Feb 2019 21:00:26 -0500 Subject: [PATCH 05/13] redoconf: posix.rc: fix abort when timespec is not available. Now we define HAS_POSIX=1 if it works, and to blank otherwise, to be consistent with other rc scripts, but it doesn't abort if we can't find timespec. Meanwhile, slightly clarify the error message in rc.sh. Reported-by: Nathaniel Filardo --- docs/cookbook/c/clean.do | 2 ++ docs/cookbook/c/rc/posix.rc.od | 10 +++++++--- redoconf/rc.sh | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 docs/cookbook/c/clean.do diff --git a/docs/cookbook/c/clean.do b/docs/cookbook/c/clean.do new file mode 100644 index 0000000..4b7488c --- /dev/null +++ b/docs/cookbook/c/clean.do @@ -0,0 +1,2 @@ +rm -rf out out.* +rm -f *~ .*~ */*~ */.*~ sources arches allconfig when.c diff --git a/docs/cookbook/c/rc/posix.rc.od b/docs/cookbook/c/rc/posix.rc.od index 546fc8a..4a6b172 100644 --- a/docs/cookbook/c/rc/posix.rc.od +++ b/docs/cookbook/c/rc/posix.rc.od @@ -8,9 +8,13 @@ struct timespec x; ' x= +rc_replaceln HAS_POSIX 1 if ! rc_compile cc link "$prog"; then - x="-D_XOPEN_SOURCE=500" - rc_appendln CPPFLAGS "$x" - rc_compile cc link "$prog" + x="-D_XOPEN_SOURCE=500" + rc_appendln CPPFLAGS "$x" + if ! rc_compile cc link "$prog"; then + rc_undo + rc_replaceln HAS_POSIX "" + fi fi rc_save diff --git a/redoconf/rc.sh b/redoconf/rc.sh index bc2fa4d..2163a15 100644 --- a/redoconf/rc.sh +++ b/redoconf/rc.sh @@ -15,7 +15,7 @@ _rc_exit_check() { echo "Fatal: used redoconf/rc.sh but didn't call rc_include." >&2 exit 91 elif [ -n "$RC_QUEUE" ]; then - echo "Fatal: must call rc_save or rc_undo before ending." >&2 + echo "Fatal: script exited without rc_save or rc_undo." >&2 exit 92 fi } From 328d4ead7a825a35899e258addf1716666622741 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sun, 24 Feb 2019 22:29:19 -0500 Subject: [PATCH 06/13] Fix some build problems on MacOS X. - Linking shared libraries needs slightly different options. - We were trying to detect mach_time.h but needed to detect mach/mach_time.h instead. While we're here, add a --disable-shared option to ./configure, which is different from --enable-static. --disable-shared does not build *new* share libraries, but doesn't pass -static to the linker (apparently there is no static linking posible on MacOS). --- docs/cookbook/c/all.rc.od | 2 +- docs/cookbook/c/monotime.c | 2 +- docs/cookbook/c/rc/posix.rc.od | 4 ++-- redoconf/configure.sh | 6 +++++- redoconf/link-shlib.od | 21 ++++++++++++++++++++- redoconf/rc/default.h.rc.od | 5 +++-- redoconf/rc/shlib.rc.od | 32 +++++++++++++++++++++++++++----- 7 files changed, 59 insertions(+), 13 deletions(-) diff --git a/docs/cookbook/c/all.rc.od b/docs/cookbook/c/all.rc.od index 1ff6a57..22b35b0 100644 --- a/docs/cookbook/c/all.rc.od +++ b/docs/cookbook/c/all.rc.od @@ -10,7 +10,7 @@ rc_include \ rc/rt.autolib.rc \ rc/libpng.rc \ rc/clock_gettime.rc \ - rc/mach_time.h.rc \ + rc/mach__mach_time.h.rc \ rc/windows.h.rc \ rc/posix.rc \ rc/printf_lld.rc \ diff --git a/docs/cookbook/c/monotime.c b/docs/cookbook/c/monotime.c index 784f577..98602ba 100644 --- a/docs/cookbook/c/monotime.c +++ b/docs/cookbook/c/monotime.c @@ -23,7 +23,7 @@ long long monotime(void) { return !result ? 1 : result; } -#elif HAVE_MACH_TIME_H +#elif HAVE_MACH__MACH_TIME_H #include #include diff --git a/docs/cookbook/c/rc/posix.rc.od b/docs/cookbook/c/rc/posix.rc.od index 4a6b172..b33cb21 100644 --- a/docs/cookbook/c/rc/posix.rc.od +++ b/docs/cookbook/c/rc/posix.rc.od @@ -8,13 +8,13 @@ struct timespec x; ' x= -rc_replaceln HAS_POSIX 1 +rc_replaceln HAVE_POSIX 1 if ! rc_compile cc link "$prog"; then x="-D_XOPEN_SOURCE=500" rc_appendln CPPFLAGS "$x" if ! rc_compile cc link "$prog"; then rc_undo - rc_replaceln HAS_POSIX "" + rc_replaceln HAVE_POSIX "" fi fi rc_save diff --git a/redoconf/configure.sh b/redoconf/configure.sh index 83d77a1..38986e9 100644 --- a/redoconf/configure.sh +++ b/redoconf/configure.sh @@ -50,7 +50,8 @@ usage() { --prefix= Change installation prefix (usually /usr/local) --host= Architecture prefix for output (eg. i686-w64-mingw32-) - --enable-static Link libraries and binaries statically + --enable-static Link binaries statically + --disable-shared Do not build shared libraries --{dis,en}able-optimization Disable/enable optimization for C/C++ --{dis,en}able-debug Disable/enable debugging flags for C/C++ -h, --help This help message @@ -115,6 +116,9 @@ for d in "$@"; do --enable-static) emit "STATIC" "1" ;; + --disable-shared) + emit "NOSHARED" "1" + ;; --enable-optimization) emit_append OPTFLAGS "-O2" ;; diff --git a/redoconf/link-shlib.od b/redoconf/link-shlib.od index e3cb976..aa632f0 100644 --- a/redoconf/link-shlib.od +++ b/redoconf/link-shlib.od @@ -2,7 +2,7 @@ rc_include _all.rc rc/shlib.rc # Tricky quoting: see _compile.od for details. -if [ "$HAVE_SHLIB" = 1 ]; then +if [ "$HAVE_SHLIB" = UNIX ]; then cat >$3 <<-EOF #!/bin/sh -e LINK=$(shquote "$LINK") @@ -20,6 +20,25 @@ if [ "$HAVE_SHLIB" = 1 ]; then "\$@" \\ \$LIBS EOF +elif [ "$HAVE_SHLIB" = MACOS ]; then + cat >$3 <<-EOF + #!/bin/sh -e + LINK=$(shquote "$LINK") + LDFLAGS=$(shquote "$LDFLAGS") + OPTFLAGS=$(shquote "$OPTFLAGS") + LIBS=$(shquote "$LIBS") + LIBDIR=$(shquote "$LIBDIR") + o="\$1" + ob="\${o#*/}" + shift + IFS="$NL" + set -f + \$LINK -dynamiclib -o "\$o" \\ + -install_name "\$ob" \\ + \$LDFLAGS \$OPTFLAGS \\ + "\$@" \\ + \$LIBS + EOF else # If no shared library support and we try to build one, # compensate by building a static library instead in the diff --git a/redoconf/rc/default.h.rc.od b/redoconf/rc/default.h.rc.od index 0057d77..6df73cb 100644 --- a/redoconf/rc/default.h.rc.od +++ b/redoconf/rc/default.h.rc.od @@ -2,8 +2,9 @@ rc_include rc/CC.rc base="${1#*/}" -h="${base%.rc}" -H=$(echo "$h" | tr 'a-z.' 'A-Z_') +h1="${base%.rc}" +h=$(echo "$h1" | sed -e 's,__,/,g') # x__y_z.h.rc.od -> +H=$(echo "$h1" | tr 'a-z.' 'A-Z_') if rc_compile cc nolink "#include <$h>"; then rc_replaceln "HAVE_$H" 1 diff --git a/redoconf/rc/shlib.rc.od b/redoconf/rc/shlib.rc.od index 35c938f..20211b4 100644 --- a/redoconf/rc/shlib.rc.od +++ b/redoconf/rc/shlib.rc.od @@ -1,21 +1,43 @@ . ./redoconf.rc rc_include rc/CC.rc -appendln CFLAGS "-fPIC" -appendln LDFLAGS "-shared" - prog=' #include void f() { atoi(""); } ' +try_unix_style() { + ( + appendln CFLAGS "-fPIC" + appendln LDFLAGS "-shared" + appendln LDFLAGS "-Wl,-soname,x.so" + RCC_NO_MAIN=1 rc_compile cc link "$prog" + ) +} + +try_macos_style() { + ( + appendln CFLAGS "-fPIC" + appendln LDFLAGS "-dynamiclib" + appendln LDFLAGS "-current_version" + appendln LDFLAGS "1.0" + RCC_NO_MAIN=1 rc_compile cc link "$prog" + ) +} + if [ -n "$STATIC" ]; then echo "--enable-static specified; not building shared libraries." >&2 rc_replaceln HAVE_SHLIB "" -elif RCC_NO_MAIN=1 rc_compile cc link "$prog"; then - rc_replaceln HAVE_SHLIB 1 +elif [ -n "$NOSHARED" ]; then + echo "--disable-shared specified; not building shared libraries." >&2 + rc_replaceln HAVE_SHLIB "" +elif try_unix_style; then + rc_replaceln HAVE_SHLIB UNIX +elif try_macos_style; then + rc_replaceln HAVE_SHLIB MACOS else echo "Not building shared libraries on this platform." >&2 + rc_undo rc_replaceln HAVE_SHLIB "" fi rc_save From 313ac6a51c0f87987b288aaf5eb24901fc133b97 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sun, 24 Feb 2019 22:36:47 -0500 Subject: [PATCH 07/13] minimal/do: remove dependency on 'seq' command. It was not available in older versions of FreeBSD and MacOS. Reported-by: Wayne Scott --- minimal/do | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/minimal/do b/minimal/do index 9c25919..bd78473 100755 --- a/minimal/do +++ b/minimal/do @@ -4,7 +4,7 @@ # For the full version, visit http://github.com/apenwarr/redo # # The author disclaims copyright to this source file and hereby places it in -# the public domain. (2010 12 14; updated 2018 12 13) +# the public domain. (2010 12 14; updated 2019 02 24) # USAGE=" usage: do [-d] [-x] [-v] [-c] @@ -28,16 +28,23 @@ if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then plain="$(printf '\033[m')" fi +# The 'seq' command is not available on all platforms. +_seq() { + local x=0 max="$1" + while [ "$x" -lt "$max" ]; do + x=$((x + 1)) + echo "$x" + done +} + # Split $1 into a dir part ($_dirsplit_dir) and base filename ($_dirsplit_base) -_dirsplit() -{ +_dirsplit() { _dirsplit_base=${1##*/} _dirsplit_dir=${1%$_dirsplit_base} } # Like /usr/bin/dirname, but avoids a fork and uses _dirsplit semantics. -qdirname() -( +qdirname() ( _dirsplit "$1" dir=${_dirsplit_dir%/} echo "${dir:-.}" @@ -214,7 +221,7 @@ _realpath() path="${relto%/}/$path" fi ( - for d in $(seq 100); do + for d in $(_seq 100); do #echo "Trying: $PWD--$path" >&2 if cd -P "$path" 2>/dev/null; then # success @@ -269,7 +276,7 @@ _find_dofiles() dofile=$_dirsplit_base [ -n "$dodir" ] && dodir=${dodir%/}/ [ -e "$dodir$dofile" ] && return 0 - for i in $(seq 100); do + for i in $(_seq 100); do [ -n "$dodir" ] && dodir=${dodir%/}/ #echo "_find_dofiles: '$dodir' '$dofile'" >&2 _find_dofiles_pwd "$dodir" "$dofile" && return 0 From 1574b11598d4dce42fe174eaf406b6f130db02bb Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 25 Feb 2019 13:09:11 +0000 Subject: [PATCH 08/13] Precompiled headers: supply "-x c-header" or "-x c++-header" if available. Some older versions of gcc give "all.hpp: linker input file unused because linking not done" otherwise, because they don't realize files named *.hpp are headers. Reported-by: Wayne Scott --- redoconf/_compile.od | 5 +++-- redoconf/compile.od | 3 +++ redoconf/default.do.sh | 4 ++-- redoconf/rc/default.h.precompiled.rc.od | 11 +++++++++-- redoconf/rc/default.hpp.precompiled.rc.od | 13 ++++++++++--- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/redoconf/_compile.od b/redoconf/_compile.od index 4a237b9..856a065 100644 --- a/redoconf/_compile.od +++ b/redoconf/_compile.od @@ -6,9 +6,10 @@ cat >$3 <<-EOF t="\$1" d="\$2" i="\$3" IFS="$NL" set -f - \$CC -o "\$t" -c "\$i" \\ + \$CC -o "\$t" \\ -MMD -MF "\$d" \\ - \$CPPFLAGS \$CFLAGS \$CXXFLAGS \$FLAGS_PCH \$xCFLAGS \$OPTFLAGS + \$CPPFLAGS \$CFLAGS \$CXXFLAGS \$FLAGS_PCH \$xCFLAGS \$OPTFLAGS \\ + -c "\$i" EOF chmod a+x "$3" redo-stamp <$3 diff --git a/redoconf/compile.od b/redoconf/compile.od index f379ad8..79363bf 100644 --- a/redoconf/compile.od +++ b/redoconf/compile.od @@ -31,6 +31,7 @@ cat >$3 <<-EOF CXXFLAGS= PCH1=$(shquote "$CFLAGS_PCH") PCH2=$(shquote "$CFLAGS_PCH_FPIC") + PCH3=$(shquote "$CFLAGS_PCH_LANG") ;; *) CC=$(shquote "$CXX") @@ -39,11 +40,13 @@ cat >$3 <<-EOF CXXFLAGS=$(shquote "$CXXFLAGS") PCH1=$(shquote "$CXXFLAGS_PCH") PCH2=$(shquote "$CXXFLAGS_PCH_FPIC") + PCH3=$(shquote "$CXXFLAGS_PCH_LANG") ;; esac case \$PCH in 1) FLAGS_PCH=\$PCH1 ;; 2) FLAGS_PCH=\$PCH2 ;; + 3) FLAGS_PCH=\$PCH3 ;; esac . ./_compile EOF diff --git a/redoconf/default.do.sh b/redoconf/default.do.sh index 76cb10d..56a6b18 100644 --- a/redoconf/default.do.sh +++ b/redoconf/default.do.sh @@ -116,14 +116,14 @@ case $1 in ;; *.h.fpic.gch|*.hpp.fpic.gch) src="$S/${1%.fpic.gch}" - xCFLAGS="-fPIC" PCH="" dep="" compile "$@" + xCFLAGS="-fPIC" PCH="3" dep="" compile "$@" # precompiled header is "unchanged" if its component # headers are unchanged. cat ${deps#*:} | tee $1.stamp | redo-stamp ;; *.h.gch|*.hpp.gch) src="$S/${1%.gch}" - xCFLAGS="" PCH="" dep="" compile "$@" + xCFLAGS="" PCH="3" dep="" compile "$@" # precompiled header is "unchanged" if its component # headers are unchanged. cat ${deps#*:} | tee $1.stamp | redo-stamp diff --git a/redoconf/rc/default.h.precompiled.rc.od b/redoconf/rc/default.h.precompiled.rc.od index 0402169..66f4434 100644 --- a/redoconf/rc/default.h.precompiled.rc.od +++ b/redoconf/rc/default.h.precompiled.rc.od @@ -4,13 +4,20 @@ rc_include rc/CC.rc base="${1#rc/}" src="${base%.h.precompiled.rc}" +# Check whether the compiler supports forcing +# the language type. Some versions of gcc +# need this in order to precompile headers +# named *.hpp. +x="-x${NL}c-header" +if (appendln CFLAGS "$x" && rc_compile cc nolink); then + rc_appendln CFLAGS_PCH_LANG "$x" +fi + # The existence of the specific gcc warning about # precompiled headers is a pretty good indicator # that they are supported in the way we expect. rc_appendln CFLAGS "-Winvalid-pch" if rc_compile cc nolink; then - rc_appendln CFLAGS "$x" - rc_appendln CFLAGS_PCH "-include$NL$src.h" rc_appendln CFLAGS_PCH_FPIC "-include$NL$src.h.fpic" diff --git a/redoconf/rc/default.hpp.precompiled.rc.od b/redoconf/rc/default.hpp.precompiled.rc.od index 41fc712..d6ae4d4 100644 --- a/redoconf/rc/default.hpp.precompiled.rc.od +++ b/redoconf/rc/default.hpp.precompiled.rc.od @@ -4,13 +4,20 @@ rc_include rc/CXX.rc base="${1#rc/}" src="${base%.hpp.precompiled.rc}" +# Check whether the compiler supports forcing +# the language type. Some versions of gcc +# need this in order to precompile headers +# named *.hpp. +x="-x${NL}c++-header" +if (appendln CXXFLAGS "$x" && rc_compile cxx nolink); then + rc_appendln CXXFLAGS_PCH_LANG "$x" +fi + # The existence of the specific gcc warning about # precompiled headers is a pretty good indicator # that they are supported in the way we expect. -appendln CXXFLAGS "-Winvalid-pch" +rc_appendln CXXFLAGS "-Winvalid-pch" if rc_compile cxx nolink; then - rc_appendln CXXFLAGS "$x" - rc_appendln CXXFLAGS_PCH "-include$NL$src.hpp" rc_appendln CXXFLAGS_PCH_FPIC "-include$NL$src.hpp.fpic" From e036e2522d99cd279e4bd675089fcdbc75696957 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 25 Feb 2019 13:44:28 +0000 Subject: [PATCH 09/13] docs/cookbook/c/allconfig.do: avoid need for '&' backgrounding. Instead of running a bunch of separate rc_include statements in the background, which causes unpredictable ordering of log output and prevents -j from controlling parallelism, let's do a single redo-ifchange for all of them (the slow part) followed by sequentially checking the results (the fast part). --- docs/cookbook/c/allconfig.do | 41 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/cookbook/c/allconfig.do b/docs/cookbook/c/allconfig.do index 807a1c9..466c175 100644 --- a/docs/cookbook/c/allconfig.do +++ b/docs/cookbook/c/allconfig.do @@ -8,24 +8,35 @@ config() { ( cd "$dir" && ../configure --host="$arch" "$@" && - ( set --; - . ./redoconf.rc && - rc_include rc/CC.rc && - [ -n "$HAVE_CC" ] - ) && echo "$dir" - ) || (echo "Skipping arch '$arch' $*" >&2) + ) } -for d in $(cat arches); do - if [ "$d" = "native" ]; then - arch="" - else - arch="$d" - fi - config "out.$d" "$arch" & - config "out.$d.static" "$arch" "--enable-static" & - config "out.$d.opt" "$arch" "--enable-optimization" & +dirs=$( + for d in $(cat arches); do + if [ "$d" = "native" ]; then + arch="" + else + arch="$d" + fi + config "out.$d" "$arch" + config "out.$d.static" "$arch" "--enable-static" + config "out.$d.opt" "$arch" "--enable-optimization" + done +) + +for dir in $dirs; do + echo "$dir/rc/CC.rc" +done | xargs redo-ifchange + +for dir in $dirs; do + ( cd "$dir" && + set --; + . ./redoconf.rc && + rc_include rc/CC.rc && + [ -n "$HAVE_CC" ] && + echo "$dir" + ) || (echo "Skipping $dir' - no working C compiler." >&2) done >$3 wait From 1eb7b2879d30258c99e923634d078e83aad03f9d Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 25 Feb 2019 13:57:47 +0000 Subject: [PATCH 10/13] mkdocs: don't bother to include cookbook/c/out.*/ dirs. --- mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs.yml b/mkdocs.yml index 3f9834d..e8f86c9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -28,6 +28,7 @@ plugins: - cookbook/container/*.initrd - cookbook/container/*.layer - cookbook/container/*.list + - cookbook/c/out.* - "t/*" - "*.eps" - "*.gz" From 88250334da81fc9334323177157ef6fbd1699b33 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Fri, 1 Mar 2019 13:38:25 -0500 Subject: [PATCH 11/13] redoconf: move -Wl,-rpath flags to shlib.rc and add -Wl,-z,origin. It was kind of ugly to have this kind of special flag directly in link.od; now we detect whether it's available. This also gives a project the ability to override the flag in some other way if they want. As a result, rc/shlib.rc needs to be included in all.rc.od if you want to create or link against shared libraries. While we're here, also add -Wl,-z,origin on platforms where it works. This is apparently needed for FreeBSD 8.0 at least, and probably other platforms. Reported-by: Wayne Scott --- docs/cookbook/c/all.rc.od | 1 + redoconf/link-shlib.od | 8 +++++++- redoconf/link.od | 1 - redoconf/rc/shlib.rc.od | 20 ++++++++++++++++---- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/cookbook/c/all.rc.od b/docs/cookbook/c/all.rc.od index 22b35b0..f206e7f 100644 --- a/docs/cookbook/c/all.rc.od +++ b/docs/cookbook/c/all.rc.od @@ -2,6 +2,7 @@ rc_include \ rc/CC.required.rc \ rc/CXX.rc \ + rc/shlib.rc \ rc/libqt4.rc \ rc/libgtk2.rc \ rc/Wextra.rc \ diff --git a/redoconf/link-shlib.od b/redoconf/link-shlib.od index aa632f0..239762c 100644 --- a/redoconf/link-shlib.od +++ b/redoconf/link-shlib.od @@ -1,5 +1,5 @@ . ./redoconf.rc -rc_include _all.rc rc/shlib.rc +rc_include _all.rc # Tricky quoting: see _compile.od for details. if [ "$HAVE_SHLIB" = UNIX ]; then @@ -40,6 +40,12 @@ elif [ "$HAVE_SHLIB" = MACOS ]; then \$LIBS EOF else + if [ -z "$HAVE_SHLIB" ]; then + echo "link-shlib.od: fatal:" \ + "must include rc/shlib.rc to use shared libraries." >&2 + exit 90 + fi + # If no shared library support and we try to build one, # compensate by building a static library instead in the # same place. diff --git a/redoconf/link.od b/redoconf/link.od index e416539..41912ea 100644 --- a/redoconf/link.od +++ b/redoconf/link.od @@ -13,7 +13,6 @@ cat >$3 <<-EOF IFS="$NL" set -f \$LINK -o "\$o" \\ - -Wl,-rpath,'\$ORIGIN' \\ \$LDFLAGS \$OPTFLAGS \\ "\$@" \\ \$LIBS diff --git a/redoconf/rc/shlib.rc.od b/redoconf/rc/shlib.rc.od index 20211b4..6944118 100644 --- a/redoconf/rc/shlib.rc.od +++ b/redoconf/rc/shlib.rc.od @@ -27,17 +27,29 @@ try_macos_style() { if [ -n "$STATIC" ]; then echo "--enable-static specified; not building shared libraries." >&2 - rc_replaceln HAVE_SHLIB "" + rc_replaceln HAVE_SHLIB "STATIC" elif [ -n "$NOSHARED" ]; then echo "--disable-shared specified; not building shared libraries." >&2 - rc_replaceln HAVE_SHLIB "" + rc_replaceln HAVE_SHLIB "STATIC" elif try_unix_style; then rc_replaceln HAVE_SHLIB UNIX elif try_macos_style; then rc_replaceln HAVE_SHLIB MACOS else echo "Not building shared libraries on this platform." >&2 - rc_undo - rc_replaceln HAVE_SHLIB "" + rc_replaceln HAVE_SHLIB "STATIC" fi + +if [ "$HAVE_SHLIB" != "STATIC" ]; then + x='-Wl,-z,origin' + if (appendln LDFLAGS "$x" && rc_compile cc link); then + rc_appendln LDFLAGS "$x" + fi + + x='-Wl,-rpath,$ORIGIN' + if (appendln LDFLAGS "$x" && rc_compile cc link); then + rc_appendln LDFLAGS "$x" + fi +fi + rc_save From 49f85f2156bc5f134dedb74f768fd1b17fb8195e Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 2 Mar 2019 04:12:25 -0500 Subject: [PATCH 12/13] redoconf: assorted minor fixes. - libqt4.rc: add detection of the 'moc' command in $MOC. - libssl.rc: add detection script for openssl. - default.do.sh: provide a die() function to all .od files. It's just too useful to not have it (I haven't converted everything to it yet). - When building out/x/y.z, match against $S/default.z.od and $S/default.od if they exist. - *.list files (lists of source/object files to include in a binary) can now contain *.o files in addition to *.c, *.cc, etc. - rename compile() to _compile() to avoid polluting the namespace for scripts called from default.do.sh. - When building a .so file in the top level directory, no need to make a symlink of it into the top level directory. - link.od and link-shlib.od forgot to make use of the $xLIBS variable. --- docs/cookbook/c/configure.help | 2 +- redoconf/default.do.sh | 57 +++++++++++++++++++++++----------- redoconf/link-shlib.od | 4 +-- redoconf/link.od | 2 +- redoconf/rc/libqt4.rc.od | 10 +++++- redoconf/rc/libssl.rc.od | 10 ++++++ 6 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 redoconf/rc/libssl.rc.od diff --git a/docs/cookbook/c/configure.help b/docs/cookbook/c/configure.help index ca36761..85eeee9 100644 --- a/docs/cookbook/c/configure.help +++ b/docs/cookbook/c/configure.help @@ -10,7 +10,7 @@ LIBS Extra libraries to always link against (eg. -lsocket) STATIC Link libraries and binaries statically CXX C++ compiler name (c++) CXXFLAGS Extra C++ compiler flags (eg. -O2 -g) -LIBQT4 Extra linker options for 'QtCore' +LIBQT4 Extra linker options for 'QtGui' LIBGTK2 Extra linker options for 'gtk+-2.0 gio-2.0 gdk-2.0 gdk-pixbuf-2.0' LIBM Extra linker options for 'libm' LIBPNG Extra linker options for 'libpng' diff --git a/redoconf/default.do.sh b/redoconf/default.do.sh index 56a6b18..91f91c7 100644 --- a/redoconf/default.do.sh +++ b/redoconf/default.do.sh @@ -9,6 +9,11 @@ fi NL=" " +die() { + echo Error: "$@" >&2 + exit 99 +} + _mkdir_of() { local dir="${1%/*}" [ "$dir" = "$1" ] || @@ -23,8 +28,10 @@ _dir1=${1%"$_base1"} _missing="" for d in "$S/$1.od" \ "$S/${_dir1}default.${_base1#*.}.od" \ + "$S/default.${_base1#*.}.od" \ "$REDOCONF/$1.od" \ - "$REDOCONF/${_dir1}default.${_base1#*.}.od"; do + "$REDOCONF/${_dir1}default.${_base1#*.}.od" \ + "$REDOCONF/default.${_base1#*.}.od"; do if [ -e "$d" ]; then redo-ifchange "$d" _mkdir_of "$3" @@ -60,7 +67,7 @@ _pick_src() { [ -e "$src.do" ] && return missing="$missing$NL$src" done - echo "default.do.sh: _pick_src: no source file found for '$1.*'" >&2 + die "default.do.sh: _pick_src: no source file found for '$1.*'" return 1 } @@ -71,7 +78,7 @@ _objlist() { while read -r d; do case $d in -*) ;; - *.c|*.cc|*.cpp|*.cxx|*.C|*.c++) + *.c|*.cc|*.cpp|*.cxx|*.C|*.c++|*.o) echo "$dir${d%.*}$suffix" ;; *) echo "$dir$d" ;; @@ -86,7 +93,7 @@ _flaglist() { done <"$1" } -compile() { +_compile() { redo-ifchange compile "$src" $dep rm -f "$1.deps" _mkdir_of "$3" @@ -101,29 +108,41 @@ compile() { redo-ifchange ${deps#*:} } +_link() { + ( + local o="$1" listf="$2" + redo-ifchange link "$listf" + files=$(_objlist .o "$listf") + xLIBS=$(_flaglist "$listf") + IFS="$NL" + redo-ifchange $files + xLIBS="$xLIBS" ./link "$o" $files + ) +} + case $1 in *.fpic.o) _pick_src "$S/${1%.fpic.o}" _add_missing - xCFLAGS="-fPIC" PCH="2" dep="$lang-fpic.precompile" compile "$@" + xCFLAGS="-fPIC" PCH="2" dep="$lang-fpic.precompile" _compile "$@" exit # fast path: exit as early as possible ;; *.o) _pick_src "$S/${1%.o}" _add_missing - xCFLAGS="" PCH="1" dep="$lang.precompile" compile "$@" + xCFLAGS="" PCH="1" dep="$lang.precompile" _compile "$@" exit # fast path: exit as early as possible ;; *.h.fpic.gch|*.hpp.fpic.gch) src="$S/${1%.fpic.gch}" - xCFLAGS="-fPIC" PCH="3" dep="" compile "$@" + xCFLAGS="-fPIC" PCH="3" dep="" _compile "$@" # precompiled header is "unchanged" if its component # headers are unchanged. cat ${deps#*:} | tee $1.stamp | redo-stamp ;; *.h.gch|*.hpp.gch) src="$S/${1%.gch}" - xCFLAGS="" PCH="3" dep="" compile "$@" + xCFLAGS="" PCH="3" dep="" _compile "$@" # precompiled header is "unchanged" if its component # headers are unchanged. cat ${deps#*:} | tee $1.stamp | redo-stamp @@ -146,8 +165,9 @@ case $1 in IFS="$NL" redo-ifchange $files xLIBS="$xLIBS" ./link-shlib "$1.$ver" $files - ln -s "$(basename "$1.$ver")" "$3" - ln -sf "$1.$ver" . + bname="$(basename "$1.$ver")" + ln -s "$bname" "$3" + [ "$1.$ver" = "$bname" ] || ln -sf "$1.$ver" . ;; *.list|*.ver) if [ -e "$S/$1" ]; then @@ -155,7 +175,7 @@ case $1 in _mkdir_of "$3" cp "$S/$1" "$3" else - echo "default.do.sh: no rule to build '$1'" >&2 + die "default.do.sh: no rule to build '$1'" exit 99 fi ;; @@ -172,14 +192,15 @@ case $1 in bin="${1%.exe}" if [ -e "$S/$bin.list" -o -e "$S/$bin.list.od" ]; then # a final program binary - redo-ifchange link "$bin.list" - files=$(_objlist .o "$bin.list") - xLIBS=$(_flaglist "$bin.list") - IFS="$NL" - redo-ifchange $files - xLIBS="$xLIBS" ./link "$3" $files + _link "$3" "$bin.list" + elif [ -e "$S/default.od" ]; then + d="$S/default.od" + redo-ifchange "$d" + _mkdir_of "$3" + ( PS4="$PS4[$d] "; . "$d" ) + exit else - echo "default.do.sh: no rule to build '$1' or '$1.list'" >&2 + die "default.do.sh: no rule to build '$1' or '$1.list'" exit 99 fi ;; diff --git a/redoconf/link-shlib.od b/redoconf/link-shlib.od index 239762c..a3e3896 100644 --- a/redoconf/link-shlib.od +++ b/redoconf/link-shlib.od @@ -18,7 +18,7 @@ if [ "$HAVE_SHLIB" = UNIX ]; then -Wl,-soname,"\$ob" \\ \$LDFLAGS \$OPTFLAGS \\ "\$@" \\ - \$LIBS + \$xLIBS \$LIBS EOF elif [ "$HAVE_SHLIB" = MACOS ]; then cat >$3 <<-EOF @@ -37,7 +37,7 @@ elif [ "$HAVE_SHLIB" = MACOS ]; then -install_name "\$ob" \\ \$LDFLAGS \$OPTFLAGS \\ "\$@" \\ - \$LIBS + \$xLIBS \$LIBS EOF else if [ -z "$HAVE_SHLIB" ]; then diff --git a/redoconf/link.od b/redoconf/link.od index 41912ea..765040c 100644 --- a/redoconf/link.od +++ b/redoconf/link.od @@ -15,7 +15,7 @@ cat >$3 <<-EOF \$LINK -o "\$o" \\ \$LDFLAGS \$OPTFLAGS \\ "\$@" \\ - \$LIBS + \$xLIBS \$LIBS EOF chmod a+x "$3" redo-stamp <$3 diff --git a/redoconf/rc/libqt4.rc.od b/redoconf/rc/libqt4.rc.od index e7a02eb..0169176 100644 --- a/redoconf/rc/libqt4.rc.od +++ b/redoconf/rc/libqt4.rc.od @@ -5,6 +5,14 @@ prog=' #include ' -rc_pkg_detect LIBQT4 QtCore \ +rc_pkg_detect LIBQT4 QtGui \ rc_compile cxx link "$prog" + +for d in "$MOC" moc-qt4 moc; do + if type "$d" >/dev/null 2>&1; then + rc_replaceln MOC "$d" + break + fi +done + rc_save diff --git a/redoconf/rc/libssl.rc.od b/redoconf/rc/libssl.rc.od new file mode 100644 index 0000000..ca3a581 --- /dev/null +++ b/redoconf/rc/libssl.rc.od @@ -0,0 +1,10 @@ +. ./redoconf.rc +rc_include rc/CC.rc rc/pkg-config.rc + +prog=" +#include +" + +rc_pkg_detect LIBSSL "libssl libcrypto" \ + rc_compile cc link "$prog" +rc_save From 1a3c11f2207736f9ce7f2b69639c13269770dd9c Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Sat, 2 Mar 2019 04:23:05 -0500 Subject: [PATCH 13/13] redoconf: a stub rc_include() now sources ./redoconf.rc automatically. This lets us remove the awkward ". ./redoconf.rc" line from zillions of .od scripts, without paying the price of *always* including that whole file every time default.do.sh is used. --- docs/cookbook/c/all.rc.od | 1 - docs/cookbook/c/flagtest.o.od | 1 - docs/cookbook/c/hello world.list.od | 1 - docs/cookbook/c/rc/clock_gettime.rc.od | 1 - docs/cookbook/c/rc/extra.rc.od | 1 - docs/cookbook/c/rc/posix.rc.od | 1 - docs/cookbook/c/rc/printf_lld.rc.od | 1 - redoconf/compile.od | 1 - redoconf/default.do.sh | 5 +++++ redoconf/default.precompile.od | 1 - redoconf/link-shlib.od | 1 - redoconf/link.od | 1 - redoconf/rc/CC.rc.od | 1 - redoconf/rc/CXX.rc.od | 1 - redoconf/rc/Wall.rc.od | 1 - redoconf/rc/Wextra.rc.od | 1 - redoconf/rc/default.autolib.rc.od | 1 - redoconf/rc/default.h.precompiled.rc.od | 1 - redoconf/rc/default.h.rc.od | 1 - redoconf/rc/default.hpp.precompiled.rc.od | 1 - redoconf/rc/default.required.rc.od | 2 -- redoconf/rc/libgl.rc.od | 1 - redoconf/rc/libgtk2.rc.od | 1 - redoconf/rc/libm.rc.od | 1 - redoconf/rc/libpng.rc.od | 1 - redoconf/rc/libqt4.rc.od | 1 - redoconf/rc/libsdl.rc.od | 1 - redoconf/rc/libssl.rc.od | 1 - redoconf/rc/libx11.rc.od | 1 - redoconf/rc/pkg-config.rc.od | 1 - redoconf/rc/run.rc.od | 1 - redoconf/rc/shlib.rc.od | 1 - redoconf/rc/zdefs.rc.od | 1 - redoconf/run.od | 1 - 34 files changed, 5 insertions(+), 34 deletions(-) diff --git a/docs/cookbook/c/all.rc.od b/docs/cookbook/c/all.rc.od index f206e7f..7caf52c 100644 --- a/docs/cookbook/c/all.rc.od +++ b/docs/cookbook/c/all.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include \ rc/CC.required.rc \ rc/CXX.rc \ diff --git a/docs/cookbook/c/flagtest.o.od b/docs/cookbook/c/flagtest.o.od index 67b5c88..57b9536 100644 --- a/docs/cookbook/c/flagtest.o.od +++ b/docs/cookbook/c/flagtest.o.od @@ -1,7 +1,6 @@ # Demonstrate how to compile .o files using nonstandard # compiler flags. You could also do this for a whole # directory using default.o.od. -. ./redoconf.rc rc_include all.rc src="$S/${1%.o}.c" diff --git a/docs/cookbook/c/hello world.list.od b/docs/cookbook/c/hello world.list.od index cb5548b..6f5078e 100644 --- a/docs/cookbook/c/hello world.list.od +++ b/docs/cookbook/c/hello world.list.od @@ -1,6 +1,5 @@ # This script is run from the output dir. # The source dir is at $S. -. ./redoconf.rc rc_include all.rc redo-ifchange "$S/sources" diff --git a/docs/cookbook/c/rc/clock_gettime.rc.od b/docs/cookbook/c/rc/clock_gettime.rc.od index 85a3307..b420fc2 100644 --- a/docs/cookbook/c/rc/clock_gettime.rc.od +++ b/docs/cookbook/c/rc/clock_gettime.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/rt.autolib.rc rc/posix.rc prog=" diff --git a/docs/cookbook/c/rc/extra.rc.od b/docs/cookbook/c/rc/extra.rc.od index 1075a71..da49273 100644 --- a/docs/cookbook/c/rc/extra.rc.od +++ b/docs/cookbook/c/rc/extra.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc_appendln CPPFLAGS "-DEXTRA_RC_INCLUDED=1" diff --git a/docs/cookbook/c/rc/posix.rc.od b/docs/cookbook/c/rc/posix.rc.od index b33cb21..e992b0f 100644 --- a/docs/cookbook/c/rc/posix.rc.od +++ b/docs/cookbook/c/rc/posix.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc prog=' diff --git a/docs/cookbook/c/rc/printf_lld.rc.od b/docs/cookbook/c/rc/printf_lld.rc.od index dd1650e..35a6e6b 100644 --- a/docs/cookbook/c/rc/printf_lld.rc.od +++ b/docs/cookbook/c/rc/printf_lld.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/windows.h.rc rc/Wall.rc appendln CPPFLAGS "-Werror" # abort if any warnings diff --git a/redoconf/compile.od b/redoconf/compile.od index 79363bf..5cbecfc 100644 --- a/redoconf/compile.od +++ b/redoconf/compile.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include _all.rc redo-ifchange _compile diff --git a/redoconf/default.do.sh b/redoconf/default.do.sh index 91f91c7..1d7ef52 100644 --- a/redoconf/default.do.sh +++ b/redoconf/default.do.sh @@ -14,6 +14,11 @@ die() { exit 99 } +rc_include() { + . ./redoconf.rc || exit 1 # redefines rc_include + rc_include "$@" +} + _mkdir_of() { local dir="${1%/*}" [ "$dir" = "$1" ] || diff --git a/redoconf/default.precompile.od b/redoconf/default.precompile.od index b52eb24..de73ce1 100644 --- a/redoconf/default.precompile.od +++ b/redoconf/default.precompile.od @@ -4,7 +4,6 @@ # Notably, we have to precompile any precompiled # headers. We also generate redoconf.h in case # programs want to include it. -. ./redoconf.rc rc_include _all.rc case ${1%.precompile} in diff --git a/redoconf/link-shlib.od b/redoconf/link-shlib.od index a3e3896..b1f8feb 100644 --- a/redoconf/link-shlib.od +++ b/redoconf/link-shlib.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include _all.rc # Tricky quoting: see _compile.od for details. diff --git a/redoconf/link.od b/redoconf/link.od index 765040c..d00c4ed 100644 --- a/redoconf/link.od +++ b/redoconf/link.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include _all.rc # Tricky quoting: see _compile.od for details. diff --git a/redoconf/rc/CC.rc.od b/redoconf/rc/CC.rc.od index 03605cd..88f22f3 100644 --- a/redoconf/rc/CC.rc.od +++ b/redoconf/rc/CC.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc_helpmsg ARCH "Architecture prefix for output (eg. i686-w64-mingw32-)" diff --git a/redoconf/rc/CXX.rc.od b/redoconf/rc/CXX.rc.od index c6875c9..1d15835 100644 --- a/redoconf/rc/CXX.rc.od +++ b/redoconf/rc/CXX.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc_helpmsg CXX "C++ compiler name (c++)" diff --git a/redoconf/rc/Wall.rc.od b/redoconf/rc/Wall.rc.od index 35d3b36..5505178 100644 --- a/redoconf/rc/Wall.rc.od +++ b/redoconf/rc/Wall.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc_appendln CPPFLAGS "-Wall" diff --git a/redoconf/rc/Wextra.rc.od b/redoconf/rc/Wextra.rc.od index ec6cd3e..1d843fd 100644 --- a/redoconf/rc/Wextra.rc.od +++ b/redoconf/rc/Wextra.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc_appendln CPPFLAGS "-Wextra" diff --git a/redoconf/rc/default.autolib.rc.od b/redoconf/rc/default.autolib.rc.od index 53281c8..00dd7f2 100644 --- a/redoconf/rc/default.autolib.rc.od +++ b/redoconf/rc/default.autolib.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc base="${1#*/}" diff --git a/redoconf/rc/default.h.precompiled.rc.od b/redoconf/rc/default.h.precompiled.rc.od index 66f4434..9742fea 100644 --- a/redoconf/rc/default.h.precompiled.rc.od +++ b/redoconf/rc/default.h.precompiled.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc base="${1#rc/}" diff --git a/redoconf/rc/default.h.rc.od b/redoconf/rc/default.h.rc.od index 6df73cb..7ca7cf0 100644 --- a/redoconf/rc/default.h.rc.od +++ b/redoconf/rc/default.h.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc base="${1#*/}" diff --git a/redoconf/rc/default.hpp.precompiled.rc.od b/redoconf/rc/default.hpp.precompiled.rc.od index d6ae4d4..ba1ae5a 100644 --- a/redoconf/rc/default.hpp.precompiled.rc.od +++ b/redoconf/rc/default.hpp.precompiled.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CXX.rc base="${1#rc/}" diff --git a/redoconf/rc/default.required.rc.od b/redoconf/rc/default.required.rc.od index 157aee8..989be5e 100644 --- a/redoconf/rc/default.required.rc.od +++ b/redoconf/rc/default.required.rc.od @@ -1,5 +1,3 @@ -. ./redoconf.rc - base=${1%.required.rc} name=${base#*/} NAME=$(echo "$name" | tr 'a-z.' 'A-Z_') diff --git a/redoconf/rc/libgl.rc.od b/redoconf/rc/libgl.rc.od index 5a98829..7d9a46c 100644 --- a/redoconf/rc/libgl.rc.od +++ b/redoconf/rc/libgl.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/libgtk2.rc.od b/redoconf/rc/libgtk2.rc.od index f8f55e1..1b3bf97 100644 --- a/redoconf/rc/libgtk2.rc.od +++ b/redoconf/rc/libgtk2.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/libm.rc.od b/redoconf/rc/libm.rc.od index 87cc3ed..5c5ff59 100644 --- a/redoconf/rc/libm.rc.od +++ b/redoconf/rc/libm.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/libpng.rc.od b/redoconf/rc/libpng.rc.od index 43a11c6..6a678c5 100644 --- a/redoconf/rc/libpng.rc.od +++ b/redoconf/rc/libpng.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/libqt4.rc.od b/redoconf/rc/libqt4.rc.od index 0169176..c60f4c3 100644 --- a/redoconf/rc/libqt4.rc.od +++ b/redoconf/rc/libqt4.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CXX.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/libsdl.rc.od b/redoconf/rc/libsdl.rc.od index 1494d07..f4cfc58 100644 --- a/redoconf/rc/libsdl.rc.od +++ b/redoconf/rc/libsdl.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/libssl.rc.od b/redoconf/rc/libssl.rc.od index ca3a581..1f608d1 100644 --- a/redoconf/rc/libssl.rc.od +++ b/redoconf/rc/libssl.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=" diff --git a/redoconf/rc/libx11.rc.od b/redoconf/rc/libx11.rc.od index 7450467..c61f71a 100644 --- a/redoconf/rc/libx11.rc.od +++ b/redoconf/rc/libx11.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/pkg-config.rc prog=' diff --git a/redoconf/rc/pkg-config.rc.od b/redoconf/rc/pkg-config.rc.od index 6c3f0cc..a96a893 100644 --- a/redoconf/rc/pkg-config.rc.od +++ b/redoconf/rc/pkg-config.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include for d in "$PKG_CONFIG" pkg-config; do diff --git a/redoconf/rc/run.rc.od b/redoconf/rc/run.rc.od index 6f3f82f..142e3ba 100644 --- a/redoconf/rc/run.rc.od +++ b/redoconf/rc/run.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc rc/windows.h.rc consider() { diff --git a/redoconf/rc/shlib.rc.od b/redoconf/rc/shlib.rc.od index 6944118..030c31e 100644 --- a/redoconf/rc/shlib.rc.od +++ b/redoconf/rc/shlib.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc prog=' diff --git a/redoconf/rc/zdefs.rc.od b/redoconf/rc/zdefs.rc.od index 7684a5f..ce81ab4 100644 --- a/redoconf/rc/zdefs.rc.od +++ b/redoconf/rc/zdefs.rc.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/CC.rc x="-Wl,-z,defs" diff --git a/redoconf/run.od b/redoconf/run.od index 104b0c1..8ac58d5 100644 --- a/redoconf/run.od +++ b/redoconf/run.od @@ -1,4 +1,3 @@ -. ./redoconf.rc rc_include rc/run.rc if [ -n "$CAN_RUN" ]; then