Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SCons] Change prefix default if conda is detected #1191

Merged
merged 5 commits into from
Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,8 @@ jobs:
cython boost-cpp fmt eigen yaml-cpp h5py pandas libgomp openblas pytest
- name: Build Cantera
run: |
scons build extra_inc_dirs=$CONDA_PREFIX/include:$CONDA_PREFIX/include/eigen3 \
extra_lib_dirs=$CONDA_PREFIX/lib system_fmt=y system_eigen=y system_yamlcpp=y \
system_sundials=y blas_lapack_libs='lapack,blas' -j2 VERBOSE=True debug=n \
scons build system_fmt=y system_eigen=y system_yamlcpp=y system_sundials=y \
blas_lapack_libs='lapack,blas' -j2 VERBOSE=True debug=n \
optimize_flags='-O3 -ffast-math -fno-finite-math-only'
- name: Test Cantera
run: scons test show_long_tests=yes verbose_tests=yes
Expand Down
134 changes: 93 additions & 41 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,12 @@ config_options = [
}),
PathOption(
"prefix",
"""Set this to the directory where Cantera should be installed. On Windows
systems, '$ProgramFiles' typically refers to "C:\Program Files".""",
"""Set this to the directory where Cantera should be installed. If the Python
executable found during compilation is managed by 'conda', the installation
'prefix' defaults to the corresponding environment and the 'conda' layout
will be used for installation (specifying any of the options 'prefix',
'python_prefix', 'python_cmd' or 'layout' will override this default). On
Windows systems, '$ProgramFiles' typically refers to "C:\Program Files".""",
ischoegl marked this conversation as resolved.
Show resolved Hide resolved
{"Windows": "$ProgramFiles\Cantera", "default": "/usr/local"},
PathVariable.PathAccept),
PathOption(
Expand Down Expand Up @@ -483,12 +487,16 @@ config_options = [
Option(
"extra_inc_dirs",
"""Additional directories to search for header files, with multiple
directories separated by colons (*nix, macOS) or semicolons (Windows)""",
directories separated by colons (*nix, macOS) or semicolons (Windows).
If an active 'conda' environment is detected, the corresponding include
path is automatically added.""",
""),
Option(
"extra_lib_dirs",
"""Additional directories to search for libraries, with multiple
directories separated by colons (*nix, macOS) or semicolons (Windows)""",
directories separated by colons (*nix, macOS) or semicolons (Windows).
If an active 'conda' environment is detected, the corresponding library
path is automatically added.""",
""),
PathOption(
"boost_inc_dir",
Expand Down Expand Up @@ -550,12 +558,17 @@ config_options = [
"""The layout of the directory structure. 'standard' installs files to
several subdirectories under 'prefix', for example, 'prefix/bin',
'prefix/include/cantera', 'prefix/lib' etc. This layout is best used in
conjunction with "prefix='/usr/local'". 'compact' puts all installed
files in the subdirectory defined by 'prefix'. This layout is best
with a prefix like '/opt/cantera'. 'debian' installs to the stage
directory in a layout used for generating Debian packages.""",
conjunction with "prefix='/usr/local'". 'compact' puts all installed files
in the subdirectory defined by 'prefix'. This layout is best with a prefix
like '/opt/cantera'. 'debian' installs to the stage directory in a layout
used for generating Debian packages. If the Python executable found during
compilation is managed by 'conda', the layout will default to 'conda'
irrespective of operating system. For the 'conda' layout, the Python package
as well as all libraries and header files are installed into the active
'conda' environment. Input data, samples, and other files are installed in
the 'shared/cantera' subdirectory of the active 'conda' environment.""",
{"Windows": "compact", "default": "standard"},
("standard", "compact", "debian")),
("standard", "compact", "debian", "conda")),
ischoegl marked this conversation as resolved.
Show resolved Hide resolved
BoolOption(
"fast_fail_tests",
"If enabled, tests will exit at the first failure.",
Expand Down Expand Up @@ -866,10 +879,10 @@ except subprocess.CalledProcessError:
env["git_commit"] = "unknown"

# Print values of all build options:
print("Configuration variables read from 'cantera.conf' and command line:")
for line in open('cantera.conf'):
print(' ', line.strip())
print()
# the (updated) "cantera.conf" combines all options that were specified by the user
cantera_conf = Path("cantera.conf").read_text()
logger.info("Configuration variables read from 'cantera.conf' and command line:")
logger.info(textwrap.indent(cantera_conf, " "), print_level=False)

# ********************************************
# *** Configure system-specific properties ***
Expand Down Expand Up @@ -905,6 +918,19 @@ if os.pathsep == ';':
env['extra_inc_dirs'] = [d for d in env['extra_inc_dirs'].split(os.pathsep) if d]
env['extra_lib_dirs'] = [d for d in env['extra_lib_dirs'].split(os.pathsep) if d]

# Add conda library/include paths (if applicable) to extra
conda_prefix = os.environ.get("CONDA_PREFIX")
if conda_prefix is not None:
if os.name == "nt":
conda_inc_dir = pjoin(conda_prefix, "Library", "include")
conda_lib_dir = pjoin(conda_prefix, "Library", env["libdirname"])
else:
conda_inc_dir = pjoin(conda_prefix, "include")
conda_lib_dir = pjoin(conda_prefix, env["libdirname"])
env["extra_inc_dirs"].append(conda_inc_dir)
env["extra_lib_dirs"].append(conda_lib_dir)
ischoegl marked this conversation as resolved.
Show resolved Hide resolved
logger.info(f"Adding conda include and library paths: {conda_prefix}")

env.Append(CPPPATH=env['extra_inc_dirs'],
LIBPATH=env['extra_lib_dirs'])

Expand Down Expand Up @@ -1626,26 +1652,65 @@ if env['matlab_toolbox'] == 'y':
# /usr/local because of dist-packages vs site-packages
env['debian'] = any(name.endswith('dist-packages') for name in sys.path)

# Identify options selected either on command line or in cantera.conf
selected_options = set(line.split("=")[0].strip()
for line in cantera_conf.splitlines())

# Check whether Cantera should be installed into a conda environment
if conda_prefix is not None:
if env["layout"] != "conda" and sys.executable.startswith(conda_prefix):
# use conda layout unless any 'blocking' options were specified
blocking_options = {"layout", "prefix", "python_prefix", "python_cmd"}
if not selected_options & blocking_options:
env["layout"] = "conda"
logger.info(
f"Using conda environment as default 'prefix': {conda_prefix}")
elif env["layout"] == "conda":
logger.error("Layout option 'conda' requires a conda environment.")
sys.exit(1)

# Directories where things will be after actually being installed. These
# variables are the ones that are used to populate header files, scripts, etc.
env['prefix'] = os.path.normpath(env['prefix'])
env['ct_installroot'] = env['prefix']
env['ct_libdir'] = pjoin(env['prefix'], env['libdirname'])
env['ct_bindir'] = pjoin(env['prefix'], 'bin')
env['ct_incdir'] = pjoin(env['prefix'], 'include', 'cantera')
env['ct_incroot'] = pjoin(env['prefix'], 'include')
if env["layout"] == "conda":
if "stage_dir" in selected_options:
conda_prefix = Path(conda_prefix)
env["prefix"] = str(conda_prefix.relative_to(conda_prefix.parents[2]))
else:
env["prefix"] = os.path.normpath(conda_prefix)

if env["layout"] == "conda" and os.name == "nt":
env["ct_libdir"] = pjoin(env["prefix"], "Library", env["libdirname"])
env["ct_bindir"] = pjoin(env["prefix"], "Scripts")
env["ct_python_bindir"] = pjoin(env["prefix"], "Scripts")
env["ct_incdir"] = pjoin(env["prefix"], "Library", "include", "cantera")
env["ct_incroot"] = pjoin(env["prefix"], "Library", "include")
else:
env["prefix"] = os.path.normpath(env["prefix"])
env["ct_libdir"] = pjoin(env["prefix"], env["libdirname"])
env["ct_bindir"] = pjoin(env["prefix"], "bin")
env["ct_python_bindir"] = pjoin(env["prefix"], "bin")
env["ct_incdir"] = pjoin(env["prefix"], "include", "cantera")
env["ct_incroot"] = pjoin(env["prefix"], "include")

env["ct_installroot"] = env["prefix"]
ischoegl marked this conversation as resolved.
Show resolved Hide resolved

if env['layout'] == 'compact':
env['ct_datadir'] = pjoin(env['prefix'], 'data')
env['ct_sampledir'] = pjoin(env['prefix'], 'samples')
env["ct_docdir"] = pjoin(env["prefix"], "doc")
env['ct_mandir'] = pjoin(env['prefix'], 'man1')
env['ct_matlab_dir'] = pjoin(env['prefix'], 'matlab', 'toolbox')
else:
env['ct_datadir'] = pjoin(env['prefix'], 'share', 'cantera', 'data')
env['ct_sampledir'] = pjoin(env['prefix'], 'share', 'cantera', 'samples')
env["ct_docdir"] = pjoin(env["prefix"], "share", "cantera", "doc")
env['ct_mandir'] = pjoin(env['prefix'], 'share', 'man', 'man1')
env['ct_matlab_dir'] = pjoin(env['prefix'], env['libdirname'],
'cantera', 'matlab', 'toolbox')
if env["layout"] == "conda":
env["ct_matlab_dir"] = pjoin(
env["prefix"], "share", "cantera", "matlab", "toolbox")
else:
env["ct_matlab_dir"] = pjoin(
env["prefix"], env["libdirname"], "cantera", "matlab", "toolbox")

# Always set the stage directory before building an MSI installer
if 'msi' in COMMAND_LINE_TARGETS:
Expand Down Expand Up @@ -1673,7 +1738,7 @@ if env["stage_dir"]:
if stage_prefix.is_absolute():
stage_prefix = Path(*stage_prefix.parts[1:])

instRoot = Path.cwd().joinpath(env["stage_dir"], stage_prefix)
instRoot = str(Path.cwd().joinpath(env["stage_dir"], stage_prefix))
else:
instRoot = env["prefix"]

Expand All @@ -1684,6 +1749,7 @@ if os.path.abspath(instRoot) == Dir('.').abspath:

if env['layout'] == 'debian':
base = pjoin(os.getcwd(), 'debian')
env["inst_root"] = base

env['inst_libdir'] = pjoin(base, 'cantera-dev', 'usr', env['libdirname'])
env['inst_incdir'] = pjoin(base, 'cantera-dev', 'usr', 'include', 'cantera')
Expand All @@ -1701,25 +1767,11 @@ if env['layout'] == 'debian':
env['inst_python_bindir'] = pjoin(base, 'cantera-python', 'usr', 'bin')
env['python_prefix'] = pjoin(base, 'cantera-python3')
else:
env['inst_libdir'] = pjoin(instRoot, env['libdirname'])
env['inst_bindir'] = pjoin(instRoot, 'bin')
env['inst_python_bindir'] = pjoin(instRoot, 'bin')
env['inst_incdir'] = pjoin(instRoot, 'include', 'cantera')
env['inst_incroot'] = pjoin(instRoot, 'include')

if env['layout'] == 'compact':
env['inst_matlab_dir'] = pjoin(instRoot, 'matlab', 'toolbox')
env['inst_datadir'] = pjoin(instRoot, 'data')
env['inst_sampledir'] = pjoin(instRoot, 'samples')
env['inst_docdir'] = pjoin(instRoot, 'doc')
env['inst_mandir'] = pjoin(instRoot, 'man1')
else: # env['layout'] == 'standard'
env['inst_matlab_dir'] = pjoin(instRoot, env['libdirname'], 'cantera',
'matlab', 'toolbox')
env['inst_datadir'] = pjoin(instRoot, 'share', 'cantera', 'data')
env['inst_sampledir'] = pjoin(instRoot, 'share', 'cantera', 'samples')
env['inst_docdir'] = pjoin(instRoot, 'share', 'cantera', 'doc')
env['inst_mandir'] = pjoin(instRoot, 'share', 'man', 'man1')
env["inst_root"] = instRoot
locations = ["libdir", "bindir", "python_bindir", "incdir", "incroot",
"matlab_dir", "datadir", "sampledir", "docdir", "mandir"]
for loc in locations:
env[f"inst_{loc}"] = env[f"ct_{loc}"].replace(env["ct_installroot"], instRoot)

# **************************************
# *** Set options needed in config.h ***
Expand Down