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.
This commit is contained in:
parent
5db883ac58
commit
6dae51f4d2
67 changed files with 1777 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
|
||||
|
|
|
|||
6
docs/cookbook/c/.gitignore
vendored
Normal file
6
docs/cookbook/c/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
hello
|
||||
/when.c
|
||||
/allconfig
|
||||
/arches
|
||||
/out
|
||||
/out.*
|
||||
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 @@
|
|||
. ./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
|
||||
27
docs/cookbook/c/allconfig.do
Normal file
27
docs/cookbook/c/allconfig.do
Normal file
|
|
@ -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
|
||||
14
docs/cookbook/c/arches.do
Normal file
14
docs/cookbook/c/arches.do
Normal file
|
|
@ -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
|
||||
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 '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)
|
||||
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");
|
||||
}
|
||||
9
docs/cookbook/c/flagtest.o.od
Normal file
9
docs/cookbook/c/flagtest.o.od
Normal file
|
|
@ -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"
|
||||
30
docs/cookbook/c/hello world.list.od
Normal file
30
docs/cookbook/c/hello world.list.od
Normal file
|
|
@ -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
|
||||
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_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 */
|
||||
5
docs/cookbook/c/rc/extra.rc.od
Normal file
5
docs/cookbook/c/rc/extra.rc.od
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
. ./redoconf.rc
|
||||
rc_include
|
||||
|
||||
rc_appendln CPPFLAGS "-DEXTRA_RC_INCLUDED=1"
|
||||
rc_save
|
||||
16
docs/cookbook/c/rc/posix.rc.od
Normal file
16
docs/cookbook/c/rc/posix.rc.od
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
. ./redoconf.rc
|
||||
rc_include rc/CC.rc
|
||||
|
||||
prog='
|
||||
#include <time.h>
|
||||
|
||||
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
|
||||
16
docs/cookbook/c/rc/printf_lld.rc.od
Normal file
16
docs/cookbook/c/rc/printf_lld.rc.od
Normal file
|
|
@ -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 <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();
|
||||
}
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue