Commit 64ec23c9 authored by Kenton Varda's avatar Kenton Varda

Fix automake to support bootstrapping the compiler.

parent d5f614a1
......@@ -42,7 +42,7 @@ EXTRA_DIST = \
LICENSE.txt \
$(test_capnpc_inputs)
CLEANFILES = $(test_capnpc_outputs) capnpc_middleman test_capnpc_middleman
CLEANFILES = $(test_capnpc_outputs) test_capnpc_middleman
# Deletes all the files generated by autoreconf.
MAINTAINERCLEANFILES = \
......@@ -76,12 +76,6 @@ maintainer-clean-local:
%.capnp:
@:
# Implicit rules for invoking capnpc.
%.capnp.h: %.capnp
$(CAPNPC) --src-prefix=$(srcdir) -oc++ -I$(srcdir)/src $^
%.capnp.c++: %.capnp.h
@:
public_capnpc_inputs = \
src/capnp/c++.capnp \
src/capnp/schema.capnp
......@@ -200,7 +194,7 @@ nodist_libcapnp_la_SOURCES = \
src/capnp/schema.capnp.c++ \
src/capnp/c++.capnp.c++
bin_PROGRAMS = capnp capnpc-capnp
bin_PROGRAMS = capnp capnpc-capnp capnpc-c++
capnp_LDADD = $(PTHREAD_LIBS) libcapnp.la
capnp_SOURCES = src/capnp/compiler/capnp.c++
......@@ -208,6 +202,9 @@ capnp_SOURCES = src/capnp/compiler/capnp.c++
capnpc_capnp_LDADD = $(PTHREAD_LIBS) libcapnp.la
capnpc_capnp_SOURCES = src/capnp/compiler/capnpc-capnp.c++
capnpc_c___LDADD = $(PTHREAD_LIBS) libcapnp.la
capnpc_c___SOURCES = src/capnp/compiler/capnpc-c++.c++
# Source files intentionally not included in the dist at this time:
# src/capnp/serialize-snappy*
# src/capnp/benchmark/...
......@@ -225,6 +222,22 @@ test_capnpc_outputs = \
src/capnp/test-import.capnp.c++ \
src/capnp/test-import.capnp.h
if USE_EXTERNAL_CAPNP
test_capnpc_middleman: $(test_capnpc_inputs)
$(CAPNP) compile --src-prefix=$(srcdir)/src -o$(CAPNPC_CXX):src -I$(srcdir)/src $^
touch test_capnpc_middleman
else
test_capnpc_middleman: capnp$(EXEEXT) capnpc-c++$(EXEEXT) $(test_capnpc_inputs)
echo $^ | (read CAPNP CAPNPC_CXX SOURCES && ./$$CAPNP compile --src-prefix=$(srcdir)/src -o./$$CAPNPC_CXX:src -I$(srcdir)/src $$SOURCES)
touch test_capnpc_middleman
endif
$(test_capnpc_outputs): test_capnpc_middleman
BUILT_SOURCES = $(test_capnpc_outputs)
check_PROGRAMS = capnp-test
......
......@@ -14,11 +14,14 @@ AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],
AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],
[CXXFLAGS="-O2 -DNDEBUG"])
AS_IF([test "x$CAPNPC" = "x"], [CAPNPC="capnpc"])
AC_SUBST([CAPNPC])
AM_INIT_AUTOMAKE
AC_ARG_WITH([external-capnp],
[AS_HELP_STRING([--with-external-capnp],
[use the system capnp binary (or the one specified with $CAPNP) instead of compiling a new
one (useful for cross-compiling)])],
[external_capnp=yes],[external_capnp=no])
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
......@@ -27,6 +30,24 @@ AX_CXX_COMPILE_STDCXX_11([noext])
ACX_PTHREAD
AC_PROG_LIBTOOL
AS_IF([test "$external_capnp" != "no"], [
AS_IF([test "x$CAPNP" = "x"], [CAPNP="capnp"], [with_capnp=yes])
AS_IF([test "x$CAPNPC_CXX" = "x"], [
# CAPNPC_CXX was not specified. Choose a reasonable default.
AS_CASE([$CAPNP], [*/*], [
# $CAPNP contains a slash, so it's not on $PATH. Assume capnpc-c++ is not either, but is
# in the same directory.
CAPNPC_CXX=`dirname $CAPNP`/capnpc-c++
], [
# $CAPNP is on $PATH, so tell it to find the plugin on $PATH as well.
CAPNPC_CXX="c++"
])
])
AC_SUBST([CAPNP])
AC_SUBST([CAPNPC_CXX])
])
AM_CONDITIONAL([USE_EXTERNAL_CAPNP], [test "$external_capnp" != "no"])
LIBS="$PTHREAD_LIBS $LIBS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
......
......@@ -40,6 +40,7 @@
#include <capnp/serialize.h>
#include <capnp/serialize-packed.h>
#include <limits>
#include <errno.h>
#if HAVE_CONFIG_H
#include "config.h"
......@@ -191,6 +192,11 @@ public:
}
kj::MainBuilder::Validity addSource(kj::StringPtr file) {
// Strip redundant "./" prefixes to make src-prefix matching more lenient.
while (file.startsWith("./")) {
file = file.slice(2);
}
if (!compilerConstructed) {
compiler = compilerSpace.construct(annotationFlag);
compilerConstructed = true;
......@@ -247,6 +253,16 @@ public:
}
kj::MainBuilder::Validity addSourcePrefix(kj::StringPtr prefix) {
// Strip redundant "./" prefixes to make src-prefix matching more lenient.
while (prefix.startsWith("./")) {
prefix = prefix.slice(2);
}
if (prefix == "" || prefix == ".") {
// Irrelevant prefix.
return true;
}
if (prefix.endsWith("/")) {
sourcePrefixes.add(kj::heapString(prefix));
} else {
......@@ -309,17 +325,34 @@ public:
KJ_SYSCALL(dup2(pipeFds[0], STDIN_FILENO));
KJ_SYSCALL(close(pipeFds[0]));
kj::Array<char> pwd = kj::heapArray<char>(256);
while (getcwd(pwd.begin(), pwd.size()) == nullptr) {
KJ_REQUIRE(pwd.size() < 8192, "WTF your working directory path is more than 8k?");
pwd = kj::heapArray<char>(pwd.size() * 2);
}
if (output.dir != nullptr) {
KJ_SYSCALL(chdir(output.dir.cStr()), output.dir);
}
if (shouldSearchPath) {
KJ_SYSCALL(execlp(exeName.cStr(), exeName.cStr(), nullptr));
execlp(exeName.cStr(), exeName.cStr(), nullptr);
} else {
KJ_SYSCALL(execl(exeName.cStr(), exeName.cStr(), nullptr));
if (!exeName.startsWith("/")) {
// The name is relative. Prefix it with our original working directory path.
exeName = kj::str(pwd.begin(), "/", exeName);
}
execl(exeName.cStr(), exeName.cStr(), nullptr);
}
KJ_FAIL_ASSERT("execlp() returned?");
int error = errno;
if (error == ENOENT) {
context.exitError(kj::str(output.name, ": no such plugin (executable should be '",
exeName, "')"));
} else {
KJ_FAIL_SYSCALL("exec()", error);
}
}
KJ_SYSCALL(close(pipeFds[0]));
......@@ -330,9 +363,9 @@ public:
int status;
KJ_SYSCALL(waitpid(child, &status, 0));
if (WIFSIGNALED(status)) {
context.error(kj::str(exeName, ": plugin failed: ", strsignal(WTERMSIG(status))));
context.error(kj::str(output.name, ": plugin failed: ", strsignal(WTERMSIG(status))));
} else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
context.error(kj::str(exeName, ": plugin failed: exit code ", WEXITSTATUS(status)));
context.error(kj::str(output.name, ": plugin failed: exit code ", WEXITSTATUS(status)));
}
}
......
......@@ -107,7 +107,6 @@ __EOF__
fi
rm -f capnproto-*.tar.gz samples/addressbook samples/addressbook.capnp.c++ \
samples/addressbook.capnp.h
rm -rf gtest
exit 0
elif [ "x$1" == "xhelp" ]; then
echo "usage: $0 [COMMAND]"
......@@ -171,8 +170,11 @@ echo "========================================================================="
doit make install
"x$(which capnp)" == "x$STAGING/bin/capnp"
"x$(which capnpc-c++)" == "x$STAGING/bin/capnpc-c++"
cd samples
doit capnpc -oc++ addressbook.capnp -I"$STAGING"/include
doit capnp compile -oc++ addressbook.capnp -I"$STAGING"/include --no-standard-import
doit ${CXX:-g++} -std=c++11 $SAMPLE_CXXFLAGS -I"$STAGING"/include -L"$STAGING"/lib \
addressbook.c++ addressbook.capnp.c++ -lcapnp -pthread -o addressbook
echo "@@@@ ./addressbook (in various configurations)"
......@@ -181,6 +183,14 @@ echo "@@@@ ./addressbook (in various configurations)"
rm addressbook addressbook.capnp.c++ addressbook.capnp.h
cd ..
echo "========================================================================="
echo "Testing --with-external-capnp"
echo "========================================================================="
doit make distclean
doit ./configure --prefix="$STAGING" --with-external-capnp CAPNP=$STAGING/bin/capnp
doit make -j6 check
doit make uninstall
echo "========================================================================="
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment