misc: Improve go bindings gen
Type: improvement Change-Id: Id705dab895602a60b053296b560ca3db5b0cd344 Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
This commit is contained in:

committed by
Beno�t Ganne

parent
c2feb65f42
commit
d591b82cc8
2
Makefile
2
Makefile
@@ -639,7 +639,7 @@ json-api-files-debug:
|
|||||||
|
|
||||||
.PHONY: go-api-files
|
.PHONY: go-api-files
|
||||||
go-api-files: json-api-files
|
go-api-files: json-api-files
|
||||||
$(WS_ROOT)/src/tools/vppapigen/generate_go.py
|
$(WS_ROOT)/src/tools/vppapigen/generate_go.py $(ARGS)
|
||||||
|
|
||||||
.PHONY: ctags
|
.PHONY: ctags
|
||||||
ctags: ctags.files
|
ctags: ctags.files
|
||||||
|
@@ -5,6 +5,7 @@ import os
|
|||||||
import pathlib
|
import pathlib
|
||||||
import subprocess
|
import subprocess
|
||||||
import tarfile
|
import tarfile
|
||||||
|
import shutil
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import sys
|
import sys
|
||||||
@@ -13,38 +14,9 @@ import sys
|
|||||||
# GoVPP API generator generates Go bindings compatible with the local VPP
|
# GoVPP API generator generates Go bindings compatible with the local VPP
|
||||||
#
|
#
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument("-govpp-commit", help="GoVPP commit or branch (defaults to v0.3.5-45-g671f16c)",
|
|
||||||
default="671f16c", # fixed GoVPP version
|
|
||||||
type=str)
|
|
||||||
parser.add_argument("-output-dir", help="output target directory for generated bindings", type=str)
|
|
||||||
parser.add_argument("-api-files", help="api files to generate (without commas)", nargs="+", type=str)
|
|
||||||
parser.add_argument("-import-prefix", help="prefix imports in the generated go code", type=str)
|
|
||||||
parser.add_argument("-no-source-path-info", help="disable source path info in generated files", nargs='?', const=True,
|
|
||||||
default=False)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
# Check input arguments
|
|
||||||
def validate_args(vpp_dir, o, f, c, i):
|
|
||||||
if o is not None:
|
|
||||||
if not os.path.exists(o) or os.path.isfile(o):
|
|
||||||
print(o + " is not a valid output path")
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
o = vpp_dir
|
|
||||||
if f is None:
|
|
||||||
f = []
|
|
||||||
if c is None:
|
|
||||||
c = "671f16c"
|
|
||||||
if i is None:
|
|
||||||
i = ""
|
|
||||||
|
|
||||||
return str(o), f, c, i
|
|
||||||
|
|
||||||
|
|
||||||
# Returns version of the installed Go
|
|
||||||
def get_go_version(go_root):
|
def get_go_version(go_root):
|
||||||
|
# Returns version of the installed Go
|
||||||
p = subprocess.Popen(["./go", "version"],
|
p = subprocess.Popen(["./go", "version"],
|
||||||
cwd=go_root + "/bin",
|
cwd=go_root + "/bin",
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
@@ -76,15 +48,24 @@ def install_golang(go_root):
|
|||||||
print('Go ' + get_go_version(go_root) + ' is already installed')
|
print('Go ' + get_go_version(go_root) + ' is already installed')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
filename = requests.get(
|
||||||
|
'https://golang.org/VERSION?m=text').text + ".linux-amd64.tar.gz"
|
||||||
|
url = "https://dl.google.com/go/" + filename
|
||||||
|
|
||||||
print("Go binary not found, installing the latest version...")
|
print("Go binary not found, installing the latest version...")
|
||||||
|
print("Download url = %s" % url)
|
||||||
|
print("Install directory = %s" % go_root)
|
||||||
|
text = input("[Y/n] ?")
|
||||||
|
|
||||||
|
if text.strip().lower() != "y" and text.strip().lower() != "yes":
|
||||||
|
print("Aborting...")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
go_folders = ['src', 'pkg', 'bin']
|
go_folders = ['src', 'pkg', 'bin']
|
||||||
|
|
||||||
for f in go_folders:
|
for f in go_folders:
|
||||||
if not os.path.exists(os.path.join(go_root, f)):
|
if not os.path.exists(os.path.join(go_root, f)):
|
||||||
os.makedirs(os.path.join(go_root, f))
|
os.makedirs(os.path.join(go_root, f))
|
||||||
|
|
||||||
filename = requests.get('https://golang.org/VERSION?m=text').text + ".linux-amd64.tar.gz"
|
|
||||||
url = "https://dl.google.com/go/" + filename
|
|
||||||
r = requests.get(url)
|
r = requests.get(url)
|
||||||
with open("/tmp/" + filename, 'wb') as f:
|
with open("/tmp/" + filename, 'wb') as f:
|
||||||
f.write(r.content)
|
f.write(r.content)
|
||||||
@@ -103,23 +84,26 @@ def install_golang(go_root):
|
|||||||
# Installs latest binary API generator
|
# Installs latest binary API generator
|
||||||
def install_binapi_gen(c, go_root, go_path):
|
def install_binapi_gen(c, go_root, go_path):
|
||||||
os.environ['GO111MODULE'] = "on"
|
os.environ['GO111MODULE'] = "on"
|
||||||
if os.path.exists(go_root + "/bin/go") & os.path.isfile(go_root + "/bin/go"):
|
if (os.path.exists(go_root + "/bin/go") and
|
||||||
p = subprocess.Popen(["./go", "get", "git.fd.io/govpp.git/cmd/binapi-generator@" + c],
|
os.path.isfile(go_root + "/bin/go")):
|
||||||
|
p = subprocess.Popen(["./go", "get",
|
||||||
|
"git.fd.io/govpp.git/cmd/binapi-generator@" + c],
|
||||||
cwd=go_root + "/bin",
|
cwd=go_root + "/bin",
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
stderr=subprocess.PIPE,
|
||||||
universal_newlines=True, )
|
universal_newlines=True, )
|
||||||
_, error = p.communicate()
|
_, error = p.communicate()
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
print("binapi generator installation failed: %d %s" % (p.returncode, error))
|
print("binapi generator installation failed: %d %s" %
|
||||||
|
(p.returncode, error))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
bg_ver = get_binapi_gen_version(go_path)
|
bg_ver = get_binapi_gen_version(go_path)
|
||||||
print('Installed binary API generator ' + bg_ver)
|
print('Installed binary API generator ' + bg_ver)
|
||||||
|
|
||||||
|
|
||||||
# Creates generated bindings using GoVPP binapigen to the target folder
|
# Creates generated bindings using GoVPP binapigen to the target folder
|
||||||
def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_path):
|
def generate_api(output_dir, vpp_dir, api_list, import_prefix,
|
||||||
output_binapi = output_dir + "binapi" if output_dir[-1] == "/" else output_dir + "/binapi"
|
no_source, go_path):
|
||||||
json_dir = vpp_dir + "/build-root/install-vpp-native/vpp/share/vpp/api"
|
json_dir = vpp_dir + "/build-root/install-vpp-native/vpp/share/vpp/api"
|
||||||
|
|
||||||
if not os.path.exists(json_dir):
|
if not os.path.exists(json_dir):
|
||||||
@@ -127,12 +111,16 @@ def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_pat
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print("Generating API")
|
print("Generating API")
|
||||||
cmd = ["./binapi-generator", "--output-dir=" + output_binapi, "--input-dir=" + json_dir]
|
cmd = ["./binapi-generator", "--input-dir=" + json_dir]
|
||||||
|
if output_dir:
|
||||||
|
cmd += ["--output-dir=" + output_dir]
|
||||||
if len(api_list):
|
if len(api_list):
|
||||||
print("Following API files were requested by 'GO_API_FILES': " + str(api_list))
|
print("Following API files were requested by 'GO_API_FILES': " +
|
||||||
print("Note that dependency requirements may generate additional API files")
|
str(api_list))
|
||||||
|
print("Note that dependency requirements may generate "
|
||||||
|
"additional API files")
|
||||||
cmd.append(api_list)
|
cmd.append(api_list)
|
||||||
if not import_prefix == "":
|
if import_prefix:
|
||||||
cmd.append("-import-prefix=" + import_prefix)
|
cmd.append("-import-prefix=" + import_prefix)
|
||||||
if no_source:
|
if no_source:
|
||||||
cmd.append("-no-source-path-info")
|
cmd.append("-no-source-path-info")
|
||||||
@@ -153,30 +141,59 @@ def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_pat
|
|||||||
print(msg, end=" ")
|
print(msg, end=" ")
|
||||||
|
|
||||||
print("\n")
|
print("\n")
|
||||||
print("Go API bindings were generated to " + output_binapi)
|
print("Go API bindings were generated to " + output_dir)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
# project root directory
|
# project root directory
|
||||||
root = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))
|
root = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))
|
||||||
vpp_dir: str = root.parent.parent.parent
|
vpp_dir = root.parent.parent.parent
|
||||||
|
|
||||||
o, f, c, i = validate_args(vpp_dir, args.output_dir, args.api_files, args.govpp_commit,
|
parser = argparse.ArgumentParser()
|
||||||
args.import_prefix)
|
parser.add_argument("-govpp-commit", "--govpp-commit",
|
||||||
|
help="GoVPP commit or branch "
|
||||||
|
"(defaults to v0.3.5-45-g671f16c)",
|
||||||
|
default="671f16c", # fixed GoVPP version
|
||||||
|
type=str)
|
||||||
|
parser.add_argument("-output-dir", "--output-dir",
|
||||||
|
help="output target directory for generated bindings",
|
||||||
|
type=str,
|
||||||
|
default=os.path.join(vpp_dir, "vppbinapi"))
|
||||||
|
parser.add_argument("-api-files", "--api-files",
|
||||||
|
help="api files to generate (without commas)",
|
||||||
|
nargs="+",
|
||||||
|
type=str,
|
||||||
|
default=[])
|
||||||
|
parser.add_argument("-import-prefix", "--import-prefix",
|
||||||
|
help="prefix imports in the generated go code",
|
||||||
|
default="",
|
||||||
|
type=str)
|
||||||
|
parser.add_argument("-no-source-path-info", "--no-source-path-info",
|
||||||
|
help="disable source path info in generated files",
|
||||||
|
nargs='?',
|
||||||
|
const=True,
|
||||||
|
default=True)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
# go specific environment variables
|
# go specific environment variables
|
||||||
if "GOROOT" in os.environ:
|
if "GOROOT" in os.environ:
|
||||||
go_root = os.environ['GOROOT']
|
go_root = os.environ['GOROOT']
|
||||||
else:
|
else:
|
||||||
go_root = os.environ['HOME'] + "/.go"
|
go_binary = shutil.which("go")
|
||||||
|
if go_binary != "":
|
||||||
|
go_binary_dir, _ = os.path.split(go_binary)
|
||||||
|
go_root = os.path.join(go_binary_dir, "..")
|
||||||
|
else:
|
||||||
|
go_root = os.environ['HOME'] + "/.go"
|
||||||
if "GOPATH" in os.environ:
|
if "GOPATH" in os.environ:
|
||||||
go_path = os.environ['GOPATH']
|
go_path = os.environ['GOPATH']
|
||||||
else:
|
else:
|
||||||
go_path = os.environ['HOME'] + "/go"
|
go_path = os.environ['HOME'] + "/go"
|
||||||
|
|
||||||
install_golang(go_root)
|
install_golang(go_root)
|
||||||
install_binapi_gen(c, go_root, go_path)
|
install_binapi_gen(args.govpp_commit, go_root, go_path)
|
||||||
generate_api(o, str(vpp_dir), f, i, args.no_source_path_info, go_path)
|
generate_api(args.output_dir, str(vpp_dir), args.api_files,
|
||||||
|
args.import_prefix, args.no_source_path_info, go_path)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
Reference in New Issue
Block a user