53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
![]() |
import tempfile
|
||
|
import sysconfig
|
||
|
import os.path
|
||
|
from distutils import ccompiler
|
||
|
|
||
|
|
||
|
__all__ = ["build_cxx"]
|
||
|
|
||
|
|
||
|
def build_cxx(*, cxx_sources, output_name, include_dirs, macros):
|
||
|
build_dir = tempfile.TemporaryDirectory(prefix="nmigen_cxx_")
|
||
|
|
||
|
cwd = os.getcwd()
|
||
|
try:
|
||
|
# Unforuntately, `ccompiler.compile` assumes the paths are relative, and interprets
|
||
|
# the directory name of the source path specially. That makes it necessary to build in
|
||
|
# the output directory directly.
|
||
|
os.chdir(build_dir.name)
|
||
|
|
||
|
cc_driver = ccompiler.new_compiler()
|
||
|
cc_driver.output_dir = "."
|
||
|
|
||
|
cc = sysconfig.get_config_var("CC")
|
||
|
cxx = sysconfig.get_config_var("CXX")
|
||
|
cflags = sysconfig.get_config_var("CCSHARED")
|
||
|
ld_ldflags = sysconfig.get_config_var("LDCXXSHARED")
|
||
|
cc_driver.set_executables(
|
||
|
compiler=f"{cc} {cflags}",
|
||
|
compiler_so=f"{cc} {cflags}",
|
||
|
compiler_cxx=f"{cxx} {cflags}",
|
||
|
linker_so=ld_ldflags,
|
||
|
)
|
||
|
|
||
|
for include_dir in include_dirs:
|
||
|
cc_driver.add_include_dir(include_dir)
|
||
|
for macro in macros:
|
||
|
cc_driver.define_macro(macro)
|
||
|
for cxx_filename, cxx_source in cxx_sources.items():
|
||
|
with open(cxx_filename, "w") as f:
|
||
|
f.write(cxx_source)
|
||
|
|
||
|
cxx_filenames = list(cxx_sources.keys())
|
||
|
obj_filenames = cc_driver.object_filenames(cxx_filenames)
|
||
|
so_filename = cc_driver.shared_object_filename(output_name)
|
||
|
|
||
|
cc_driver.compile(cxx_filenames)
|
||
|
cc_driver.link_shared_object(obj_filenames, output_filename=so_filename, target_lang="c++")
|
||
|
|
||
|
return build_dir, so_filename
|
||
|
|
||
|
finally:
|
||
|
os.chdir(cwd)
|