From 78d24f3e5e4f501f91f9bf353a4250fc1274380b Mon Sep 17 00:00:00 2001 From: Nathan Skrzypczak Date: Wed, 18 May 2022 13:46:24 +0200 Subject: vppapigen: fix make go-api for go1.18 This patch updates the go-api-files logic for supporting go1.18. Notable changes are that `go get ...` changed to `go install` and that we need to bump the govpp binapigen version to integrate a go1.18 fix. This patch also simplifies the cli execution syntax Type: fix Change-Id: I1d8aac65490fe3ea4c1965a4775b6bf8d5c05d26 Signed-off-by: Nathan Skrzypczak --- src/tools/vppapigen/generate_go.py | 129 ++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 58 deletions(-) diff --git a/src/tools/vppapigen/generate_go.py b/src/tools/vppapigen/generate_go.py index fa53bc3dca3..4ed507b5d73 100755 --- a/src/tools/vppapigen/generate_go.py +++ b/src/tools/vppapigen/generate_go.py @@ -14,33 +14,46 @@ import sys # GoVPP API generator generates Go bindings compatible with the local VPP # +DefaultGoVppCommit = "16a47ef937b3a5ce6acf45885386062b323c8d25" -def get_go_version(go_root): - # Returns version of the installed Go + +def version_geq(ver_a, ver_b): + major_a, minor_a, patch_a = ver_a.split(".") + major_b, minor_b, patch_b = ver_b.split(".") + if major_a > major_b: + return True + elif major_a == major_b and minor_a > minor_b: + return True + elif major_a == major_b and minor_a == minor_b and patch_a >= patch_b: + return True + return False + + +def execute(cli, cwd=None): p = subprocess.Popen( - ["./go", "version"], - cwd=go_root + "/bin", + cli.split(), + cwd=cwd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, universal_newlines=True, ) - output, _ = p.communicate() - output_fmt = output.replace("go version go", "", 1) + output, error = p.communicate() + if p.returncode != 0: + print("Command `%s` failed: %d %s" % (cli, p.returncode, error)) + sys.exit(1) + return output, error - return output_fmt.rstrip("\n") + +def get_go_version(go_root): + # Returns version of the installed Go + output, _ = execute("./go version", cwd=go_root + "/bin") + return output.replace("go version go", "", 1).rstrip("\n") # Returns version of the installed binary API generator def get_binapi_gen_version(go_path): - p = subprocess.Popen( - ["./binapi-generator", "-version"], - cwd=go_path + "/bin", - stdout=subprocess.PIPE, - universal_newlines=True, - ) - output, _ = p.communicate() - output_fmt = output.replace("govpp", "", 1) - - return output_fmt.rstrip("\n") + output, _ = execute("./binapi-generator -version", cwd=go_path + "/bin") + return output.replace("govpp", "", 1).rstrip("\n") # Verifies local Go installation and installs the latest @@ -88,19 +101,18 @@ def install_golang(go_root): # Installs latest binary API generator def install_binapi_gen(c, go_root, go_path): - os.environ["GO111MODULE"] = "on" - if os.path.exists(go_root + "/bin/go") and os.path.isfile(go_root + "/bin/go"): - p = subprocess.Popen( - ["./go", "get", "git.fd.io/govpp.git/cmd/binapi-generator@" + c], + go_version = get_go_version(go_root) + if version_geq(go_version, "1.18.0"): + execute( + "./go install git.fd.io/govpp.git/cmd/binapi-generator@" + c, + cwd=go_root + "/bin", + ) + else: + os.environ["GO111MODULE"] = "on" + execute( + "./go get git.fd.io/govpp.git/cmd/binapi-generator@" + c, cwd=go_root + "/bin", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True, ) - _, error = p.communicate() - if p.returncode != 0: - print("binapi generator installation failed: %d %s" % (p.returncode, error)) - sys.exit(1) bg_ver = get_binapi_gen_version(go_path) print("Installed binary API generator " + bg_ver) @@ -119,25 +131,14 @@ def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_pat cmd += ["--output-dir=" + output_dir] if len(api_list): print("Following API files were requested by 'GO_API_FILES': " + str(api_list)) - print("Note that dependency requirements may generate " "additional API files") + print("Note that dependency requirements may generate additional API files") cmd.append(api_list) if import_prefix: cmd.append("-import-prefix=" + import_prefix) if no_source: cmd.append("-no-source-path-info") - p = subprocess.Popen( - cmd, - cwd=go_path + "/bin", - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True, - ) - - out = p.communicate()[1] - if p.returncode != 0: - print("go api generate failed: %d %s" % (p.returncode, out)) - sys.exit(1) + _, out = execute(" ".join(cmd), cwd=go_path + "/bin") # Print nice output of the binapi generator for msg in out.split(): if "=" in msg: @@ -148,6 +149,25 @@ def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_pat print("Go API bindings were generated to " + output_dir) +def get_go_variables(): + # go specific environment variables + if "GOROOT" in os.environ: + go_root = os.environ["GOROOT"] + else: + 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: + go_path = os.environ["GOPATH"] + else: + go_path = os.environ["HOME"] + "/go" + + return go_root, go_path + + def main(): # project root directory root = pathlib.Path(os.path.dirname(os.path.abspath(__file__))) @@ -157,8 +177,8 @@ def main(): parser.add_argument( "-govpp-commit", "--govpp-commit", - help="GoVPP commit or branch " "(defaults to v0.3.5-45-g671f16c)", - default="671f16c", # fixed GoVPP version + help="GoVPP commit or branch ", + default=DefaultGoVppCommit, type=str, ) parser.add_argument( @@ -193,22 +213,15 @@ def main(): ) args = parser.parse_args() - # go specific environment variables - if "GOROOT" in os.environ: - go_root = os.environ["GOROOT"] - else: - 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: - go_path = os.environ["GOPATH"] - else: - go_path = os.environ["HOME"] + "/go" - + go_root, go_path = get_go_variables() install_golang(go_root) + + if not ( + os.path.exists(go_root + "/bin/go") and os.path.isfile(go_root + "/bin/go") + ): + print(go_root + "/bin/go does not exist") + sys.exit(1) + install_binapi_gen(args.govpp_commit, go_root, go_path) generate_api( args.output_dir, -- cgit 1.2.3-korg