Skip to content

Commit 41edd8a

Browse files
committed
improved library loading
1 parent eed65a8 commit 41edd8a

File tree

2 files changed

+72
-43
lines changed

2 files changed

+72
-43
lines changed

src/ogdf_python/info.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,6 @@
11
from ogdf_python.loader import *
22

3-
__all__ = ["get_ogdf_info", "get_macro"]
4-
5-
6-
def get_macro(m):
7-
cppdef("""
8-
#define STR(str) #str
9-
#define STRING(str) STR(str)
10-
namespace get_macro {{
11-
#ifdef {m}
12-
std::string var_{m} = STRING({m});
13-
#endif
14-
}};
15-
""".format(m=m))
16-
val = getattr(cppyy.gbl.get_macro, "var_%s" % m, None)
17-
if val is not None:
18-
val = val.decode("ascii")
19-
return val
3+
__all__ = ["get_ogdf_info"]
204

215

226
def conf_which(n):
@@ -33,13 +17,15 @@ def conf_which(n):
3317

3418
def get_ogdf_info():
3519
from ogdf_python import __version__
20+
from ogdf_python.loader import CONFIG
3621
cppinclude("ogdf/basic/System.h")
3722
data = {
3823
"ogdf_path": get_loaded_library_path() or "unknown",
3924
"ogdf_include_path": get_base_include_path() or "unknown",
4025
"ogdf_config_include_path": get_base_include_path("ogdf/basic/internal/config_autogen.h") or "unknown",
4126
"ogdf_version": get_macro("OGDF_VERSION").strip('"'),
4227
"ogdf_python_version": __version__,
28+
"ogdf_python_config": CONFIG,
4329
"ogdf_debug": get_macro("OGDF_DEBUG") is not None,
4430
"ogdf_build_debug": ogdf.debugMode,
4531
"debug": get_macro("NDEBUG") is None,

src/ogdf_python/loader.py

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,18 @@
3030

3131
cppyy.ll.set_signals_as_exception(True)
3232
CONFIG = os.getenv("OGDF_PYTHON_MODE", "release")
33-
if CONFIG not in ("release", "debug"):
34-
warnings.warn(f"Environment variable OGDF_PYTHON_MODE set to '{CONFIG}' instead of 'debug' or 'release'.")
33+
IS_DEBUG = CONFIG.lower() == "debug"
34+
CONFIG_RD = "debug" if IS_DEBUG else "release"
3535

3636

3737
## Search Utils
3838

3939
def get_library_path(name=None):
4040
if name is None:
41-
if CONFIG == "release":
42-
return get_library_path("OGDF") or get_library_path("libOGDF")
41+
if IS_DEBUG:
42+
return get_library_path("OGDF-debug") or get_library_path("libOGDF-debug")
4343
else:
44-
return get_library_path(f"OGDF-{CONFIG}") or get_library_path(f"libOGDF-{CONFIG}")
44+
return get_library_path("OGDF") or get_library_path("libOGDF")
4545
return cppyy.gbl.gSystem.FindDynamicLibrary(cppyy.gbl.CppyyLegacy.TString(name), True)
4646

4747

@@ -73,6 +73,24 @@ def call_if_exists(func, path):
7373
return False
7474

7575

76+
def get_macro(m):
77+
var_name = "var_%s" % m
78+
if not hasattr(cppyy.gbl, "get_macro") or not hasattr(cppyy.gbl.get_macro, var_name):
79+
cppyy.cppdef("""
80+
#define STR(str) #str
81+
#define STRING(str) STR(str)
82+
namespace get_macro {{
83+
#ifdef {m}
84+
std::string var_{m} = STRING({m});
85+
#endif
86+
}};
87+
""".format(m=m))
88+
val = getattr(cppyy.gbl.get_macro, var_name, None)
89+
if val is not None:
90+
val = val.decode("ascii")
91+
return val
92+
93+
7694
## Setup Search Paths
7795

7896
if "OGDF_INSTALL_DIR" in os.environ:
@@ -84,16 +102,36 @@ def call_if_exists(func, path):
84102
cppyy.add_include_path(str(INSTALL_DIR / "include"))
85103

86104
if "OGDF_BUILD_DIR" in os.environ:
87-
BUILD_DIR = Path(os.getenv("OGDF_BUILD_DIR")).absolute()
88-
cppyy.add_library_path(str(BUILD_DIR))
89-
call_if_exists(cppyy.add_library_path, BUILD_DIR / "Debug")
90-
call_if_exists(cppyy.add_library_path, BUILD_DIR / "Release")
91-
cppyy.add_include_path(str(BUILD_DIR / "include"))
92-
for line in open(BUILD_DIR / "CMakeCache.txt"):
93-
line = line.strip()
94-
if line.startswith("OGDF-PROJECT_SOURCE_DIR"):
95-
key, _, val = line.partition("=")
96-
cppyy.add_include_path(str(Path(val) / "include"))
105+
BUILD_TARGETS = Path(os.getenv("OGDF_BUILD_DIR")) / "OgdfTargets.cmake"
106+
if BUILD_TARGETS.is_file():
107+
values = {}
108+
active = False
109+
for line in BUILD_TARGETS.open():
110+
line = line.strip()
111+
if active:
112+
if line == ")":
113+
active = False
114+
else:
115+
pref, _, suff = line.partition(" ")
116+
values[pref] = suff.strip('"')
117+
elif line == "set_target_properties(OGDF PROPERTIES":
118+
active = True
119+
120+
includes =values.get("INTERFACE_INCLUDE_DIRECTORIES",None)
121+
if includes:
122+
includes = includes.replace(r"\$<IF:\$<CONFIG:Debug>,debug,release>", CONFIG_RD)
123+
for s in includes.split(";"):
124+
cppyy.add_include_path(s)
125+
else:
126+
warnings.warn("$OGDF_BUILD_DIR/OgdfTargets.cmake does not specify INTERFACE_INCLUDE_DIRECTORIES for OGDF.")
127+
location = values.get("IMPORTED_LOCATION_" + CONFIG.upper(), None)
128+
if location:
129+
cppyy.add_library_path(str(Path(location).parent))
130+
else:
131+
warnings.warn("$OGDF_BUILD_DIR/OgdfTargets.cmake does not specify IMPORTED_LOCATION_${OGDF_PYTHON_MODE}"
132+
f" for mode {CONFIG.upper()}.")
133+
else:
134+
warnings.warn("Environment variable OGDF_BUILD_DIR set, but $OGDF_BUILD_DIR/OgdfTargets.cmake not found.")
97135

98136
try:
99137
wheel_inst_dir = importlib_resources.files("ogdf_wheel") / "install"
@@ -106,23 +144,23 @@ def call_if_exists(func, path):
106144
## Now do the actual loading
107145

108146
cppyy.cppdef("#undef NDEBUG")
109-
if CONFIG == "release":
147+
if not IS_DEBUG:
110148
cppyy.cppdef("#define NDEBUG")
111149
cppyy.include("cassert")
112150
cppyy.cppdef("#define OGDF_INSTALL")
113151

114152
try:
115-
if CONFIG == "release":
153+
if IS_DEBUG:
154+
cppyy.load_library("COIN-debug")
155+
cppyy.load_library("OGDF-debug")
156+
else:
116157
cppyy.load_library("COIN")
117158
cppyy.load_library("OGDF")
118-
else:
119-
cppyy.load_library(f"COIN-{CONFIG}")
120-
cppyy.load_library(f"OGDF-{CONFIG}")
121159

122160
config_autogen_h = "ogdf/basic/internal/config_autogen.h"
123161
if not get_include_path(config_autogen_h):
124162
# try to find the config-dependent header include path if it isn't correctly configured yet
125-
config_include = get_include_path(f"ogdf-{CONFIG}/{config_autogen_h}")
163+
config_include = get_include_path(f"ogdf-{CONFIG_RD}/{config_autogen_h}")
126164
if config_include:
127165
config_include = config_include.removesuffix(config_autogen_h)
128166
cppyy.add_include_path(config_include)
@@ -143,17 +181,22 @@ def call_if_exists(func, path):
143181
f"The current include path is:\n{cppyy.gbl.gInterpreter.GetIncludePath()}\n"
144182
) from e
145183

146-
if CONFIG == "release":
147-
if cppyy.gbl.ogdf.debugMode:
148-
warnings.warn("Attempted to load OGDF release build, but the found library was built in debug mode.")
149-
else:
184+
if IS_DEBUG:
150185
if not cppyy.gbl.ogdf.debugMode:
151186
warnings.warn("Attempted to load OGDF debug build, but the found library was built in release mode.")
187+
if get_macro("OGDF_DEBUG") is None:
188+
warnings.warn("Attempted to load OGDF debug build, but the found headers are for release mode.")
189+
else:
190+
if cppyy.gbl.ogdf.debugMode:
191+
warnings.warn("Attempted to load OGDF release build, but the found library was built in debug mode.")
192+
if get_macro("OGDF_DEBUG") is not None:
193+
warnings.warn("Attempted to load OGDF release build, but the found headers are for debug mode.")
152194

153195
## Load re-exports
154196
from cppyy import include as cppinclude, cppdef, cppexec, nullptr
155197
from cppyy.gbl import ogdf
156198

157199
__all__ = ["cppyy", "cppinclude", "cppdef", "cppexec", "nullptr", "ogdf",
158-
"get_library_path", "get_loaded_library_path", "get_include_path", "get_base_include_path"]
200+
"get_library_path", "get_loaded_library_path", "get_include_path", "get_base_include_path",
201+
"get_macro"]
159202
__keep_imports = [cppyy, cppinclude, cppdef, cppexec, nullptr, ogdf]

0 commit comments

Comments
 (0)