14 # GoVPP API generator generates Go bindings compatible with the local VPP
18 def get_go_version(go_root):
19 # Returns version of the installed Go
23 stdout=subprocess.PIPE,
24 universal_newlines=True,
26 output, _ = p.communicate()
27 output_fmt = output.replace("go version go", "", 1)
29 return output_fmt.rstrip("\n")
32 # Returns version of the installed binary API generator
33 def get_binapi_gen_version(go_path):
35 ["./binapi-generator", "-version"],
37 stdout=subprocess.PIPE,
38 universal_newlines=True,
40 output, _ = p.communicate()
41 output_fmt = output.replace("govpp", "", 1)
43 return output_fmt.rstrip("\n")
46 # Verifies local Go installation and installs the latest
48 def install_golang(go_root):
49 go_bin = go_root + "/bin/go"
51 if os.path.exists(go_bin) and os.path.isfile(go_bin):
52 print("Go " + get_go_version(go_root) + " is already installed")
56 requests.get("https://golang.org/VERSION?m=text").text + ".linux-amd64.tar.gz"
58 url = "https://dl.google.com/go/" + filename
60 print("Go binary not found, installing the latest version...")
61 print("Download url = %s" % url)
62 print("Install directory = %s" % go_root)
63 text = input("[Y/n] ?")
65 if text.strip().lower() != "y" and text.strip().lower() != "yes":
69 go_folders = ["src", "pkg", "bin"]
72 if not os.path.exists(os.path.join(go_root, f)):
73 os.makedirs(os.path.join(go_root, f))
75 with open("/tmp/" + filename, "wb") as f:
78 go_tf = tarfile.open("/tmp/" + filename)
79 # Strip /go dir from the go_root path as it will
80 # be created while extracting the tar file
81 go_root_head, _ = os.path.split(go_root)
82 go_tf.extractall(path=go_root_head)
84 os.remove("/tmp/" + filename)
86 print("Go " + get_go_version(go_root) + " was installed")
89 # Installs latest binary API generator
90 def install_binapi_gen(c, go_root, go_path):
91 os.environ["GO111MODULE"] = "on"
92 if os.path.exists(go_root + "/bin/go") and os.path.isfile(go_root + "/bin/go"):
94 ["./go", "get", "git.fd.io/govpp.git/cmd/binapi-generator@" + c],
96 stdout=subprocess.PIPE,
97 stderr=subprocess.PIPE,
98 universal_newlines=True,
100 _, error = p.communicate()
101 if p.returncode != 0:
102 print("binapi generator installation failed: %d %s" % (p.returncode, error))
104 bg_ver = get_binapi_gen_version(go_path)
105 print("Installed binary API generator " + bg_ver)
108 # Creates generated bindings using GoVPP binapigen to the target folder
109 def generate_api(output_dir, vpp_dir, api_list, import_prefix, no_source, go_path):
110 json_dir = vpp_dir + "/build-root/install-vpp-native/vpp/share/vpp/api"
112 if not os.path.exists(json_dir):
113 print("Missing JSON api definitions")
116 print("Generating API")
117 cmd = ["./binapi-generator", "--input-dir=" + json_dir]
119 cmd += ["--output-dir=" + output_dir]
121 print("Following API files were requested by 'GO_API_FILES': " + str(api_list))
122 print("Note that dependency requirements may generate " "additional API files")
125 cmd.append("-import-prefix=" + import_prefix)
127 cmd.append("-no-source-path-info")
128 p = subprocess.Popen(
130 cwd=go_path + "/bin",
131 stdout=subprocess.PIPE,
132 stderr=subprocess.PIPE,
133 universal_newlines=True,
136 out = p.communicate()[1]
137 if p.returncode != 0:
138 print("go api generate failed: %d %s" % (p.returncode, out))
141 # Print nice output of the binapi generator
142 for msg in out.split():
148 print("Go API bindings were generated to " + output_dir)
152 # project root directory
153 root = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))
154 vpp_dir = root.parent.parent.parent
156 parser = argparse.ArgumentParser()
160 help="GoVPP commit or branch " "(defaults to v0.3.5-45-g671f16c)",
161 default="671f16c", # fixed GoVPP version
167 help="output target directory for generated bindings",
169 default=os.path.join(vpp_dir, "vppbinapi"),
174 help="api files to generate (without commas)",
182 help="prefix imports in the generated go code",
187 "-no-source-path-info",
188 "--no-source-path-info",
189 help="disable source path info in generated files",
194 args = parser.parse_args()
196 # go specific environment variables
197 if "GOROOT" in os.environ:
198 go_root = os.environ["GOROOT"]
200 go_binary = shutil.which("go")
202 go_binary_dir, _ = os.path.split(go_binary)
203 go_root = os.path.join(go_binary_dir, "..")
205 go_root = os.environ["HOME"] + "/.go"
206 if "GOPATH" in os.environ:
207 go_path = os.environ["GOPATH"]
209 go_path = os.environ["HOME"] + "/go"
211 install_golang(go_root)
212 install_binapi_gen(args.govpp_commit, go_root, go_path)
218 args.no_source_path_info,
223 if __name__ == "__main__":