cURL package: add support for building on Windows (#30169)

This commit is contained in:
John W. Parent 2023-01-12 13:23:57 -05:00 committed by GitHub
parent 57e9e77475
commit a1c840b3e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,13 +3,17 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import glob
import os
import re import re
import sys import sys
from spack.build_systems.autotools import AutotoolsBuilder
from spack.build_systems.nmake import NMakeBuilder
from spack.package import * from spack.package import *
class Curl(AutotoolsPackage): class Curl(NMakePackage, AutotoolsPackage):
"""cURL is an open source command line tool and library for """cURL is an open source command line tool and library for
transferring data with URL syntax""" transferring data with URL syntax"""
@ -60,6 +64,8 @@ class Curl(AutotoolsPackage):
default_tls = "openssl" default_tls = "openssl"
if sys.platform == "darwin": if sys.platform == "darwin":
default_tls = "secure_transport" default_tls = "secure_transport"
elif sys.platform == "win32":
default_tls = "sspi"
# TODO: add dependencies for other possible TLS backends # TODO: add dependencies for other possible TLS backends
variant( variant(
@ -78,6 +84,7 @@ class Curl(AutotoolsPackage):
# 'schannel', # 'schannel',
"secure_transport", "secure_transport",
# 'wolfssl', # 'wolfssl',
conditional("sspi", when="platform=windows"),
), ),
multi=True, multi=True,
) )
@ -88,6 +95,8 @@ class Curl(AutotoolsPackage):
variant("librtmp", default=False, description="enable Rtmp support") variant("librtmp", default=False, description="enable Rtmp support")
variant("ldap", default=False, description="enable ldap support") variant("ldap", default=False, description="enable ldap support")
variant("libidn2", default=False, description="enable libidn2 support") variant("libidn2", default=False, description="enable libidn2 support")
for plat in ["darwin", "cray", "linux"]:
with when("platform=%s" % plat):
variant( variant(
"libs", "libs",
default="shared,static", default="shared,static",
@ -95,6 +104,8 @@ class Curl(AutotoolsPackage):
multi=True, multi=True,
description="Build shared libs, static libs or both", description="Build shared libs, static libs or both",
) )
# curl queries pkgconfig for openssl compilation flags
depends_on("pkgconfig", type="build")
conflicts("platform=cray", when="tls=secure_transport", msg="Only supported on macOS") conflicts("platform=cray", when="tls=secure_transport", msg="Only supported on macOS")
conflicts("platform=linux", when="tls=secure_transport", msg="Only supported on macOS") conflicts("platform=linux", when="tls=secure_transport", msg="Only supported on macOS")
@ -117,6 +128,12 @@ class Curl(AutotoolsPackage):
# https://github.com/curl/curl/pull/9054 # https://github.com/curl/curl/pull/9054
patch("easy-lock-sched-header.patch", when="@7.84.0") patch("easy-lock-sched-header.patch", when="@7.84.0")
build_system(
"autotools",
conditional("nmake", when="platform=windows"),
default="autotools",
)
@classmethod @classmethod
def determine_version(cls, exe): def determine_version(cls, exe):
curl = Executable(exe) curl = Executable(exe)
@ -150,6 +167,8 @@ def determine_variants(cls, exes, version):
def command(self): def command(self):
return Executable(self.prefix.bin.join("curl-config")) return Executable(self.prefix.bin.join("curl-config"))
class AutotoolsBuilder(AutotoolsBuilder):
def configure_args(self): def configure_args(self):
spec = self.spec spec = self.spec
@ -239,3 +258,54 @@ def with_or_without_secure_transport(self, activated):
return "--with-darwinssl" return "--with-darwinssl"
else: else:
return "--without-darwinssl" return "--without-darwinssl"
class NMakeBuilder(NMakeBuilder):
phases = ["install"]
def nmake_args(self):
args = []
mode = "dll" if "libs=dll" in self.spec else "static"
args.append("mode=%s" % mode)
args.append("WITH_ZLIB=%s" % mode)
args.append("ZLIB_PATH=%s" % self.spec["zlib"].prefix)
if "+libssh" in self.spec:
args.append("WITH_SSH=%s" % mode)
if "+libssh2" in self.spec:
args.append("WITH_SSH2=%s" % mode)
args.append("SSH2_PATH=%s" % self.spec["libssh2"].prefix)
if "+nghttp2" in self.spec:
args.append("WITH_NGHTTP2=%s" % mode)
args.append("NGHTTP2=%s" % self.spec["nghttp2"].prefix)
if "tls=openssl" in self.spec:
args.append("WITH_SSL=%s" % mode)
args.append("SSL_PATH=%s" % self.spec["openssl"].prefix)
elif "tls=mbedtls" in self.spec:
args.append("WITH_MBEDTLS=%s" % mode)
args.append("MBEDTLS_PATH=%s" % self.spec["mbedtls"].prefix)
elif "tls=sspi" in self.spec:
args.append("ENABLE_SSPI=%s" % mode)
# The trailing path seperator is REQUIRED for cURL to install
# otherwise cURLs build system will interpret the path as a file
# and the install will fail with ambiguous errors
args.append("WITH_PREFIX=%s" % self.prefix + "\\")
return args
def install(self, spec, prefix):
# Spack's env CC and CXX values will cause an error
# if there is a path in the space, and escaping with
# double quotes raises a syntax issues, instead
# cURLs nmake will automatically invoke proper cl.exe if
# no env value for CC, CXX is specified
# Unset the value to allow for cURLs heuristics (derive via VCVARS)
# to derive the proper compiler
env = os.environ
env["CC"] = ""
env["CXX"] = ""
winbuild_dir = os.path.join(self.stage.source_path, "winbuild")
with working_dir(winbuild_dir):
nmake("/f", "Makefile.vc", *self.nmake_args(), ignore_quotes=True)
with working_dir(os.path.join(self.stage.source_path, "builds")):
install_dir = glob.glob("libcurl-**")[0]
install_tree(install_dir, self.prefix)