Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

p4c compiler driver #378

Merged
merged 5 commits into from
Mar 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ m4/ltversion.m4
m4/lt~obsolete.m4
frontends/p4/p4-lex.c
frontends/p4/p4-parse.cpp
py-compile

# vi/emacs tags files

Expand Down
11 changes: 10 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ noinst_PROGRAMS = # Binaries built that are not installed
BUILT_SOURCES = # Generated source files
check_PROGRAMS = # Test programs to build
TESTS = # Tests to execute
bin_SCRIPTS = # Scripts built
EXTRA_DIST = # Extra files to distribute

# Variables specific to our build system.
XFAIL_TESTS = $(IFAIL_TESTS) # Tests that are supposed to fail
Expand All @@ -58,6 +60,7 @@ p4_14include_HEADERS = # p4_14 include files

include $(srcdir)/lib/Makefile.am
include $(srcdir)/tools/ir-generator/Makefile.am
include $(srcdir)/tools/driver/Makefile.am
include $(srcdir)/ir/Makefile.am
include $(srcdir)/frontends/Makefile.am
include $(srcdir)/midend/Makefile.am
Expand Down Expand Up @@ -103,7 +106,13 @@ p4include_HEADERS += $(srcdir)/p4include/core.p4 $(srcdir)/p4include/v1model.p4
#### For testing, install headers in the build directory

all-local:
@$(MAKE) install-data pkgdatadir=$(builddir)
@$(MAKE) install-data pkgdatadir=$(abs_builddir)

# install-data-hook runs after other install rules
# for testing, p4c is regenerated to look up cfg files in build directory
install-data-hook:
@sed -e 's,[@]pkgdatadir[@],$(abs_builddir),g' < $(srcdir)/tools/driver/p4c.in > $(builddir)/p4c
@chmod +x $(builddir)/p4c

# FIXME -- should be a way of getting configure to do this automatcially? or automake?
setup.h: $(srcdir)/setup.h.in Makefile
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ AC_PROG_RANLIB
AX_CXX_COMPILE_STDCXX_11([noext],[mandatory])
AC_LANG(C++)

AM_PATH_PYTHON

AC_CHECK_FUNCS([clock_gettime])
AC_CHECK_FUNCS([memchr])
AC_CHECK_FUNCS([memrchr])
Expand Down
27 changes: 27 additions & 0 deletions tools/driver/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

bin_SCRIPTS += p4c
CLEANFILES += $(bin_SCRIPTS)
EXTRA_DIST += p4c.in

do_substitution = sed -e 's,[@]pkgdatadir[@],$(pkgdatadir),g'

# generate the p4c for installation
# this runs before install-data-hook
p4c: $(srcdir)/tools/driver/p4c.in
@$(do_substitution) < $(srcdir)/tools/driver/p4c.in > $(builddir)/p4c
@chmod +x $(builddir)/p4c

include $(srcdir)/tools/driver/p4c_src/Makefile.am
27 changes: 27 additions & 0 deletions tools/driver/p4c.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python
#
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys
sys.path.insert(1, '@pkgdatadir@')
os.environ['P4C_CFG_PATH'] = "@pkgdatadir@/p4c_src"
os.environ['P4C_16_INCLUDE_PATH'] = "@pkgdatadir@/p4include"
os.environ['P4C_14_INCLUDE_PATH'] = "@pkgdatadir@/p4_14include"
os.environ['PATH'] += ":@pkgdatadir@"

from p4c_src.main import main
if __name__ == '__main__':
main()
22 changes: 22 additions & 0 deletions tools/driver/p4c_src/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

p4c_PYTHON = tools/driver/p4c_src/main.py \
tools/driver/p4c_src/util.py \
tools/driver/p4c_src/config.py \
tools/driver/p4c_src/__init__.py \
tools/driver/p4c_src/p4c.bmv2.cfg \
tools/driver/p4c_src/p4c.ebpf.cfg

p4cdir=$(pkgdatadir)/p4c_src
24 changes: 24 additions & 0 deletions tools/driver/p4c_src/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

""" 'p4c' compiler driver """

__author__ = "Barefoot Networks"
__email__ = "p4c@barefootnetworks.com"
__versioninfo__ = (0, 0, 1)
__version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev'

__all__ = []

from .main import main
126 changes: 126 additions & 0 deletions tools/driver/p4c_src/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Copyright 2013-present Barefoot Networks, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import absolute_import
import sys
import os

class Config(object):
"""
Config - Configuration data for a 'p4c' tool chain.

The common configuration data include compiler/assembler name,
compiler/assembler installation path.
"""

def __init__(self, config_prefix):
self.config_prefix = config_prefix or 'p4c'
self.target = []
self.steps = {}
self.init_func = {}
self.options = {}
self.toolchain = {}

def load_from_config(self, path, output_dir, source_file):
cfg_globals = dict(globals())
cfg_globals['config'] = self
cfg_globals['__file__'] = path
cfg_globals['output_dir'] = output_dir
cfg_globals['source_fullname'] = source_file
cfg_globals['source_basename'] = os.path.splitext(os.path.basename(source_file))[0]

data = None
f = open(path)
try:
data = f.read()
except:
print "error", path
f.close()

try:
exec(compile(data, path, 'exec'), cfg_globals, None)
except SystemExit:
e = sys.exc_info()[1]
if e.args:
raise
except:
import traceback
print traceback.format_exc()

def add_preprocessor_option(self, backend, option):
if backend not in self.options:
self.options[backend] = {}
if 'preprocessor' not in self.options[backend]:
self.options[backend]['preprocessor'] = []
self.options[backend]['preprocessor'].append(option)

def add_compiler_option(self, backend, option):
if backend not in self.options:
self.options[backend] = {}
if 'compiler' not in self.options[backend]:
self.options[backend]['compiler'] = []
self.options[backend]['compiler'].append(option)

def add_assembler_option(self, backend, option):
if backend not in self.options:
self.options[backend] = {}
if 'assembler' not in self.options[backend]:
self.options[backend]['assembler'] = []
self.options[backend]['assembler'].append(option)

def add_linker_option(self, backend, option):
if backend not in self.options:
self.options[backend] = {}
if 'linker' not in self.options[backend]:
self.options[backend]['linker'] = []
self.options[backend]['linker'].append(option)

def add_toolchain(self, backend, toolchain):
if backend not in self.toolchain:
self.toolchain[backend] = {}
if not isinstance(toolchain, dict):
print "variable toolchain is not type dict"
sys.exit(1)
for k, v in toolchain.iteritems():
self.toolchain[backend][k] = v

def add_compilation_steps(self, backend, step):
self.steps[backend] = step


def get_compiler(self, backend):
if 'compiler' in self.toolchain[backend]:
return self.toolchain[backend]['compiler']
else:
return None

def get_preprocessor(self, backend):
if 'preprocessor' in self.toolchain[backend]:
return self.toolchain[backend]['preprocessor']
else:
return None

def get_assembler(self, backend):
if 'assembler' in self.toolchain[backend]:
return self.toolchain[backend]['assembler']
else:
return None

def get_linker(self, backend):
if 'linker' in self.toolchain[backend]:
return self.toolchain[backend]['linker']
else:
return None


Loading