boost package: fix Windows build (#43732)
* Boost:Adjust bootstrapping/b2 options as needed for Windows (the bootstrapping phase sufficiently differs between Windows/Unix that it is handled entirely within its own branch). * Boost: Paths in user-config.jam should be POSIX, including on Windows * Python: `.libs` for the Python package should return link libraries on Windows. The libraries are also stored in a different directory.
This commit is contained in:
parent
e1da0a7312
commit
fc4a4ec70d
@ -5,6 +5,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from spack.package import *
|
||||
|
||||
@ -303,6 +304,11 @@ def libs(self):
|
||||
# safe to do so on affected platforms.
|
||||
conflicts("+clanglibcpp", when="@1.85: +stacktrace")
|
||||
|
||||
# On Windows, the signals variant is required when building any of
|
||||
# the all_libs variants.
|
||||
for lib in all_libs:
|
||||
requires("+signals", when=f"+{lib} platform=windows")
|
||||
|
||||
# Patch fix from https://svn.boost.org/trac/boost/ticket/11856
|
||||
patch("boost_11856.patch", when="@1.60.0%gcc@4.4.7")
|
||||
|
||||
@ -495,9 +501,9 @@ def bjam_python_line(self, spec):
|
||||
|
||||
return "using python : {0} : {1} : {2} : {3} ;\n".format(
|
||||
spec["python"].version.up_to(2),
|
||||
spec["python"].command.path,
|
||||
spec["python"].headers.directories[0],
|
||||
spec["python"].libs[0],
|
||||
Path(spec["python"].command.path).as_posix(),
|
||||
Path(spec["python"].headers.directories[0]).as_posix(),
|
||||
Path(spec["python"].libs[0]).parent.as_posix(),
|
||||
)
|
||||
|
||||
def determine_bootstrap_options(self, spec, with_libs, options):
|
||||
@ -521,6 +527,9 @@ def determine_bootstrap_options(self, spec, with_libs, options):
|
||||
else:
|
||||
options.append("--without-icu")
|
||||
|
||||
self.write_jam_file(spec, boost_toolset_id)
|
||||
|
||||
def write_jam_file(self, spec, boost_toolset_id=None):
|
||||
with open("user-config.jam", "w") as f:
|
||||
# Boost may end up using gcc even though clang+gfortran is set in
|
||||
# compilers.yaml. Make sure this does not happen:
|
||||
@ -535,7 +544,7 @@ def determine_bootstrap_options(self, spec, with_libs, options):
|
||||
# similar, but that doesn't work with the Cray compiler
|
||||
# wrappers. Since Boost doesn't use the MPI C++ bindings,
|
||||
# that can be used as a compiler option instead.
|
||||
mpi_line = "using mpi : %s" % spec["mpi"].mpicxx
|
||||
mpi_line = "using mpi : %s" % Path(spec["mpi"].mpicxx).as_posix()
|
||||
f.write(mpi_line + " ;\n")
|
||||
|
||||
if spec.satisfies("+python"):
|
||||
@ -608,6 +617,16 @@ def determine_b2_options(self, spec, options):
|
||||
|
||||
options.extend(["link=%s" % ",".join(link_types), "--layout=%s" % layout])
|
||||
|
||||
if spec.satisfies("platform=windows"):
|
||||
# The runtime link must either be shared or static, not both.
|
||||
if "+shared" in spec:
|
||||
options.append("runtime-link=shared")
|
||||
else:
|
||||
options.append("runtime-link=static")
|
||||
for lib in self.all_libs:
|
||||
if f"+{lib}" not in spec:
|
||||
options.append(f"--without-{lib}")
|
||||
|
||||
if not spec.satisfies("@:1.75 %intel") and not spec.satisfies("platform=windows"):
|
||||
# When building any version >= 1.76, the toolset must be specified.
|
||||
# Earlier versions could not specify Intel as the toolset
|
||||
@ -671,6 +690,23 @@ def add_buildopt_symlinks(self, prefix):
|
||||
prefix, remainder = lib.split(".", 1)
|
||||
symlink(lib, "%s-mt.%s" % (prefix, remainder))
|
||||
|
||||
def bootstrap_windows(self):
|
||||
"""Run the Windows-specific bootstrap.bat. The only bootstrapping command
|
||||
line option that is accepted by the bootstrap.bat script is the compiler
|
||||
information: either the vc version (e.g. MSVC 14.3.x would be vc143)
|
||||
or gcc or clang.
|
||||
"""
|
||||
bootstrap_options = list()
|
||||
if self.spec.satisfies("%msvc"):
|
||||
bootstrap_options.append(f"vc{self.compiler.platform_toolset_ver}")
|
||||
elif self.spec.satisfies("%gcc"):
|
||||
bootstrap_options.append("gcc")
|
||||
elif self.spec.satisfies("%clang"):
|
||||
bootstrap_options.append("clang")
|
||||
|
||||
bootstrap = Executable("cmd.exe")
|
||||
bootstrap("/c", ".\\bootstrap.bat", *bootstrap_options)
|
||||
|
||||
def install(self, spec, prefix):
|
||||
# On Darwin, Boost expects the Darwin libtool. However, one of the
|
||||
# dependencies may have pulled in Spack's GNU libtool, and these two
|
||||
@ -710,16 +746,13 @@ def install(self, spec, prefix):
|
||||
if spec.satisfies("+graph") and spec.satisfies("+mpi"):
|
||||
with_libs.add("graph_parallel")
|
||||
|
||||
# to make Boost find the user-config.jam
|
||||
env["BOOST_BUILD_PATH"] = self.stage.source_path
|
||||
|
||||
bootstrap_options = ["--prefix=%s" % prefix]
|
||||
self.determine_bootstrap_options(spec, with_libs, bootstrap_options)
|
||||
|
||||
if self.spec.satisfies("platform=windows"):
|
||||
bootstrap = Executable("cmd.exe")
|
||||
bootstrap("/c", ".\\bootstrap.bat", *bootstrap_options)
|
||||
self.bootstrap_windows()
|
||||
else:
|
||||
# to make Boost find the user-config.jam
|
||||
env["BOOST_BUILD_PATH"] = self.stage.source_path
|
||||
bootstrap_options = ["--prefix=%s" % prefix]
|
||||
self.determine_bootstrap_options(spec, with_libs, bootstrap_options)
|
||||
bootstrap = Executable("./bootstrap.sh")
|
||||
bootstrap(*bootstrap_options)
|
||||
|
||||
@ -742,15 +775,24 @@ def install(self, spec, prefix):
|
||||
if jobs > 64 and spec.satisfies("@:1.58"):
|
||||
jobs = 64
|
||||
|
||||
# Windows just wants a b2 call with no args
|
||||
b2_options = []
|
||||
if not self.spec.satisfies("platform=windows"):
|
||||
path_to_config = "--user-config=%s" % os.path.join(
|
||||
self.stage.source_path, "user-config.jam"
|
||||
)
|
||||
b2_options = ["-j", "%s" % jobs]
|
||||
b2_options.append(path_to_config)
|
||||
if self.spec.satisfies("platform=windows"):
|
||||
|
||||
def is_64bit():
|
||||
# TODO: This method should be abstracted to a more general location
|
||||
# as it is repeated in many places (msmpi.py for one)
|
||||
return "64" in str(self.spec.target.family)
|
||||
|
||||
b2_options = [f"--prefix={self.prefix}", f"address-model={64 if is_64bit() else 32}"]
|
||||
if not self.spec.satisfies("+python"):
|
||||
b2_options.append("--without-python")
|
||||
|
||||
self.write_jam_file(self.spec)
|
||||
else:
|
||||
b2_options = ["-j", "%s" % jobs]
|
||||
path_to_config = "--user-config=%s" % os.path.join(
|
||||
self.stage.source_path, "user-config.jam"
|
||||
)
|
||||
b2_options.append(path_to_config)
|
||||
threading_opts = self.determine_b2_options(spec, b2_options)
|
||||
|
||||
# Create headers if building from a git checkout
|
||||
|
@ -1023,8 +1023,13 @@ def find_library(self, library):
|
||||
win_root_dir,
|
||||
]
|
||||
|
||||
# The Python shipped with Xcode command line tools isn't in any of these locations
|
||||
for subdir in ["lib", "lib64"]:
|
||||
if self.spec.satisfies("platform=windows"):
|
||||
lib_dirs = ["libs"]
|
||||
else:
|
||||
# The Python shipped with Xcode command line tools isn't in any of these locations
|
||||
lib_dirs = ["lib", "lib64"]
|
||||
|
||||
for subdir in lib_dirs:
|
||||
directories.append(os.path.join(self.config_vars["base"], subdir))
|
||||
|
||||
directories = dedupe(directories)
|
||||
@ -1067,14 +1072,16 @@ def libs(self):
|
||||
# The +shared variant isn't reliable, as `spack external find` currently can't
|
||||
# detect it. If +shared, prefer the shared libraries, but check for static if
|
||||
# those aren't found. Vice versa for ~shared.
|
||||
if "+shared" in self.spec:
|
||||
if self.spec.satisfies("platform=windows"):
|
||||
# Since we are searching for link libraries, on Windows search only for
|
||||
# ".Lib" extensions by default as those represent import libraries for implict links.
|
||||
candidates = static_libs
|
||||
elif self.spec.satisfies("+shared"):
|
||||
candidates = shared_libs + static_libs
|
||||
else:
|
||||
candidates = static_libs + shared_libs
|
||||
|
||||
candidates = dedupe(candidates)
|
||||
|
||||
for candidate in candidates:
|
||||
for candidate in dedupe(candidates):
|
||||
lib = self.find_library(candidate)
|
||||
if lib:
|
||||
return lib
|
||||
|
Loading…
Reference in New Issue
Block a user