Skip to content

Commit 6970aef

Browse files
committed
build debug and release versions simultaneously
1 parent 081f3aa commit 6970aef

4 files changed

Lines changed: 75 additions & 32 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
*.zip
2+
*.tar.gz
3+
*.whl
14
*.svg
25
cmake_build/
36
wheelhouse/

hatch_build.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ def tag(self):
6363
plat = sysconfig.get_platform()
6464
return "py3-none-%s" % plat.replace("-", "_").replace(".", "_")
6565

66-
@cached_property
67-
def cmake_build_dir(self):
68-
p = Path(self.directory) / "cmake_build"
66+
def cmake_build_dir(self, config):
67+
p = Path(self.directory) / f"cmake_build_{config}"
6968
p.mkdir(parents=True, exist_ok=True)
7069
return p
7170

@@ -82,10 +81,10 @@ def cmake_install_dir(self):
8281
def ogdf_src_dir(self):
8382
return Path(self.root) / "ogdf"
8483

85-
def run(self, *args):
84+
def run(self, *args, dir):
8685
args = list(map(str, args))
8786
with group("Running", *args):
88-
return subprocess.run(args, capture_output=False, check=True, cwd=self.cmake_build_dir)
87+
return subprocess.run(args, capture_output=False, check=True, cwd=dir)
8988

9089
def dump_files(self, dir):
9190
with group("Index of", dir):
@@ -112,30 +111,43 @@ def initialize(self, version, build_data):
112111
del self.build_config.target_config["shared-data"]
113112

114113
with group("Config"):
114+
pprint({
115+
"root": self.root,
116+
"directory": self.directory,
117+
"ogdf_src_dir": self.ogdf_src_dir,
118+
"cmake_install_dir": self.cmake_install_dir,
119+
"cmake_build_dir debug": self.cmake_build_dir("debug"),
120+
"cmake_build_dir release": self.cmake_build_dir("release"),
121+
})
115122
pprint(build_data)
116123
pprint(self.build_config.__dict__)
117124

118125
flags = [
119-
"-DCMAKE_CONFIGURATION_TYPES=Debug;Release",
120-
"-DCMAKE_CROSS_CONFIGS=all", "-DCMAKE_DEFAULT_CONFIGS=all",
121126
"-DBUILD_SHARED_LIBS=ON",
122127
"-DCMAKE_INSTALL_PREFIX=%s" % self.cmake_install_dir,
123128
"-DOGDF_WARNING_ERRORS=OFF",
124129
"-DCMAKE_BUILD_RPATH=$ORIGIN;@loader_path", "-DCMAKE_INSTALL_RPATH=$ORIGIN;@loader_path",
125130
"-DMACOSX_RPATH=TRUE",
126-
"-DOGDF_USE_ASSERT_EXCEPTIONS=ON", # "-DOGDF_USE_ASSERT_EXCEPTIONS_WITH=ON_LIBUNWIND",
127131
"-DOGDF_MEMORY_MANAGER=POOL_TS", # "-DOGDF_MEMORY_MANAGER=MALLOC_TS", "-DOGDF_LEAK_CHECK=ON",
128132
]
129-
if not is_windows() and not is_macos(): # XCode and VS are multi-config by default
130-
flags.append("-G Ninja Multi-Config")
131-
self.run("cmake", self.ogdf_src_dir, *flags)
133+
134+
release_dir = self.cmake_build_dir("release")
135+
self.run("cmake", self.ogdf_src_dir, "-DCMAKE_BUILD_TYPE=Release", *flags, dir=release_dir)
136+
self.run("cmake", "--build", ".", "--parallel", str(multiprocessing.cpu_count()), dir=release_dir)
137+
self.run("cmake", "--install", ".", dir=release_dir)
138+
139+
if not is_windows():
140+
flags.extend([
141+
"-DOGDF_USE_ASSERT_EXCEPTIONS=ON", # "-DOGDF_USE_ASSERT_EXCEPTIONS_WITH=ON_LIBUNWIND",
142+
])
143+
debug_dir = self.cmake_build_dir("debug")
144+
self.run("cmake", self.ogdf_src_dir, "-DCMAKE_BUILD_TYPE=Debug", *flags, dir=debug_dir)
145+
self.run("cmake", "--build", ".", "--parallel", str(multiprocessing.cpu_count()), dir=debug_dir)
146+
self.run("cmake", "--install", ".", dir=debug_dir)
132147

133148
# import IPython
134149
# IPython.embed()
135150

136-
self.run("cmake", "--build", ".")
137-
self.run("cmake", "--install", ".")
138-
139151
self.dump_files(self.directory)
140152
self.dump_files(self.root)
141153

@@ -158,5 +170,6 @@ def clean(self, versions):
158170
the [`clean`](../cli/reference.md#hatch-clean) command.
159171
"""
160172
import shutil
161-
shutil.rmtree(self.cmake_build_dir)
162-
shutil.rmtree(self.cmake_install_dir)
173+
shutil.rmtree(self.cmake_build_dir("release"), ignore_errors=True)
174+
shutil.rmtree(self.cmake_build_dir("debug"), ignore_errors=True)
175+
shutil.rmtree(self.cmake_install_dir, ignore_errors=True)

test_contents.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,26 @@ def diff_dict_keys(a, b):
6262

6363

6464
def check_diff(tag, actual, expected, ign_a="", ign_e="", exp_a=[], win=False):
65+
"""
66+
:param tag: tag for logging
67+
:param actual: {filename: size} dict of actually found files
68+
:param expected: {filename: size} dict of expected files
69+
:param ign_a: regex for ignoring superfluous files that are in actual but not in expected
70+
:param ign_e: regex for ignoring missing files that are in expected but not in actual
71+
:param exp_a: list of additional file names that need to be present in actual, independent of expected
72+
:param win: on windows, we ignore file sizes
73+
"""
6574
global issues
6675
print("\tChecking", tag)
67-
if win:
68-
actual, expected = diff_dict_keys(actual, expected)
69-
else:
70-
actual, expected = diff_dicts(actual, expected)
7176
for e in exp_a:
7277
if e not in actual:
7378
print("\tMissing file %s in %s!" % (e, tag))
7479
issues += 1
80+
81+
if win: # ignore file sizes on windows
82+
actual, expected = diff_dict_keys(actual, expected)
83+
else:
84+
actual, expected = diff_dicts(actual, expected)
7585
sup = {k: v for k, v in actual.items() if not re.fullmatch(ign_a, k) and k not in exp_a}
7686
mis = {k: v for k, v in expected.items() if not re.fullmatch(ign_e, k)}
7787
if sup or mis:
@@ -91,7 +101,7 @@ def ignore(*ps):
91101
]
92102

93103

94-
def check_wheel(wheelp, ogdfp, name, tag):
104+
def check_wheel(wheelp, ogdfp, name, tag, config):
95105
name_esc = ignore(name)
96106
headers, others = {}, {}
97107
for k, v in ogdfp["include/"].items():
@@ -100,7 +110,8 @@ def check_wheel(wheelp, ogdfp, name, tag):
100110
else:
101111
others[k] = v
102112

103-
# _cur is the install location for the current platform (UNIX), _oth for the other (Windows)
113+
# _cur is the install location for the current target platform (default UNIX), _oth for the other (Windows)
114+
# only one of them will actually contain files, depending on the target platform
104115
incl_cur, incl_oth = wheelp[name + ".data/data/include/"], wheelp["ogdf_wheel/install/include/"]
105116
exam_cur, exam_oth = wheelp[name + ".data/data/share/doc/libogdf/examples/"], wheelp["ogdf_wheel/install/share/doc/libogdf/examples/"]
106117
check = check_diff
@@ -109,7 +120,11 @@ def check_wheel(wheelp, ogdfp, name, tag):
109120
exam_cur, exam_oth = exam_oth, exam_cur
110121
check = partial(check_diff, win=True)
111122

112-
check("wheel includes [cur]", incl_cur, headers, exp_a=["ogdf/basic/internal/config_autogen.h"])
123+
if config:
124+
check("wheel includes [cur]", incl_cur, headers, exp_a=[f"ogdf-{config}/ogdf/basic/internal/config_autogen.h"])
125+
else:
126+
check("wheel includes [cur]", incl_cur, headers,
127+
exp_a=["ogdf-debug/ogdf/basic/internal/config_autogen.h", "ogdf-release/ogdf/basic/internal/config_autogen.h"])
113128
check("wheel includes [oth]", incl_oth, {})
114129
check("wheel examples [cur]", exam_cur, ogdfp["doc/examples/"], ign_e=IGNORE_GIT + "|.*\\.dox")
115130
check("wheel examples [oth]", exam_oth, {})
@@ -121,21 +136,32 @@ def check_wheel(wheelp, ogdfp, name, tag):
121136
'ogdf/lib/minisat/doc/ReleaseNotes-2.2.0.txt': 3418,
122137
'ogdf/geometric/README.md': 321})
123138

124-
ign_meta = f"{name_esc}\\.dist-info/(METADATA|RECORD|WHEEL)|{name_esc}\\.data/data/lib/cmake/.*\.cmake"
139+
def expand_suffix(*paths, pre=""):
140+
ret = []
141+
if config != "release":
142+
ret.extend(pre + p.replace("{suffix}", "-debug") for p in paths)
143+
if config != "debug":
144+
ret.extend(pre + p.replace("{suffix}", "") for p in paths)
145+
return ret
146+
147+
ign_meta = f"{name_esc}\\.dist-info/(METADATA|RECORD|WHEEL)|{name_esc}\\.data/data/(lib/cmake|share/ogdf)/.*\\.cmake"
125148
exp_lic = [name + ".dist-info/licenses/" + f for f in LICENSES] + ['ogdf_wheel/__init__.py']
126149
if "win" in tag:
127150
check("wheel install [win]", wheelp["ogdf_wheel/install/"], {},
128-
ign_a="lib/cmake/.*\.cmake|lib/(COIN|OGDF)\.lib",
129-
exp_a=["bin/OGDF.dll"])
151+
ign_a="lib/cmake/.*\\.cmake|lib/(COIN|OGDF)" + ('(-debug)' if config != 'release' else '')
152+
+ ('' if config else '?') + "\\.lib",
153+
exp_a=expand_suffix("bin/OGDF{suffix}.dll"))
130154
check("wheel rest [win]", wheelp[""], {}, ign_a=ign_meta, exp_a=exp_lic)
131155
elif "macos" in tag:
132156
check("wheel rest [macos]", wheelp[""], {},
133157
ign_a=ign_meta,
134-
exp_a=[name + ".data/data/lib/libOGDF.dylib", name + ".data/data/lib/libCOIN.dylib", *exp_lic])
158+
exp_a=expand_suffix("libOGDF{suffix}.dylib", "libCOIN{suffix}.dylib", pre=name + ".data/data/lib/")
159+
+ exp_lic)
135160
else:
136161
check("wheel rest [linux]", wheelp[""], {},
137-
ign_a=ign_meta,
138-
exp_a=[name + ".data/data/lib/libOGDF.so", name + ".data/data/lib/libCOIN.so", *exp_lic])
162+
ign_a=ign_meta+f"|{name}.data/data/lib(64)?/lib.*\\.so\\.[0-9]+\\.[0-9]+",
163+
exp_a=expand_suffix("libOGDF{suffix}.so", "libCOIN{suffix}.so", pre=name + ".data/data/lib/")
164+
+ exp_lic)
139165

140166

141167
def check_sdist(sdistp, ogdff):
@@ -162,7 +188,8 @@ def dump_data(dumpdir, files, partitions, name):
162188
@click.option('--dist', type=click.Path(exists=True, file_okay=False), default=Path("dist"))
163189
@click.option('--ogdf', type=click.Path(exists=True, file_okay=False), default=Path("ogdf"))
164190
@click.option('--dump', type=click.Path(file_okay=False))
165-
def main(dist, ogdf, dump):
191+
@click.option('--config', default="")
192+
def main(dist, ogdf, dump, config):
166193
dist = Path(dist)
167194
ogdf = Path(ogdf)
168195
dump = Path(dump) if dump else dump
@@ -194,7 +221,7 @@ def main(dist, ogdf, dump):
194221
name + ".data/data/include/", name + ".data/data/share/doc/libogdf/examples/",
195222
"ogdf_wheel/install/include/", "ogdf_wheel/install/share/doc/libogdf/examples/", "ogdf_wheel/install/"])
196223
if dump: dump_data(dump, wheelf, wheelp, "wheel-%s" % wheel.name)
197-
check_wheel(wheelp, ogdfp, name, wheel.stem)
224+
check_wheel(wheelp, ogdfp, name, wheel.stem, config)
198225

199226
if issues:
200227
print("There were %s issue(s)!" % issues)

0 commit comments

Comments
 (0)