Merge branch 'redoconf'
* redoconf: redoconf: a stub rc_include() now sources ./redoconf.rc automatically. redoconf: assorted minor fixes. redoconf: move -Wl,-rpath flags to shlib.rc and add -Wl,-z,origin. mkdocs: don't bother to include cookbook/c/out.*/ dirs. docs/cookbook/c/allconfig.do: avoid need for '&' backgrounding. Precompiled headers: supply "-x c-header" or "-x c++-header" if available. minimal/do: remove dependency on 'seq' command. Fix some build problems on MacOS X. redoconf: posix.rc: fix abort when timespec is not available. redoconf: better handling of required vs optional detectors. redoconf: clock_gettime() detection needs to depend on -lrt. redoconf: avoid sed -E in _objlist(). Experimental new redoconf C/C++ build/autoconfiguration system.
This commit is contained in:
commit
3071d13416
72 changed files with 1928 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
7
docs/cookbook/c/.gitignore
vendored
Normal file
7
docs/cookbook/c/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
hello
|
||||
/when.c
|
||||
/allconfig
|
||||
/arches
|
||||
/out
|
||||
/out.*
|
||||
/sources
|
||||
1
docs/cookbook/c/all.do
Normal file
1
docs/cookbook/c/all.do
Normal file
|
|
@ -0,0 +1 @@
|
|||
redo-ifchange all.each
|
||||
4
docs/cookbook/c/all.h
Normal file
4
docs/cookbook/c/all.h
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "main.h"
|
||||
#include "libhello/hello.h"
|
||||
#include "monotime.h"
|
||||
#include <stdio.h>
|
||||
4
docs/cookbook/c/all.hpp
Normal file
4
docs/cookbook/c/all.hpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
1
docs/cookbook/c/all.od
Normal file
1
docs/cookbook/c/all.od
Normal file
|
|
@ -0,0 +1 @@
|
|||
redo-ifchange "hello world"
|
||||
23
docs/cookbook/c/all.rc.od
Normal file
23
docs/cookbook/c/all.rc.od
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
rc_include \
|
||||
rc/CC.required.rc \
|
||||
rc/CXX.rc \
|
||||
rc/shlib.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.rc \
|
||||
rc/mach__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
|
||||
42
docs/cookbook/c/allconfig.do
Normal file
42
docs/cookbook/c/allconfig.do
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
redo-ifchange arches configure redoconf/utils.sh
|
||||
|
||||
config() {
|
||||
local dir="$1" arch="$2"
|
||||
shift
|
||||
shift
|
||||
[ -d "$dir" ] || mkdir "$dir"
|
||||
(
|
||||
cd "$dir" &&
|
||||
../configure --host="$arch" "$@" &&
|
||||
echo "$dir"
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
16
docs/cookbook/c/arches.do
Normal file
16
docs/cookbook/c/arches.do
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(
|
||||
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
|
||||
fi
|
||||
) >$3
|
||||
redo-always
|
||||
redo-stamp <$3
|
||||
2
docs/cookbook/c/clean.do
Normal file
2
docs/cookbook/c/clean.do
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
rm -rf out out.*
|
||||
rm -f *~ .*~ */*~ */.*~ sources arches allconfig when.c
|
||||
6
docs/cookbook/c/clean.od
Normal file
6
docs/cookbook/c/clean.od
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# runs from the output directory
|
||||
rm -f *~ .*~ *.rc *.log *.gch *.stamp \
|
||||
*.[oa] *.deps \
|
||||
*.so *.so.* *.ver \
|
||||
*.exe *.list \
|
||||
hello
|
||||
3
docs/cookbook/c/configure
vendored
Executable file
3
docs/cookbook/c/configure
vendored
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
S="$(dirname "$0")"
|
||||
. "$S/redoconf/configure.sh"
|
||||
17
docs/cookbook/c/configure.help
Normal file
17
docs/cookbook/c/configure.help
Normal file
|
|
@ -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 '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'
|
||||
PREFIX Change installation prefix (usually /usr/local)
|
||||
10
docs/cookbook/c/default.each.do
Normal file
10
docs/cookbook/c/default.each.do
Normal file
|
|
@ -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
|
||||
10
docs/cookbook/c/flagtest.c
Normal file
10
docs/cookbook/c/flagtest.c
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#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");
|
||||
}
|
||||
8
docs/cookbook/c/flagtest.o.od
Normal file
8
docs/cookbook/c/flagtest.o.od
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Demonstrate how to compile .o files using nonstandard
|
||||
# compiler flags. You could also do this for a whole
|
||||
# directory using default.o.od.
|
||||
rc_include all.rc
|
||||
|
||||
src="$S/${1%.o}.c"
|
||||
redo-ifchange "_compile" "$src"
|
||||
CC="$CC" CPPFLAGS="-DFLAGTEST_SET=42" ./_compile "$3" "$1.deps" "$src"
|
||||
28
docs/cookbook/c/hello world.list.od
Normal file
28
docs/cookbook/c/hello world.list.od
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# This script is run from the output dir.
|
||||
# The source dir is at $S.
|
||||
rc_include all.rc
|
||||
redo-ifchange "$S/sources"
|
||||
|
||||
(
|
||||
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-stamp <$3
|
||||
6
docs/cookbook/c/libhello/hello.c
Normal file
6
docs/cookbook/c/libhello/hello.c
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "hello.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void hello(void) {
|
||||
printf("Hello, world!\n");
|
||||
}
|
||||
6
docs/cookbook/c/libhello/hello.h
Normal file
6
docs/cookbook/c/libhello/hello.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __HELLO_H
|
||||
#define __HELLO_H
|
||||
|
||||
void hello(void);
|
||||
|
||||
#endif /* __HELLO_H */
|
||||
1
docs/cookbook/c/libhello/lib hello.list
Normal file
1
docs/cookbook/c/libhello/lib hello.list
Normal file
|
|
@ -0,0 +1 @@
|
|||
hello.c
|
||||
1
docs/cookbook/c/libhello/lib hello.ver
Normal file
1
docs/cookbook/c/libhello/lib hello.ver
Normal file
|
|
@ -0,0 +1 @@
|
|||
1.2.5
|
||||
22
docs/cookbook/c/main.c
Normal file
22
docs/cookbook/c/main.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "main.h"
|
||||
#include "libhello/hello.h"
|
||||
#include "monotime.h"
|
||||
#include "redoconf.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
19
docs/cookbook/c/main.h
Normal file
19
docs/cookbook/c/main.h
Normal file
|
|
@ -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 */
|
||||
58
docs/cookbook/c/monotime.c
Normal file
58
docs/cookbook/c/monotime.c
Normal file
|
|
@ -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 <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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__MACH_TIME_H
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
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 <windows.h>
|
||||
|
||||
/* 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
|
||||
6
docs/cookbook/c/monotime.h
Normal file
6
docs/cookbook/c/monotime.h
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef __MONOTIME_H
|
||||
#define __MONOTIME_H
|
||||
|
||||
long long monotime(void);
|
||||
|
||||
#endif /* __MONOTIME_H */
|
||||
16
docs/cookbook/c/rc/clock_gettime.rc.od
Normal file
16
docs/cookbook/c/rc/clock_gettime.rc.od
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
rc_include rc/CC.rc rc/rt.autolib.rc rc/posix.rc
|
||||
|
||||
prog="
|
||||
#include <time.h>
|
||||
|
||||
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
|
||||
4
docs/cookbook/c/rc/extra.rc.od
Normal file
4
docs/cookbook/c/rc/extra.rc.od
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
rc_include
|
||||
|
||||
rc_appendln CPPFLAGS "-DEXTRA_RC_INCLUDED=1"
|
||||
rc_save
|
||||
19
docs/cookbook/c/rc/posix.rc.od
Normal file
19
docs/cookbook/c/rc/posix.rc.od
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
rc_include rc/CC.rc
|
||||
|
||||
prog='
|
||||
#include <time.h>
|
||||
|
||||
struct timespec x;
|
||||
'
|
||||
|
||||
x=
|
||||
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 HAVE_POSIX ""
|
||||
fi
|
||||
fi
|
||||
rc_save
|
||||
15
docs/cookbook/c/rc/printf_lld.rc.od
Normal file
15
docs/cookbook/c/rc/printf_lld.rc.od
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
rc_include rc/CC.rc rc/windows.h.rc rc/Wall.rc
|
||||
|
||||
appendln CPPFLAGS "-Werror" # abort if any warnings
|
||||
prog='
|
||||
#include <stdio.h>
|
||||
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
|
||||
1
docs/cookbook/c/redoconf
Symbolic link
1
docs/cookbook/c/redoconf
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../../redoconf
|
||||
10
docs/cookbook/c/slow.cc
Normal file
10
docs/cookbook/c/slow.cc
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "main.h"
|
||||
|
||||
int cpp_test() {
|
||||
std::string a = "hello ", b = "world";
|
||||
return a.length() + b.length();
|
||||
}
|
||||
12
docs/cookbook/c/sources.do
Normal file
12
docs/cookbook/c/sources.do
Normal file
|
|
@ -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
|
||||
1
docs/cookbook/c/test.do
Normal file
1
docs/cookbook/c/test.do
Normal file
|
|
@ -0,0 +1 @@
|
|||
redo-ifchange test.each
|
||||
16
docs/cookbook/c/test.od
Normal file
16
docs/cookbook/c/test.od
Normal file
|
|
@ -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
|
||||
7
docs/cookbook/c/when.c.do
Normal file
7
docs/cookbook/c/when.c.do
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
cat >$3 <<-EOF
|
||||
const char *stamp_time(void) {
|
||||
return "$(date +%Y-%m-%d)";
|
||||
}
|
||||
EOF
|
||||
redo-always
|
||||
redo-stamp <$3
|
||||
|
|
@ -28,6 +28,7 @@ plugins:
|
|||
- cookbook/container/*.initrd
|
||||
- cookbook/container/*.layer
|
||||
- cookbook/container/*.list
|
||||
- cookbook/c/out.*
|
||||
- "t/*"
|
||||
- "*.eps"
|
||||
- "*.gz"
|
||||
|
|
|
|||
51
redoconf/_all.rc.od
Normal file
51
redoconf/_all.rc.od
Normal file
|
|
@ -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"
|
||||
15
redoconf/_compile.od
Normal file
15
redoconf/_compile.od
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# 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" \\
|
||||
-MMD -MF "\$d" \\
|
||||
\$CPPFLAGS \$CFLAGS \$CXXFLAGS \$FLAGS_PCH \$xCFLAGS \$OPTFLAGS \\
|
||||
-c "\$i"
|
||||
EOF
|
||||
chmod a+x "$3"
|
||||
redo-stamp <$3
|
||||
53
redoconf/compile.od
Normal file
53
redoconf/compile.od
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
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")
|
||||
PCH3=$(shquote "$CFLAGS_PCH_LANG")
|
||||
;;
|
||||
*)
|
||||
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")
|
||||
PCH3=$(shquote "$CXXFLAGS_PCH_LANG")
|
||||
;;
|
||||
esac
|
||||
case \$PCH in
|
||||
1) FLAGS_PCH=\$PCH1 ;;
|
||||
2) FLAGS_PCH=\$PCH2 ;;
|
||||
3) FLAGS_PCH=\$PCH3 ;;
|
||||
esac
|
||||
. ./_compile
|
||||
EOF
|
||||
chmod a+x "$3"
|
||||
redo-stamp <$3
|
||||
204
redoconf/configure.sh
Normal file
204
redoconf/configure.sh
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
#!/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 <src
|
||||
. "\$S/redoconf/rc.sh"
|
||||
EOF
|
||||
|
||||
# Instead of a symlink, we could make this a script like redoconf.rc,
|
||||
# except then we would have to redi-ifchange default.do.sh, which would
|
||||
# greatly increase the number of calls to redo-ifchange in the fast path.
|
||||
# That turns out to slow things down quite a bit. So let redo follow
|
||||
# the symlink and note the dependency internally, which is faster.
|
||||
[ -e default.do ] || ln -sf "$S/redoconf/default.do.sh" default.do
|
||||
|
||||
cat >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 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
|
||||
'
|
||||
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"
|
||||
;;
|
||||
--disable-shared)
|
||||
emit "NOSHARED" "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-<key>=<value>'" >&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
|
||||
212
redoconf/default.do.sh
Normal file
212
redoconf/default.do.sh
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
# This script starts with $PWD=output dir, $S=input dir.
|
||||
read -r S <src
|
||||
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
|
||||
|
||||
NL="
|
||||
"
|
||||
|
||||
die() {
|
||||
echo Error: "$@" >&2
|
||||
exit 99
|
||||
}
|
||||
|
||||
rc_include() {
|
||||
. ./redoconf.rc || exit 1 # redefines rc_include
|
||||
rc_include "$@"
|
||||
}
|
||||
|
||||
_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" \
|
||||
"$S/default.${_base1#*.}.od" \
|
||||
"$REDOCONF/$1.od" \
|
||||
"$REDOCONF/${_dir1}default.${_base1#*.}.od" \
|
||||
"$REDOCONF/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
|
||||
die "default.do.sh: _pick_src: no source file found for '$1.*'"
|
||||
return 1
|
||||
}
|
||||
|
||||
_objlist() {
|
||||
local suffix="$1" list="$2"
|
||||
local base="${2##*/}"
|
||||
local dir="${2%"$base"}"
|
||||
while read -r d; do
|
||||
case $d in
|
||||
-*) ;;
|
||||
*.c|*.cc|*.cpp|*.cxx|*.C|*.c++|*.o)
|
||||
echo "$dir${d%.*}$suffix"
|
||||
;;
|
||||
*) echo "$dir$d" ;;
|
||||
esac
|
||||
done <"$list"
|
||||
}
|
||||
|
||||
_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#*:}
|
||||
}
|
||||
|
||||
_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 "$@"
|
||||
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="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 "$@"
|
||||
# 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
|
||||
bname="$(basename "$1.$ver")"
|
||||
ln -s "$bname" "$3"
|
||||
[ "$1.$ver" = "$bname" ] || ln -sf "$1.$ver" .
|
||||
;;
|
||||
*.list|*.ver)
|
||||
if [ -e "$S/$1" ]; then
|
||||
redo-ifchange "$S/$1"
|
||||
_mkdir_of "$3"
|
||||
cp "$S/$1" "$3"
|
||||
else
|
||||
die "default.do.sh: no rule to build '$1'"
|
||||
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
|
||||
_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
|
||||
die "default.do.sh: no rule to build '$1' or '$1.list'"
|
||||
exit 99
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
30
redoconf/default.precompile.od
Normal file
30
redoconf/default.precompile.od
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# 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.
|
||||
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
|
||||
60
redoconf/link-shlib.od
Normal file
60
redoconf/link-shlib.od
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
rc_include _all.rc
|
||||
|
||||
# Tricky quoting: see _compile.od for details.
|
||||
if [ "$HAVE_SHLIB" = UNIX ]; 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 \\
|
||||
"\$@" \\
|
||||
\$xLIBS \$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 \\
|
||||
"\$@" \\
|
||||
\$xLIBS \$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.
|
||||
cat >$3 <<-EOF
|
||||
#!/bin/sh -e
|
||||
o="\$1"
|
||||
shift
|
||||
rm -f "\$o"
|
||||
ar q "\$o" "\$@"
|
||||
EOF
|
||||
fi
|
||||
chmod a+x "$3"
|
||||
redo-stamp <$3
|
||||
20
redoconf/link.od
Normal file
20
redoconf/link.od
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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" \\
|
||||
\$LDFLAGS \$OPTFLAGS \\
|
||||
"\$@" \\
|
||||
\$xLIBS \$LIBS
|
||||
EOF
|
||||
chmod a+x "$3"
|
||||
redo-stamp <$3
|
||||
240
redoconf/rc.sh
Normal file
240
redoconf/rc.sh
Normal file
|
|
@ -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 91
|
||||
elif [ -n "$RC_QUEUE" ]; then
|
||||
echo "Fatal: script exited without rc_save or rc_undo." >&2
|
||||
exit 92
|
||||
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
|
||||
}
|
||||
68
redoconf/rc/CC.rc.od
Normal file
68
redoconf/rc/CC.rc.od
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
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 <windows.h>'
|
||||
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_replaceln HAVE_CC 1
|
||||
rc_save
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Can't find a working C compiler." >&2
|
||||
rc_undo
|
||||
rc_replaceln CC ""
|
||||
rc_save
|
||||
34
redoconf/rc/CXX.rc.od
Normal file
34
redoconf/rc/CXX.rc.od
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
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_replaceln HAVE_CXX 1
|
||||
rc_save
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Warning: Can't find a working C++ compiler." >&2
|
||||
rc_undo
|
||||
rc_replaceln CXX ""
|
||||
rc_save
|
||||
8
redoconf/rc/Wall.rc.od
Normal file
8
redoconf/rc/Wall.rc.od
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
rc_include rc/CC.rc
|
||||
|
||||
rc_appendln CPPFLAGS "-Wall"
|
||||
if rc_compile cc nolink; then
|
||||
rc_save
|
||||
else
|
||||
rc_undo
|
||||
fi
|
||||
8
redoconf/rc/Wextra.rc.od
Normal file
8
redoconf/rc/Wextra.rc.od
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
rc_include rc/CC.rc
|
||||
|
||||
rc_appendln CPPFLAGS "-Wextra"
|
||||
if rc_compile cc nolink; then
|
||||
rc_save
|
||||
else
|
||||
rc_undo
|
||||
fi
|
||||
8
redoconf/rc/_init.rc.od
Normal file
8
redoconf/rc/_init.rc.od
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
if [ -e _flags ]; then
|
||||
redo-ifchange _flags
|
||||
cat _flags >$3
|
||||
redo-stamp <_flags
|
||||
else
|
||||
redo-ifcreate _flags
|
||||
redo-stamp </dev/null
|
||||
fi
|
||||
17
redoconf/rc/default.autolib.rc.od
Normal file
17
redoconf/rc/default.autolib.rc.od
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
rc_include rc/CC.rc
|
||||
|
||||
base="${1#*/}"
|
||||
lib="${base%.autolib.rc}"
|
||||
LIB=$(echo "$lib" | tr 'a-z.' 'A-Z_')
|
||||
|
||||
x="-l$lib"
|
||||
rc_appendln "LIB$LIB" "$x"
|
||||
appendln LIBS "$x"
|
||||
if rc_compile cc link ""; then
|
||||
rc_replaceln "HAVE_$LIB" 1
|
||||
else
|
||||
rc_undo
|
||||
rc_replaceln "HAVE_$LIB" ""
|
||||
rc_replaceln "LIB$LIB" ""
|
||||
fi
|
||||
rc_save
|
||||
29
redoconf/rc/default.h.precompiled.rc.od
Normal file
29
redoconf/rc/default.h.precompiled.rc.od
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
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_PCH "-include$NL$src.h"
|
||||
rc_appendln CFLAGS_PCH_FPIC "-include$NL$src.h.fpic"
|
||||
|
||||
rc_appendln PRE_CC_TARGETS "$src.h.gch"
|
||||
rc_appendln PRE_CC_TARGETS_FPIC "$src.h.fpic.gch"
|
||||
rc_save
|
||||
else
|
||||
echo "Precompiled C headers not supported." >&2
|
||||
rc_undo
|
||||
fi
|
||||
13
redoconf/rc/default.h.rc.od
Normal file
13
redoconf/rc/default.h.rc.od
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
rc_include rc/CC.rc
|
||||
|
||||
base="${1#*/}"
|
||||
h1="${base%.rc}"
|
||||
h=$(echo "$h1" | sed -e 's,__,/,g') # x__y_z.h.rc.od -> <x/y_z.h>
|
||||
H=$(echo "$h1" | 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
|
||||
29
redoconf/rc/default.hpp.precompiled.rc.od
Normal file
29
redoconf/rc/default.hpp.precompiled.rc.od
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
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.
|
||||
rc_appendln CXXFLAGS "-Winvalid-pch"
|
||||
if rc_compile cxx nolink; then
|
||||
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
|
||||
11
redoconf/rc/default.required.rc.od
Normal file
11
redoconf/rc/default.required.rc.od
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
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
|
||||
11
redoconf/rc/libgl.rc.od
Normal file
11
redoconf/rc/libgl.rc.od
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <GL/gl.h>
|
||||
int x = GL_VERSION_1_1;
|
||||
void f() { glPopMatrix(); }
|
||||
'
|
||||
|
||||
rc_pkg_detect LIBGL "gl" \
|
||||
rc_compile cc link "$prog"
|
||||
rc_save
|
||||
11
redoconf/rc/libgtk2.rc.od
Normal file
11
redoconf/rc/libgtk2.rc.od
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <gtk/gtk.h>
|
||||
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
|
||||
24
redoconf/rc/libm.rc.od
Normal file
24
redoconf/rc/libm.rc.od
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <math.h>
|
||||
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
|
||||
11
redoconf/rc/libpng.rc.od
Normal file
11
redoconf/rc/libpng.rc.od
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <png.h>
|
||||
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
|
||||
17
redoconf/rc/libqt4.rc.od
Normal file
17
redoconf/rc/libqt4.rc.od
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
rc_include rc/CXX.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <QVector>
|
||||
'
|
||||
|
||||
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
|
||||
11
redoconf/rc/libsdl.rc.od
Normal file
11
redoconf/rc/libsdl.rc.od
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <SDL.h>
|
||||
int x = SDL_INIT_TIMER;
|
||||
void f() { SDL_Init(0); }
|
||||
'
|
||||
|
||||
rc_pkg_detect LIBSDL "sdl" \
|
||||
rc_compile cc link "$prog"
|
||||
rc_save
|
||||
9
redoconf/rc/libssl.rc.od
Normal file
9
redoconf/rc/libssl.rc.od
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog="
|
||||
#include <openssl/ssl.h>
|
||||
"
|
||||
|
||||
rc_pkg_detect LIBSSL "libssl libcrypto" \
|
||||
rc_compile cc link "$prog"
|
||||
rc_save
|
||||
11
redoconf/rc/libx11.rc.od
Normal file
11
redoconf/rc/libx11.rc.od
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
rc_include rc/CC.rc rc/pkg-config.rc
|
||||
|
||||
prog='
|
||||
#include <X11/Xutil.h>
|
||||
int x = XYBitmap;
|
||||
void f() { XCreateRegion(); }
|
||||
'
|
||||
|
||||
rc_pkg_detect LIBX11 "x11" \
|
||||
rc_compile cc link "$prog"
|
||||
rc_save
|
||||
16
redoconf/rc/pkg-config.rc.od
Normal file
16
redoconf/rc/pkg-config.rc.od
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
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
|
||||
26
redoconf/rc/run.rc.od
Normal file
26
redoconf/rc/run.rc.od
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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
|
||||
54
redoconf/rc/shlib.rc.od
Normal file
54
redoconf/rc/shlib.rc.od
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
rc_include rc/CC.rc
|
||||
|
||||
prog='
|
||||
#include <stdlib.h>
|
||||
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 "STATIC"
|
||||
elif [ -n "$NOSHARED" ]; then
|
||||
echo "--disable-shared specified; not building shared libraries." >&2
|
||||
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_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
|
||||
10
redoconf/rc/zdefs.rc.od
Normal file
10
redoconf/rc/zdefs.rc.od
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
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
|
||||
25
redoconf/rc_vars.od
Normal file
25
redoconf/rc_vars.od
Normal file
|
|
@ -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
|
||||
34
redoconf/redoconf.h.od
Normal file
34
redoconf/redoconf.h.od
Normal file
|
|
@ -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
|
||||
15
redoconf/run.od
Normal file
15
redoconf/run.od
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
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
|
||||
71
redoconf/trycompile
Normal file
71
redoconf/trycompile
Normal file
|
|
@ -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"
|
||||
58
redoconf/utils.sh
Normal file
58
redoconf/utils.sh
Normal file
|
|
@ -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")"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue