From ae0560f470b99164e96196c466da35f08b215cf6 Mon Sep 17 00:00:00 2001 From: Chris Dodd Date: Fri, 27 Jan 2017 15:20:44 -0800 Subject: [PATCH] Rework include file/path handling so we can install the compiler - look for p4include in the same dir as the executable to override the install p4include path. - install includes in the build directory so tests run. --- Makefile.am | 30 +++++++++++-- backends/ebpf/Makefile.am | 2 + .../ebpf/p4include}/ebpf_model.p4 | 0 bootstrap.sh | 5 +-- configure.ac | 4 +- frontends/common/options.cpp | 42 ++++++++++++++++++- frontends/common/options.h | 1 + setup.cpp | 1 + setup.h.in | 4 +- 9 files changed, 76 insertions(+), 13 deletions(-) rename {p4include => backends/ebpf/p4include}/ebpf_model.p4 (100%) diff --git a/Makefile.am b/Makefile.am index d2be5c1bcc6..dab389288fc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,6 +47,8 @@ export IFAIL_TESTS cpplint_FILES = # Files that should be passed to cpplint (and etags) ir_DEF_FILES = # Files that generate the IR extension_frontend_SOURCES = # Files added to libfrontend by extensions +p4include_HEADERS = # p4_16 include files +p4_14include_HEADERS = # p4_14 include files ################ Subproject Makefile inclusions @@ -85,6 +87,31 @@ BUILT_SOURCES += \ ir/ir-generated.cpp \ ir/gen-tree-macro.h +######## P4 header files to install + +# FIXME -- should these be in $(pkgdatadir) or $(prefix)? setup.h.in +# FIXME -- and check-install-headers: below need to be consistent +p4includedir = $(pkgdatadir)/p4include +p4_14includedir = $(pkgdatadir)/p4_14include +p4include_HEADERS += $(srcdir)/p4include/core.p4 $(srcdir)/p4include/v1model.p4 + +#### For testing, install headers in the build directory + +check-install-headers: + @$(MAKE) install-data pkgdatadir=$(builddir) + +check: check-install-headers +recheck: check-install-headers + +# FIXME -- should be a way of getting configure to do this automatcially? or automake? +setup.h: $(srcdir)/setup.h.in Makefile + @sed -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \ + -e 's|@prefix[@]|$(prefix)|g' \ + -e 's|@p4includedir[@]|$(p4includedir)|g' \ + -e 's|@p4_14includedir[@]|$(p4_14includedir)|g' \ + $< >$@ +setup.o setup.lo: setup.h + ################ # Front-end library @@ -106,9 +133,6 @@ cpplint_FILES += $(noinst_HEADERS) ################ Misc custom targets -install: - echo "Installation not yet supported." - clean-local: -rm -f $(BUILT_SOURCES) $(CLEANFILES) diff --git a/backends/ebpf/Makefile.am b/backends/ebpf/Makefile.am index 78fcb84720a..2177fc1ceba 100644 --- a/backends/ebpf/Makefile.am +++ b/backends/ebpf/Makefile.am @@ -47,6 +47,8 @@ noinst_HEADERS += \ cpplint_FILES += $(p4c_ebpf_UNIFIED) $(p4c_ebpf_NONUNIFIED) +p4include_HEADERS += $(srcdir)/%reldir%/p4include/ebpf_model.p4 + # Generated by the targets below -include ebpftests.mk diff --git a/p4include/ebpf_model.p4 b/backends/ebpf/p4include/ebpf_model.p4 similarity index 100% rename from p4include/ebpf_model.p4 rename to backends/ebpf/p4include/ebpf_model.p4 diff --git a/bootstrap.sh b/bootstrap.sh index e1e64fcaf63..cedc2b929ee 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -34,8 +34,5 @@ autoreconf -i mkdir -p build # recommended folder for build sourcedir=`pwd` cd build -# TODO: the "prefix" is needed for finding the p4include folder. -# It should be an absolute path. This may need to change -# when we have a proper installation procedure. -../configure CXXFLAGS="-g -O0" --prefix=$sourcedir $* +../configure CXXFLAGS="-g -O0" $* echo "### Configured for building in 'build' folder" diff --git a/configure.ac b/configure.ac index 55b3bd78ee6..98138f2a78f 100644 --- a/configure.ac +++ b/configure.ac @@ -70,9 +70,7 @@ AC_CHECK_LIB([rt], [clock_gettime], [], []) AC_CHECK_LIB([gmp], [__gmpz_init], [], [AC_MSG_ERROR([GNU MP not found])]) AC_CHECK_LIB([gmpxx], [__gmpz_init], [], [AC_MSG_ERROR([GNU MP not found])]) -AC_SUBST(P4INCLUDE, $prefix/p4include) - -AC_CONFIG_FILES([Makefile setup.h]) +AC_CONFIG_FILES([Makefile]) AX_PYTHON_MODULE([difflib], [fatal], [python]) AX_PYTHON_MODULE([shutil], [fatal], [python]) AX_PYTHON_MODULE([tempfile], [fatal], [python]) diff --git a/frontends/common/options.cpp b/frontends/common/options.cpp index 18ed2a1d1bf..513007b3068 100644 --- a/frontends/common/options.cpp +++ b/frontends/common/options.cpp @@ -15,6 +15,9 @@ limitations under the License. */ #include +#include +#include +#include #include "setup.h" #include "options.h" @@ -130,6 +133,41 @@ void CompilerOptions::setInputFile() { } } +std::vector* CompilerOptions::process(int argc, char* const argv[]) { + char buffer[PATH_MAX]; + int len; + struct stat st; + /* find the path of the executable. We use a number of techniques that may fail + * or work on different systems, and take the first working one we find. Fall + * back to not overriding the compiled-in installation path */ + if ((len = readlink("/proc/self/exe", buffer, sizeof(buffer))) > 0 || + (len = readlink("/proc/curproc/exe", buffer, sizeof(buffer))) > 0 || + (len = readlink("/proc/curproc/file", buffer, sizeof(buffer))) > 0 || + (len = readlink("/proc/self/path/a.out", buffer, sizeof(buffer))) > 0) { + buffer[len] = 0; + } else if (argv[0][0] == '/') { + snprintf(buffer, sizeof(buffer), "%s", argv[0]); + } else if (strchr(argv[0], '/')) { + getcwd(buffer, sizeof(buffer)); + strncat(buffer, argv[0], sizeof(buffer) - strlen(buffer) - 1); + } else if (getenv("_")) { + strncpy(buffer, getenv("_"), sizeof(buffer)); + buffer[sizeof(buffer) - 1] = 0; + } else { + buffer[0] = 0; } + + if (char *p = strrchr(buffer, '/')) { + ++p; + snprintf(p, buffer + sizeof(buffer) - p, "p4include"); + if (stat(buffer, &st) >= 0 && S_ISDIR(st.st_mode)) + p4includePath = strdup(buffer); + snprintf(p, buffer + sizeof(buffer) - p, "p4_14include"); + if (stat(buffer, &st) >= 0 && S_ISDIR(st.st_mode)) + p4_14includePath = strdup(buffer); } + + return Util::Options::process(argc, argv); +} + FILE* CompilerOptions::preprocess() { FILE* in = nullptr; @@ -145,8 +183,8 @@ FILE* CompilerOptions::preprocess() { #else std::string cmd("cpp"); #endif - cmd += cstring(" -undef -nostdinc -I") + - p4includePath + " " + preprocessor_options + " " + file; + cmd += cstring(" -undef -nostdinc") + " " + preprocessor_options + + " -I" + (isv1() ? p4_14includePath : p4includePath) + " " + file; if (Log::verbose()) std::cerr << "Invoking preprocessor " << std::endl << cmd << std::endl; in = popen(cmd.c_str(), "r"); diff --git a/frontends/common/options.h b/frontends/common/options.h index f3d843985fe..1525b47d45d 100644 --- a/frontends/common/options.h +++ b/frontends/common/options.h @@ -37,6 +37,7 @@ class CompilerOptions : public Util::Options { public: CompilerOptions(); + std::vector* process(int argc, char* const argv[]); enum class FrontendVersion { P4_14, diff --git a/setup.cpp b/setup.cpp index 763242f4979..c9bcdbb428f 100644 --- a/setup.cpp +++ b/setup.cpp @@ -17,3 +17,4 @@ limitations under the License. #include "setup.h" const char* p4includePath = P4_SYSTEM_INCLUDE_PATH; +const char* p4_14includePath = P4_14_SYSTEM_INCLUDE_PATH; diff --git a/setup.h.in b/setup.h.in index bde29ca70cb..d079351c317 100644 --- a/setup.h.in +++ b/setup.h.in @@ -4,7 +4,9 @@ #ifndef _SETUP_H_ #define _SETUP_H_ -#define P4_SYSTEM_INCLUDE_PATH "@P4INCLUDE@" +#define P4_SYSTEM_INCLUDE_PATH "@p4includedir@" +#define P4_14_SYSTEM_INCLUDE_PATH "@p4_14includedir@" extern const char* p4includePath; +extern const char* p4_14includePath; #endif /* _SETUP_H_ */