Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/build_config/relocate.py
428331 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2026-2026 German Aerospace Center (DLR) and others.
4
# This program and the accompanying materials are made available under the
5
# terms of the Eclipse Public License 2.0 which is available at
6
# https://www.eclipse.org/legal/epl-2.0/
7
# This Source Code may also be made available under the following Secondary
8
# Licenses when the conditions for such availability set forth in the Eclipse
9
# Public License 2.0 are satisfied: GNU General Public License, version 2
10
# or later which is available at
11
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
14
# @file relocate.py
15
# @author Michael Behrisch
16
# @date 2026-02-07
17
18
import glob
19
import hashlib
20
import os
21
import shutil
22
import subprocess
23
import sys
24
if sys.platform == "darwin":
25
from delocate.tools import get_install_names, set_install_name
26
27
28
def file_hash(path, chunk_size=8192):
29
h = hashlib.sha256()
30
with open(path, "rb") as f:
31
for chunk in iter(lambda: f.read(chunk_size), b""):
32
h.update(chunk)
33
return h.hexdigest()
34
35
36
def compare_directories(dir1, dir2):
37
entries = sorted(os.listdir(dir1))
38
if entries != sorted(os.listdir(dir2)):
39
print(entries, sorted(os.listdir(dir2)))
40
return False
41
for name in entries:
42
path1 = os.path.join(dir1, name)
43
path2 = os.path.join(dir2, name)
44
if (os.path.getsize(path1) != os.path.getsize(path2)
45
or (sys.platform != "darwin" and file_hash(path1) != file_hash(path2))):
46
print(path1, path2)
47
return False
48
return True
49
50
51
def fix_links_and_strip(binaries, lib_dir_prefix):
52
if sys.platform == "darwin":
53
for bin in binaries:
54
for lib in get_install_names(bin):
55
if lib.startswith(("@loader_path/.dylibs", "@loader_path/../.dylibs")):
56
set_install_name(bin, lib, lib.replace(".dylibs", "../sumo_data/.libs"))
57
lib_dir = os.path.join(lib_dir_prefix, ".dylibs")
58
subprocess.check_call(["strip", "-S", "-x"] + binaries + glob.glob(lib_dir + "/*"))
59
else:
60
for bin in binaries:
61
subprocess.check_call(["patchelf", "--force-rpath", "--add-rpath",
62
"$ORIGIN/../sumo_data/.libs", bin])
63
lib_dir = lib_dir_prefix + ".libs"
64
subprocess.check_call(["strip", "--strip-unneeded"] + binaries + glob.glob(lib_dir + "/*"))
65
return lib_dir
66
67
68
if __name__ == "__main__":
69
root = sys.argv[1]
70
# preparing sumo_data wheel
71
sumo_data = glob.glob(root + "/sumo_data*.whl")[0]
72
subprocess.check_call(["wheel", "unpack", "-d", root, sumo_data])
73
pack_dirs = [os.path.join(root, "-".join(os.path.basename(sumo_data).split("-")[:2]))]
74
data_libs = os.path.join(pack_dirs[0], "sumo_data", ".libs")
75
if os.path.exists(data_libs):
76
sys.exit("Data lib dir already exists.")
77
78
# relocating eclipse_sumo wheel
79
sumo = glob.glob(root + "/eclipse_sumo*.whl")[0]
80
subprocess.check_call(["wheel", "unpack", "-d", root, sumo])
81
sumo_dir = os.path.join(root, "-".join(os.path.basename(sumo).split("-")[:2]))
82
pack_dirs.append(sumo_dir)
83
binaries = glob.glob(sumo_dir + "/sumo/bin/*") + glob.glob(sumo_dir + "/sumo/lib/*")
84
sumo_libs = fix_links_and_strip(binaries,
85
os.path.join(sumo_dir, "sumo" if sys.platform == "darwin" else "eclipse_sumo"))
86
os.rename(sumo_libs, data_libs)
87
88
# relocating libsumo wheels
89
for f in glob.glob(root + "/libsumo*.whl"):
90
subprocess.check_call(["wheel", "unpack", "-d", f[:-4], f])
91
libsumo_dir = os.path.join(f[:-4], "-".join(os.path.basename(f).split("-")[:2]))
92
pack_dirs.append(libsumo_dir)
93
libsumo_so = os.path.join(libsumo_dir, "libsumo", "_libsumo.so")
94
libsumo_libs = fix_links_and_strip([libsumo_so], os.path.join(libsumo_dir, "libsumo"))
95
if compare_directories(data_libs, libsumo_libs):
96
shutil.rmtree(libsumo_libs)
97
else:
98
sys.exit("Lib mismatch.")
99
100
# packing resulting wheels
101
dest_dir = os.path.join(root, "relocate")
102
os.makedirs(dest_dir)
103
for pd in pack_dirs:
104
subprocess.check_call(["wheel", "pack", "-d", dest_dir, pd])
105
106