Skip to content

Commit

Permalink
Update and refine windows tools (#257)
Browse files Browse the repository at this point in the history
* update windows compiler handling

* change compiler order

Co-authored-by: ahartikainen <ahartikainen@github.com>
  • Loading branch information
ahartikainen and ahartikainen committed Aug 4, 2020
1 parent 1bb4010 commit 62a6f8c
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 31 deletions.
32 changes: 32 additions & 0 deletions cmdstanpy/install_cmdstan.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Optional command line arguments:
-v, --version : version, defaults to latest
-d, --dir : install directory, defaults to '~/.cmdstanpy
-c --compiler : add C++ compiler to path (Windows only)
"""
import argparse
import contextlib
Expand Down Expand Up @@ -186,6 +187,13 @@ def main():
parser = argparse.ArgumentParser()
parser.add_argument('--version', '-v')
parser.add_argument('--dir', '-d')
if platform.system() == 'Windows':
# use compiler installed with install_cxx_toolchain
# Install a new compiler if compiler not found
# Search order is RTools40, RTools35
parser.add_argument(
'--compiler', '-c', dest='compiler', action='store_true'
)
args = parser.parse_args(sys.argv[1:])

version = vars(args)['version']
Expand All @@ -199,6 +207,30 @@ def main():
validate_dir(install_dir)
print('Install directory: {}'.format(install_dir))

if platform.system() == 'Windows' and vars(args)['compiler']:
from .install_cxx_toolchain import (
main as _main_cxx,
is_installed as _is_installed_cxx,
)
from .utils import cxx_toolchain_path

cxx_loc = os.path.expanduser(os.path.join('~', '.cmdstanpy'))
compiler_found = False
for cxx_version in ['40', '35']:
if _is_installed_cxx(cxx_loc, cxx_version):
compiler_found = True
break
if not compiler_found:
print('Installing RTools40')
# copy argv and clear sys.argv
original_argv = sys.argv[:]
sys.argv = sys.argv[:1]
_main_cxx()
sys.argv = original_argv
cxx_version = '40'
# Add toolchain to $PATH
cxx_toolchain_path(cxx_version)

cmdstan_version = 'cmdstan-{}'.format(version)
with pushd(install_dir):
if not os.path.exists(cmdstan_version):
Expand Down
10 changes: 7 additions & 3 deletions cmdstanpy/install_cxx_toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,12 @@ def install_mingw32_make(toolchain_loc):
list(
OrderedDict.fromkeys(
[
os.path.join(
toolchain_loc,
'mingw_64' if IS_64BITS else 'mingw_32',
'bin',
),
os.path.join(toolchain_loc, 'usr', 'bin'),
os.path.join(toolchain_loc, 'mingw64', 'bin'),
]
+ os.environ.get('PATH', '').split(';')
)
Expand Down Expand Up @@ -152,7 +156,7 @@ def install_mingw32_make(toolchain_loc):
def is_installed(toolchain_loc, version):
"""Returns True is toolchain is installed."""
if platform.system() == 'Windows':
if version == '3.5':
if version in ['35', '3.5']:
if not os.path.exists(os.path.join(toolchain_loc, 'bin')):
return False
return os.path.exists(
Expand All @@ -163,7 +167,7 @@ def is_installed(toolchain_loc, version):
'g++' + EXTENSION,
)
)
elif version == '4.0':
elif version in ['40', '4.0', '4']:
return os.path.exists(
os.path.join(
toolchain_loc,
Expand Down
69 changes: 41 additions & 28 deletions cmdstanpy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,112 +214,125 @@ def cxx_toolchain_path(version: str = None) -> Tuple[str]:
toolchain_root = ''
if 'CMDSTAN_TOOLCHAIN' in os.environ:
toolchain_root = os.environ['CMDSTAN_TOOLCHAIN']
if os.path.exists(os.path.join(toolchain_root, 'mingw_64')):
if os.path.exists(os.path.join(toolchain_root, 'mingw64')):
compiler_path = os.path.join(
toolchain_root,
'mingw_64' if (sys.maxsize > 2 ** 32) else 'mingw_32',
'mingw64' if (sys.maxsize > 2 ** 32) else 'mingw32',
'bin',
)
if os.path.exists(compiler_path):
tool_path = os.path.join(toolchain_root, 'bin')
tool_path = os.path.join(toolchain_root, 'usr', 'bin')
if not os.path.exists(tool_path):
tool_path = ''
compiler_path = ''
logger.warning(
'Found invalid installion for RTools35 on %s',
'Found invalid installion for RTools40 on %s',
toolchain_root,
)
toolchain_root = ''
else:
compiler_path = ''
logger.warning(
'Found invalid installion for RTools35 on %s',
'Found invalid installion for RTools40 on %s',
toolchain_root,
)
toolchain_root = ''
elif os.path.exists(os.path.join(toolchain_root, 'mingw64')):

elif os.path.exists(os.path.join(toolchain_root, 'mingw_64')):
compiler_path = os.path.join(
toolchain_root,
'mingw64' if (sys.maxsize > 2 ** 32) else 'mingw32',
'mingw_64' if (sys.maxsize > 2 ** 32) else 'mingw_32',
'bin',
)
if os.path.exists(compiler_path):
tool_path = os.path.join(toolchain_root, 'usr', 'bin')
tool_path = os.path.join(toolchain_root, 'bin')
if not os.path.exists(tool_path):
tool_path = ''
compiler_path = ''
logger.warning(
'Found invalid installion for RTools40 on %s',
'Found invalid installion for RTools35 on %s',
toolchain_root,
)
toolchain_root = ''
else:
compiler_path = ''
logger.warning(
'Found invalid installion for RTools40 on %s',
'Found invalid installion for RTools35 on %s',
toolchain_root,
)
toolchain_root = ''
else:
rtools_dir = os.path.expanduser(
os.path.join('~', '.cmdstanpy', 'RTools')
os.path.join('~', '.cmdstanpy', 'RTools40')
)
if not os.path.exists(rtools_dir):
raise ValueError(
'no RTools installation found, '
'run command line script "install_cxx_toolchain"'
rtools_dir = os.path.expanduser(
os.path.join('~', '.cmdstanpy', 'RTools35')
)
if not os.path.exists(rtools_dir):
rtools_dir = os.path.expanduser(
os.path.join('~', '.cmdstanpy', 'RTools')
)
if not os.path.exists(rtools_dir):
raise ValueError(
'no RTools installation found, '
'run command line script "install_cxx_toolchain"'
)
else:
rtools_dir = os.path.expanduser(os.path.join('~', '.cmdstanpy'))
else:
rtools_dir = os.path.expanduser(os.path.join('~', '.cmdstanpy'))
compiler_path = ''
tool_path = ''
if version not in ('4', '40', '4.0') and os.path.exists(
os.path.join(rtools_dir, 'RTools35')
if version not in ('35', '3.5', '3') and os.path.exists(
os.path.join(rtools_dir, 'RTools40')
):
toolchain_root = os.path.join(rtools_dir, 'RTools35')
toolchain_root = os.path.join(rtools_dir, 'RTools40')
compiler_path = os.path.join(
toolchain_root,
'mingw_64' if (sys.maxsize > 2 ** 32) else 'mingw_32',
'mingw64' if (sys.maxsize > 2 ** 32) else 'mingw32',
'bin',
)
if os.path.exists(compiler_path):
tool_path = os.path.join(toolchain_root, 'bin')
tool_path = os.path.join(toolchain_root, 'usr', 'bin')
if not os.path.exists(tool_path):
tool_path = ''
compiler_path = ''
logger.warning(
'Found invalid installion for RTools35 on %s',
'Found invalid installation for RTools40 on %s',
toolchain_root,
)
toolchain_root = ''
else:
compiler_path = ''
logger.warning(
'Found invalid installion for RTools35 on %s',
'Found invalid installation for RTools40 on %s',
toolchain_root,
)
toolchain_root = ''
if (
not toolchain_root or version in ('4', '40', '4.0')
) and os.path.exists(os.path.join(rtools_dir, 'RTools40')):
toolchain_root = os.path.join(rtools_dir, 'RTools40')
) and os.path.exists(os.path.join(rtools_dir, 'RTools35')):
toolchain_root = os.path.join(rtools_dir, 'RTools35')
compiler_path = os.path.join(
toolchain_root,
'mingw64' if (sys.maxsize > 2 ** 32) else 'mingw32',
'mingw_64' if (sys.maxsize > 2 ** 32) else 'mingw_32',
'bin',
)
if os.path.exists(compiler_path):
tool_path = os.path.join(toolchain_root, 'usr', 'bin')
tool_path = os.path.join(toolchain_root, 'bin')
if not os.path.exists(tool_path):
tool_path = ''
compiler_path = ''
logger.warning(
'Found invalid installion for RTools40 on %s',
'Found invalid installation for RTools35 on %s',
toolchain_root,
)
toolchain_root = ''
else:
compiler_path = ''
logger.warning(
'Found invalid installion for RTools40 on %s',
'Found invalid installation for RTools35 on %s',
toolchain_root,
)
toolchain_root = ''
Expand All @@ -328,7 +341,7 @@ def cxx_toolchain_path(version: str = None) -> Tuple[str]:
'no C++ toolchain installation found, '
'run command line script "install_cxx_toolchain"'
)
logger.info('Adds C++ toolchain to $PATH: %s', toolchain_root)
logger.info('Add C++ toolchain to $PATH: %s', toolchain_root)
os.environ['PATH'] = ';'.join(
list(
OrderedDict.fromkeys(
Expand Down

0 comments on commit 62a6f8c

Please sign in to comment.