API: Packaging of JSON files.
Change-Id: If041b6faf1a091d4758b514f0a8cd800ee0e6a89 Signed-off-by: Ole Troan <ot@cisco.com> Signed-off-by: Ole Troan <otroan@ot-vpp.cisco.com> Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:
@ -28,6 +28,10 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES))
|
||||
| sed -e 's:.*:../& /usr/bin:' \
|
||||
> deb/debian/vpp.install ; \
|
||||
\
|
||||
: core api definitions ; \
|
||||
./scripts/find-api-core-contents $(INSTALL_PREFIX)$(ARCH) \
|
||||
deb/debian/vpp.install ; \
|
||||
\
|
||||
: need symbolic links in the lib pkg ; \
|
||||
find $(INSTALL_PREFIX)$(ARCH)/*/lib* \( -type f -o -type l \) \
|
||||
-print | egrep -e '*\.so\.*\.*\.*' \
|
||||
@ -35,6 +39,10 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES))
|
||||
| sed -e 's:.*:../& /usr/lib/x86_64-linux-gnu:' \
|
||||
> deb/debian/vpp-lib.install ; \
|
||||
\
|
||||
: vnet api definitions ; \
|
||||
./scripts/find-api-lib-contents $(INSTALL_PREFIX)$(ARCH) \
|
||||
deb/debian/vpp-lib.install ; \
|
||||
\
|
||||
: dev package ; \
|
||||
./scripts/find-dev-contents $(INSTALL_PREFIX)$(ARCH) \
|
||||
deb/debian/vpp-dev.install ; \
|
||||
@ -62,8 +70,6 @@ install-deb: $(patsubst %,%-find-source,$(ROOT_PACKAGES))
|
||||
: dev package needs a couple of additions ; \
|
||||
echo ../build-tool-native/vppapigen/vppapigen /usr/bin \
|
||||
>> deb/debian/vpp-dev.install ; \
|
||||
echo ../../vppapigen/pyvppapigen.py /usr/bin \
|
||||
>> deb/debian/vpp-dev.install ; \
|
||||
echo ../../vpp-api/java/jvpp/gen/jvpp_gen.py /usr/bin \
|
||||
>> deb/debian/vpp-dev.install ; \
|
||||
for i in $$(ls ../vpp-api/java/jvpp/gen/jvppgen/*.py); do \
|
||||
|
@ -20,4 +20,8 @@
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
|
||||
%.api.json: %.api
|
||||
@echo " JSON APIGEN " $@ ; \
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --json $@
|
||||
|
@ -98,7 +98,12 @@ mkdir -p -m755 %{buildroot}%{_bindir}
|
||||
mkdir -p -m755 %{buildroot}%{_unitdir}
|
||||
install -p -m 755 %{_mu_build_dir}/%{_vpp_install_dir}/*/bin/* %{buildroot}%{_bindir}
|
||||
install -p -m 755 %{_mu_build_dir}/%{_vpp_build_dir}/vppapigen/vppapigen %{buildroot}%{_bindir}
|
||||
install -p -m 755 %{_mu_build_dir}/../vppapigen/pyvppapigen.py %{buildroot}%{_bindir}
|
||||
|
||||
# core api
|
||||
mkdir -p -m755 %{buildroot}/usr/share/vpp/api
|
||||
install -p -m 755 %{_mu_build_dir}/%{_vpp_install_dir}/vpp/vpp-api/vpe.api.json %{buildroot}/usr/share/vpp/api
|
||||
install -p -m 755 %{_mu_build_dir}/%{_vpp_install_dir}/vlib-api/vlibmemory/memclnt.api.json %{buildroot}/usr/share/vpp/api
|
||||
|
||||
#
|
||||
# configs
|
||||
#
|
||||
@ -123,6 +128,10 @@ do
|
||||
( cd %{buildroot}%{_libdir} &&
|
||||
ln -fs $file $(echo $file | sed -e 's/\(\.so\)\.[0-9]\+.*/\1/') )
|
||||
done
|
||||
for file in $(find %{_mu_build_dir}/%{_vpp_install_dir}/vnet -type f -name '*.api.json' -print )
|
||||
do
|
||||
install -p -m 644 $file %{buildroot}/usr/share/vpp/api
|
||||
done
|
||||
|
||||
# Python bindings
|
||||
mkdir -p -m755 %{buildroot}%{python2_sitelib}/vpp_papi
|
||||
@ -178,6 +187,11 @@ do
|
||||
%{buildroot}/usr/lib/vpp_api_test_plugins/$file
|
||||
done
|
||||
|
||||
for file in $(find %{_mu_build_dir}/%{_vpp_install_dir}/plugins -type f -name '*.api.json' -print )
|
||||
do
|
||||
install -p -m 644 $file %{buildroot}/usr/share/vpp/api
|
||||
done
|
||||
|
||||
%post
|
||||
sysctl --system
|
||||
%systemd_post vpp.service
|
||||
@ -214,12 +228,14 @@ fi
|
||||
/usr/bin/elftool
|
||||
%config /etc/sysctl.d/80-vpp.conf
|
||||
%config /etc/vpp/startup.conf
|
||||
/usr/share/vpp/api/*
|
||||
|
||||
%files lib
|
||||
%defattr(-,bin,bin)
|
||||
%exclude %{_libdir}/vpp_plugins
|
||||
%exclude %{_libdir}/vpp_api_test_plugins
|
||||
%{_libdir}/*
|
||||
/usr/share/vpp/api/*
|
||||
|
||||
%files python-api
|
||||
%defattr(644,root,root)
|
||||
@ -229,7 +245,6 @@ fi
|
||||
%defattr(-,bin,bin)
|
||||
/usr/bin/vppapigen
|
||||
/usr/bin/jvpp_gen.py
|
||||
/usr/bin/pyvppapigen.py
|
||||
%{_includedir}/*
|
||||
%{python2_sitelib}/jvppgen/*
|
||||
/usr/share/doc/vpp/examples/sample-plugin
|
||||
@ -238,3 +253,4 @@ fi
|
||||
%defattr(-,bin,bin)
|
||||
/usr/lib/vpp_plugins/*
|
||||
/usr/lib/vpp_api_test_plugins/*
|
||||
/usr/share/vpp/api/*
|
||||
|
9
build-root/scripts/find-api-core-contents
Executable file
9
build-root/scripts/find-api-core-contents
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
for i in $(find ${1}/vpp -name *.api.json -type f -print); do
|
||||
echo ../${i} /usr/share/vpp/api/ >> ${2}
|
||||
done
|
||||
for i in $(find ${1}/vlib-api -name *.api.json -type f -print); do
|
||||
echo ../${i} /usr/share/vpp/api/ >> ${2}
|
||||
done
|
||||
|
6
build-root/scripts/find-api-lib-contents
Executable file
6
build-root/scripts/find-api-lib-contents
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
for i in $(find ${1}/vnet -name *.api.json -type f -print); do
|
||||
echo ../${i} /usr/share/vpp/api/ >> ${2}
|
||||
done
|
||||
|
@ -9,3 +9,7 @@ done
|
||||
for i in ${1}/plugins/lib64/vpp_api_test_plugins/*.so; do
|
||||
echo ../${i} /usr/lib/vpp_api_test_plugins >> ${2}
|
||||
done
|
||||
|
||||
for i in $(find ${1}/plugins -name *.api.json -type f -print); do
|
||||
echo ../${i} /usr/share/vpp/api/ >> ${2}
|
||||
done
|
||||
|
@ -28,15 +28,26 @@ flowperpkt_plugin_la_SOURCES = flowperpkt/flowperpkt.c \
|
||||
flowperpkt/flowperpkt_plugin.api.h
|
||||
flowperpkt_plugin_la_LDFLAGS = -module
|
||||
|
||||
BUILT_SOURCES = flowperpkt/flowperpkt.api.h
|
||||
BUILT_SOURCES = \
|
||||
flowperpkt/flowperpkt.api.h \
|
||||
flowperpkt/flowperpkt.api.json
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
SUFFIXES = .api.h .api .api.json
|
||||
|
||||
%.api.h: %.api
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
%.api.json: %.api
|
||||
@echo " JSON APIGEN " $@ ; \
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --json $@
|
||||
|
||||
apidir = $(prefix)/flowperpkt/
|
||||
api_DATA = flowperpkt/flowperpkt.api.json
|
||||
|
||||
noinst_HEADERS = \
|
||||
flowperpkt/flowperpkt_all_api_h.h \
|
||||
flowperpkt/flowperpkt_msg_enum.h \
|
||||
|
@ -28,7 +28,8 @@ ioam_pot_plugin_la_SOURCES = \
|
||||
ioam/lib-pot/pot_api.c
|
||||
|
||||
BUILT_SOURCES = \
|
||||
ioam/lib-pot/pot.api.h ioam/lib-pot/pot.py
|
||||
ioam/lib-pot/pot.api.h \
|
||||
ioam/lib-pot/pot.api.json
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
|
||||
@ -37,14 +38,17 @@ SUFFIXES = .api.h .api
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
%.py: %.api
|
||||
$(info Creating Python binding for $@)
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $< \
|
||||
| vppapigen --input - --python - \
|
||||
| pyvppapigen.py --input - > $@
|
||||
%.api.json: %.api
|
||||
@echo " JSON APIGEN " $@ ; \
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --json $@
|
||||
|
||||
pyapidir = ${prefix}/vpp_papi_plugins
|
||||
pyapi_DATA = ioam/lib-pot/pot.py
|
||||
apidir = $(prefix)/ioam/
|
||||
api_DATA = \
|
||||
ioam/lib-pot/pot.api.json \
|
||||
ioam/lib-trace/trace.api.json \
|
||||
ioam/export/ioam_export.api.json
|
||||
|
||||
noinst_HEADERS = \
|
||||
ioam/lib-pot/pot_all_api_h.h \
|
||||
@ -73,7 +77,9 @@ ioam/export/node.c \
|
||||
ioam/export/ioam_export.api.h \
|
||||
ioam/export/ioam_export_thread.c
|
||||
|
||||
BUILT_SOURCES += ioam/export/ioam_export.api.h
|
||||
BUILT_SOURCES += \
|
||||
ioam/export/ioam_export.api.h \
|
||||
ioam/export/ioam_export.api.json
|
||||
|
||||
noinst_HEADERS += \
|
||||
ioam/export/ioam_export_all_api_h.h \
|
||||
@ -96,10 +102,9 @@ ioam_trace_plugin_la_SOURCES = \
|
||||
ioam/lib-trace/trace_util.h \
|
||||
ioam/lib-trace/trace_api.c
|
||||
|
||||
BUILT_SOURCES += \
|
||||
ioam/lib-trace/trace.api.h ioam/lib-trace/trace.py
|
||||
|
||||
pyapi_DATA += ioam/lib-trace/trace.py
|
||||
BUILT_SOURCES += \
|
||||
ioam/lib-trace/trace.api.h \
|
||||
ioam/lib-trace/trace.api.json
|
||||
|
||||
noinst_HEADERS += \
|
||||
ioam/export/ioam_export_all_api_h.h \
|
||||
|
@ -24,13 +24,26 @@ vppplugins_LTLIBRARIES = lb_plugin.la
|
||||
|
||||
lb_plugin_la_SOURCES = lb/lb.c lb/node.c lb/cli.c lb/util.c lb/refcount.c lb/api.c
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
BUILT_SOURCES = \
|
||||
lb/lb.api.h \
|
||||
lb/lb.api.json
|
||||
|
||||
SUFFIXES = .api.h .api .api.json
|
||||
|
||||
%.api.h: %.api
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
%.api.json: %.api
|
||||
@echo " JSON APIGEN " $@ ; \
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --json $@
|
||||
|
||||
apidir = $(prefix)/lb/
|
||||
api_DATA = lb/lb.api.json
|
||||
|
||||
noinst_HEADERS = lb/lb.h lb/util.h lb/refcount.h lb/lbhash.h lb/lb.api.h
|
||||
|
||||
lb_test_plugin_la_SOURCES = \
|
||||
|
@ -25,7 +25,7 @@ vppplugins_LTLIBRARIES = sample_plugin.la
|
||||
sample_plugin_la_SOURCES = sample/sample.c sample/node.c \
|
||||
sample/sample_plugin.api.h
|
||||
|
||||
BUILT_SOURCES = sample/sample.api.h
|
||||
BUILT_SOURCES = sample/sample.api.h sample/sample.api.json
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
|
||||
@ -34,6 +34,15 @@ SUFFIXES = .api.h .api
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
%.api.json: %.api
|
||||
@echo " JSON APIGEN " $@ ; \
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --json $@
|
||||
|
||||
apidir = $(prefix)/sample/
|
||||
api_DATA = sample.api.json
|
||||
|
||||
noinst_HEADERS = \
|
||||
sample/sample_all_api_h.h \
|
||||
sample/sample_msg_enum.h \
|
||||
|
@ -28,7 +28,7 @@ snat_plugin_la_SOURCES = snat/snat.c \
|
||||
snat/out2in.c \
|
||||
snat/snat_plugin.api.h
|
||||
|
||||
BUILT_SOURCES = snat/snat.api.h snat/snat.py
|
||||
BUILT_SOURCES = snat/snat.api.h snat/snat.api.json
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
|
||||
@ -37,14 +37,14 @@ SUFFIXES = .api.h .api
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
%.py: %.api
|
||||
$(info Creating Python binding for $@)
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $< \
|
||||
| vppapigen --input - --python - \
|
||||
| pyvppapigen.py --input - > $@
|
||||
%.api.json: %.api
|
||||
@echo " JSON APIGEN " $@ ; \
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --json $@
|
||||
|
||||
pyapidir = ${prefix}/vpp_papi_plugins
|
||||
pyapi_DATA = snat/snat.py
|
||||
apidir = $(prefix)/snat/
|
||||
api_DATA = snat.api.json
|
||||
|
||||
noinst_HEADERS = \
|
||||
snat/snat_all_api_h.h \
|
||||
@ -60,7 +60,7 @@ install-data-hook:
|
||||
@(cd $(vppapitestpluginsdir) && $(RM) $(vppapitestplugins_LTLIBRARIES))
|
||||
|
||||
apidir = $(prefix)/snat
|
||||
api_DATA = snat/snat.api
|
||||
api_DATA = snat/snat.api.json
|
||||
|
||||
#
|
||||
# Java code generation
|
||||
|
@ -67,9 +67,12 @@ nobase_include_HEADERS += \
|
||||
vlibsocket/vl_socket_msg_enum.h \
|
||||
vlibsocket/sockclnt.api.h
|
||||
|
||||
BUILT_SOURCES = vlibsocket/sockclnt.api.h vlibmemory/memclnt.api.h
|
||||
BUILT_SOURCES = \
|
||||
vlibsocket/sockclnt.api.h \
|
||||
vlibmemory/memclnt.api.h \
|
||||
vlibmemory/memclnt.api.json
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
SUFFIXES = .api.h .api .api.json
|
||||
|
||||
# The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk
|
||||
# and requires a symbolic link at the top of the vnet source tree
|
||||
@ -78,4 +81,4 @@ include $(top_srcdir)/suffix-rules.mk
|
||||
|
||||
# install the API definition, so we can produce java bindings, etc.
|
||||
apidir = $(prefix)/vlibmemory
|
||||
api_DATA = vlibmemory/memclnt.api
|
||||
api_DATA = vlibmemory/memclnt.api.json
|
||||
|
@ -15,7 +15,7 @@ AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
AM_CFLAGS = -Wall -Werror @DPDK@ @DPDK_CRYPTO@ @IPSEC@ @IPV6SR@
|
||||
|
||||
BUILT_SOURCES = vnet/interface.api.h
|
||||
BUILT_SOURCES = vnet/interface.api.h vnet/interface.api.json
|
||||
|
||||
libvnet_la_SOURCES =
|
||||
libvnetplugin_la_SOURCES =
|
||||
@ -884,12 +884,12 @@ pcap2pg_LDADD = libvnet.la -l:libvppinfra.a -lpthread -lm -ldl
|
||||
noinst_PROGRAMS += pcap2pg
|
||||
|
||||
# Set the suffix list
|
||||
SUFFIXES = .api.h .api
|
||||
SUFFIXES = .api.h .api .api.json
|
||||
|
||||
# install the API definition, so we can produce java bindings, etc.
|
||||
|
||||
apidir = $(prefix)/vpp-api
|
||||
api_DATA = vnet/interface.api
|
||||
apidir = $(prefix)/vnet
|
||||
api_DATA = vnet/interface.api.json
|
||||
|
||||
# The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk
|
||||
# and requires a symbolic link at the top of the vnet source tree
|
||||
|
@ -1,17 +1,2 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
SUBDIRS = python java
|
||||
|
||||
api_json_dir = $(abs_builddir)/vpp-api
|
||||
api_srcs:=$(shell find $(prefix)/../ -name '*.api')
|
||||
api_json:=$(patsubst %.api,$(api_json_dir)/%.api.json,$(notdir $(api_srcs)))
|
||||
|
||||
define define_compile_rules
|
||||
$(api_json_dir)/%.api.json: $(1)%.api
|
||||
@echo " + Generating '$$<'"
|
||||
@mkdir -p $$(@D)
|
||||
$(CC) $$(CPPFLAGS) -E -P -C -x c $$< | vppapigen --input - --json $$@
|
||||
endef
|
||||
|
||||
$(foreach directory,$(dir $(api_srcs)),$(eval $(call define_compile_rules,$(directory))))
|
||||
|
||||
BUILT_SOURCES = $(api_json)
|
||||
|
@ -83,14 +83,14 @@ packagedir_jvpp_core = io/fd/vpp/jvpp/core
|
||||
|
||||
BUILT_SOURCES += jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h
|
||||
|
||||
jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJNIConnection.h $(abs_builddir)/../vpp-api/vpe.api.json
|
||||
jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: jvpp-registry/io_fd_vpp_jvpp_VppJNIConnection.h $(prefix)/../vpp/vpp-api/vpe.api.json
|
||||
cp -rf @srcdir@/jvpp-core/* -t jvpp-core/
|
||||
mkdir -p jvpp-core/target
|
||||
cd jvpp-core \
|
||||
&& mkdir -p types dto future callfacade callback notification \
|
||||
&& @srcdir@/jvpp/gen/jvpp_gen.py --plugin_name core \
|
||||
-i $(abs_builddir)/../vpp-api/vpe.api.json \
|
||||
$(abs_builddir)/../vpp-api/interface.api.json \
|
||||
-i $(prefix)/../vpp/vpp-api/vpe.api.json \
|
||||
$(prefix)/../vnet/vnet/interface.api.json \
|
||||
&& cp -rf types dto future callfacade callback notification *.java -t $(packagedir_jvpp_core) \
|
||||
&& rm -rf types dto future callfacade callback notification *.java
|
||||
|
||||
|
@ -32,23 +32,8 @@ libpneum_la_LIBADD = -lvlibmemoryclient -lvlibapi -lsvm -lvppinfra -lpthread \
|
||||
libpneum_la_LDFLAGS = -module
|
||||
libpneum_la_CPPFLAGS =
|
||||
|
||||
#
|
||||
# Core VPP API
|
||||
#
|
||||
$(srcdir)/vpp_papi/vpe.py: $(prefix)/../vpp/vpp-api/vpe.api
|
||||
$(info Creating Python binding for $@)
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $< \
|
||||
| vppapigen --input - --python - \
|
||||
| pyvppapigen.py --input - > $(srcdir)/vpp_papi/$(notdir $@)
|
||||
|
||||
$(srcdir)/vpp_papi/memclnt.py: $(prefix)/../vlib-api/vlibmemory/memclnt.api
|
||||
$(info Creating Python binding for $@)
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $< \
|
||||
| vppapigen --input - --python - \
|
||||
| pyvppapigen.py --input - > $(srcdir)/vpp_papi/$(notdir $@)
|
||||
|
||||
# TODO: Support both Python 2 and 3.
|
||||
install-exec-local: $(srcdir)/vpp_papi/vpe.py $(srcdir)/vpp_papi/memclnt.py
|
||||
install-exec-local:
|
||||
cd $(srcdir); \
|
||||
mkdir -p $(prefix)/lib/python2.7/site-packages; \
|
||||
PYTHONUSERBASE=$(prefix) \
|
||||
|
@ -46,9 +46,9 @@ nobase_include_HEADERS = \
|
||||
# install the API definition, so we can produce java bindings, etc.
|
||||
|
||||
apidir = $(prefix)/vpp-api
|
||||
api_DATA = vpp-api/vpe.api
|
||||
api_DATA = vpp-api/vpe.api.json
|
||||
|
||||
BUILT_SOURCES += vpp-api/vpe.api.h app/version.h
|
||||
BUILT_SOURCES += vpp-api/vpe.api.h app/version.h vpp-api/vpe.api.json
|
||||
|
||||
app/version.o: app/version.h
|
||||
|
||||
@ -122,7 +122,7 @@ if WITH_IPV6SR
|
||||
endif
|
||||
|
||||
# Set the suffix list
|
||||
SUFFIXES = .api.h .api
|
||||
SUFFIXES = .api.h .api .api.json
|
||||
|
||||
# The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk
|
||||
# and requires a symbolic link at the top of the vpp source tree
|
||||
|
@ -14,7 +14,7 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
bin_PROGRAMS = vppapigen
|
||||
bin_SCRIPTS = pyvppapigen.py
|
||||
bin_SCRIPTS =
|
||||
|
||||
BUILT_SOURCES = gram.h
|
||||
|
||||
|
@ -1,291 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2016 Cisco and/or its affiliates.
|
||||
# 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 print_function
|
||||
import argparse, sys, os, importlib, pprint
|
||||
|
||||
parser = argparse.ArgumentParser(description='VPP Python API generator')
|
||||
parser.add_argument('-i', '--input', action="store", dest="inputfile", type=argparse.FileType('r'))
|
||||
parser.add_argument('-c', '--cfile', action="store")
|
||||
args = parser.parse_args()
|
||||
|
||||
#
|
||||
# Read API definitions file into vppapidefs
|
||||
#
|
||||
exec(args.inputfile.read())
|
||||
|
||||
# https://docs.python.org/3/library/struct.html
|
||||
format_struct = {'u8': 'B',
|
||||
'u16' : 'H',
|
||||
'u32' : 'I',
|
||||
'i32' : 'i',
|
||||
'u64' : 'Q',
|
||||
'f64' : 'd',
|
||||
'vl_api_fib_path_t' : 'IIBBBBBBBBBBBBBBBBBBBBB',
|
||||
'vl_api_ip4_fib_counter_t' : 'IBQQ',
|
||||
'vl_api_ip6_fib_counter_t' : 'QQBQQ',
|
||||
'vl_api_lisp_adjacency_t' : 'B' * 35
|
||||
};
|
||||
#
|
||||
# NB: If new types are introduced in vpe.api, these must be updated.
|
||||
#
|
||||
type_size = {'u8': 1,
|
||||
'u16' : 2,
|
||||
'u32' : 4,
|
||||
'i32' : 4,
|
||||
'u64' : 8,
|
||||
'f64' : 8,
|
||||
'vl_api_fib_path_t' : 29,
|
||||
'vl_api_ip4_fib_counter_t' : 21,
|
||||
'vl_api_ip6_fib_counter_t' : 33,
|
||||
'vl_api_lisp_adjacency_t' : 35
|
||||
};
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
def get_args(t):
|
||||
argslist = []
|
||||
for i in t:
|
||||
if i[1][0] == '_':
|
||||
argslist.append(i[1][1:])
|
||||
else:
|
||||
argslist.append(i[1])
|
||||
|
||||
return argslist
|
||||
|
||||
def get_pack(f):
|
||||
zeroarray = False
|
||||
bytecount = 0
|
||||
pack = ''
|
||||
elements = 1
|
||||
if len(f) is 3 or len(f) is 4:
|
||||
size = type_size[f[0]]
|
||||
bytecount += size * int(f[2])
|
||||
# Check if we have a zero length array
|
||||
if f[2] == '0':
|
||||
# If len 3 zero array
|
||||
elements = 0;
|
||||
pack += format_struct[f[0]]
|
||||
bytecount = size
|
||||
elif size == 1:
|
||||
n = f[2] * size
|
||||
pack += str(n) + 's'
|
||||
else:
|
||||
pack += format_struct[f[0]] * int(f[2])
|
||||
elements = int(f[2])
|
||||
else:
|
||||
bytecount += type_size[f[0]]
|
||||
pack += format_struct[f[0]]
|
||||
return (pack, elements, bytecount)
|
||||
|
||||
|
||||
'''
|
||||
def get_reply_func(f):
|
||||
if f['name']+'_reply' in func_name:
|
||||
return func_name[f['name']+'_reply']
|
||||
if f['name'].find('_dump') > 0:
|
||||
r = f['name'].replace('_dump','_details')
|
||||
if r in func_name:
|
||||
return func_name[r]
|
||||
return None
|
||||
'''
|
||||
|
||||
def footer_print():
|
||||
print('''
|
||||
def msg_id_base_set(b):
|
||||
global base
|
||||
base = b
|
||||
|
||||
import os
|
||||
name = os.path.splitext(os.path.basename(__file__))[0]
|
||||
''')
|
||||
print(u"plugin_register(name, api_func_table, api_name_to_id,", vl_api_version, ", msg_id_base_set)")
|
||||
|
||||
def api_table_print(name, i):
|
||||
msg_id_in = 'VL_API_' + name.upper()
|
||||
fstr = name + '_decode'
|
||||
print('api_func_table.append(' + fstr + ')')
|
||||
print('api_name_to_id["' + msg_id_in + '"] =', i)
|
||||
print('')
|
||||
|
||||
|
||||
def encode_print(name, id, t):
|
||||
args = get_args(t)
|
||||
|
||||
if name.find('_dump') > 0:
|
||||
multipart = True
|
||||
else:
|
||||
multipart = False
|
||||
|
||||
if len(args) < 4:
|
||||
print(u"def", name + "(async = False):")
|
||||
else:
|
||||
print(u"def", name + "(" + ', '.join(args[3:]) + ", async = False):")
|
||||
print(u" global base")
|
||||
print(u" context = get_context(base + " + id + ")")
|
||||
|
||||
print('''
|
||||
results_prepare(context)
|
||||
waiting_for_reply_set()
|
||||
''')
|
||||
if multipart == True:
|
||||
print(u" results_more_set(context)")
|
||||
|
||||
t = list(t)
|
||||
|
||||
# only the last field can be a variable-length-array
|
||||
# it can either be 0, or a string
|
||||
# first, deal with all the other fields
|
||||
pack = '>' + ''.join([get_pack(f)[0] for f in t[:-1]])
|
||||
|
||||
# named variable-length-array
|
||||
if len(t[-1]) == 4 and t[-1][2] == '0' and t[-1][3] == t[-2][1]:
|
||||
print(u" vpp_api.write(pack('" + pack + "', base + "
|
||||
+ id + ", 0, context, " + ', '.join(args[3:-2] + ["len(" + args[-1] + ")"])
|
||||
+ ") + " + args[-1] + ")")
|
||||
|
||||
# unnamed variable-length-array
|
||||
elif len(t[-1]) >= 3 and t[-1][2] == '0':
|
||||
print(u" vpp_api.write(pack('" + pack + "', base + " +
|
||||
id + ", 0, context, " + ', '.join(args[3:-1]) + ") + "
|
||||
+ args[-1] + ")")
|
||||
|
||||
|
||||
# not a variable-length-array
|
||||
else:
|
||||
pack += get_pack(t[-1])[0]
|
||||
print(u" vpp_api.write(pack('" + pack + "', base + " + id +
|
||||
", 0, context, " + ', '.join(args[3:]) + "))")
|
||||
|
||||
if multipart == True:
|
||||
print(
|
||||
u" vpp_api.write(pack('>HII', VL_API_CONTROL_PING, 0, context))")
|
||||
|
||||
print('''
|
||||
if not async:
|
||||
results_event_wait(context, 5)
|
||||
return results_get(context)
|
||||
return context
|
||||
''')
|
||||
|
||||
def get_normal_pack(t, i, pack, offset):
|
||||
while t:
|
||||
f = t.pop(0)
|
||||
i += 1
|
||||
if len(f) >= 3:
|
||||
return t, i, pack, offset, f
|
||||
p, elements, size = get_pack(f)
|
||||
pack += p
|
||||
offset += size
|
||||
return t, i, pack, offset, None
|
||||
|
||||
def decode_print(name, t):
|
||||
#
|
||||
# Generate code for each element
|
||||
#
|
||||
print(u'def ' + name + u'_decode(msg):')
|
||||
total = 0
|
||||
args = get_args(t)
|
||||
print(u" n = namedtuple('" + name + "', '" + ', '.join(args) + "')")
|
||||
print(u" res = []")
|
||||
|
||||
pack = '>'
|
||||
start = 0
|
||||
end = 0
|
||||
offset = 0
|
||||
t = list(t)
|
||||
i = 0
|
||||
while t:
|
||||
t, i, pack, offset, array = get_normal_pack(t, i, pack, offset)
|
||||
if array:
|
||||
p, elements, size = get_pack(array)
|
||||
|
||||
# Byte string
|
||||
if elements > 0 and type_size[array[0]] == 1:
|
||||
pack += p
|
||||
offset += size * elements
|
||||
continue
|
||||
|
||||
# Dump current pack string
|
||||
if pack != '>':
|
||||
print(u" tr = unpack_from('" + pack + "', msg[" + str(start) + ":])")
|
||||
print(u" res.extend(list(tr))")
|
||||
start += offset
|
||||
pack = '>'
|
||||
|
||||
if elements == 0:
|
||||
# This has to be the last element
|
||||
if len(array) == 3:
|
||||
print(u" res.append(msg[" + str(offset) + ":])")
|
||||
if len(t) > 0:
|
||||
eprint('WARNING: Variable length array must be last element in message', name, array)
|
||||
|
||||
continue
|
||||
if size == 1 or len(p) == 1:
|
||||
# Do it as a bytestring.
|
||||
if p == 'B':
|
||||
p = 's'
|
||||
# XXX: Assume that length parameter is the previous field. Add validation.
|
||||
print(u" c = res[" + str(i - 2) + "]")
|
||||
print(u" tr = unpack_from('>' + str(c) + '" + p + "', msg[" + str(start) + ":])")
|
||||
print(u" res.append(tr)")
|
||||
continue
|
||||
print(u" tr2 = []")
|
||||
print(u" offset = " + str(total))
|
||||
print(u" for j in range(res[" + str(i - 2) + "]):")
|
||||
print(u" tr2.append(unpack_from('>" + p + "', msg[" + str(start) + ":], offset))")
|
||||
print(u" offset += " + str(size))
|
||||
print(u" res.append(tr2)")
|
||||
continue
|
||||
|
||||
# Missing something!!
|
||||
print(u" tr = unpack_from('>" + p + "', msg[" + str(start) + ":])")
|
||||
start += size
|
||||
|
||||
print(u" res.append(tr)")
|
||||
|
||||
if pack != '>':
|
||||
print(u" tr = unpack_from('" + pack + "', msg[" + str(start) + ":])")
|
||||
print(u" res.extend(list(tr))")
|
||||
print(u" return n._make(res)")
|
||||
print('')
|
||||
|
||||
#
|
||||
# Generate the main Python file
|
||||
#
|
||||
def main():
|
||||
print('''
|
||||
#
|
||||
# AUTO-GENERATED FILE. PLEASE DO NOT EDIT.
|
||||
#
|
||||
from vpp_api_base import *
|
||||
from struct import *
|
||||
from collections import namedtuple
|
||||
import vpp_api
|
||||
api_func_table = []
|
||||
api_name_to_id = {}
|
||||
''')
|
||||
|
||||
for i, a in enumerate(messages):
|
||||
name = a[0]
|
||||
encode_print(name, str(i), a[1:])
|
||||
decode_print(name, a[1:])
|
||||
api_table_print(name, i)
|
||||
footer_print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user