summaryrefslogtreecommitdiff
path: root/tools/openssl.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/openssl.py')
-rw-r--r--tools/openssl.py179
1 files changed, 179 insertions, 0 deletions
diff --git a/tools/openssl.py b/tools/openssl.py
new file mode 100644
index 0000000..ad61df9
--- /dev/null
+++ b/tools/openssl.py
@@ -0,0 +1,179 @@
+import os, sys
+from SCons.Defaults import Mkdir
+from SCons.Variables import PathVariable, BoolVariable
+
+
+def ssl_emitter(target, source, env):
+ env.Depends(env["SSL_LIBS"], env.File(__file__))
+ return env["SSL_LIBS"], [env.Dir(env["SSL_SOURCE"]), env.File(env["SSL_SOURCE"] + "/VERSION.dat")]
+
+
+def ssl_action(target, source, env):
+ build_dir = env["SSL_BUILD"]
+ source_dir = env["SSL_SOURCE"]
+ install_dir = env["SSL_INSTALL"]
+
+ ssl_env = env.Clone()
+ args = [
+ "no-ssl2",
+ "no-ssl3",
+ "no-weak-ssl-ciphers",
+ "no-legacy",
+ "no-shared",
+ "no-tests",
+ "--prefix=%s" % install_dir,
+ "--openssldir=%s" % install_dir,
+ ]
+ if env["openssl_debug"]:
+ args.append("-d")
+
+ if env["platform"] == "linux":
+ if env["arch"] == "x86_32":
+ args.extend(["linux-x86"])
+ else:
+ args.extend(["linux-x86_64"])
+
+ elif env["platform"] == "android":
+ api = env["android_api_level"] if int(env["android_api_level"]) > 28 else "28"
+ args.extend(
+ [
+ {
+ "arm64": "android-arm64",
+ "arm32": "android-arm",
+ "x86_32": "android-x86",
+ "x86_64": "android-x86_64",
+ }[env["arch"]],
+ "-D__ANDROID_API__=%s" % api,
+ ]
+ )
+ # Setup toolchain path.
+ ssl_env.PrependENVPath("PATH", os.path.dirname(env["CC"]))
+ ssl_env["ENV"]["ANDROID_NDK_ROOT"] = os.environ.get("ANDROID_NDK_ROOT", "")
+
+ elif env["platform"] == "macos":
+ if env["arch"] == "x86_64":
+ args.extend(["darwin64-x86_64"])
+ elif env["arch"] == "arm64":
+ args.extend(["darwin64-arm64"])
+ else:
+ raise ValueError("macOS architecture not supported: %s" % env["arch"])
+
+ if sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ:
+ args.extend(
+ [
+ "CC=" + env["CC"],
+ "CXX=" + env["CXX"],
+ "AR=" + env["AR"],
+ "AS=" + env["AS"],
+ "RANLIB=" + env["RANLIB"],
+ ]
+ )
+
+ elif env["platform"] == "ios":
+ if env["ios_simulator"]:
+ args.extend(["iossimulator-xcrun"])
+ elif env["arch"] == "arm32":
+ args.extend(["ios-xcrun"])
+ elif env["arch"] == "arm64":
+ args.extend(["ios64-xcrun"])
+ else:
+ raise ValueError("iOS architecture not supported: %s" % env["arch"])
+
+ elif env["platform"] == "windows":
+ args.extend(["enable-capieng"])
+ is_win_host = sys.platform in ["win32", "msys", "cygwin"]
+ if env.get("is_msvc", False):
+ args.extend(["VC-WIN32" if env["arch"] == "x86_32" else "VC-WIN64A"])
+ else:
+ if env["arch"] == "x86_32":
+ args.extend(["mingw"])
+ if not is_win_host:
+ args.extend(["--cross-compile-prefix=i686-w64-mingw32-"])
+ else:
+ args.extend(["mingw64"])
+ if not is_win_host:
+ args.extend(["--cross-compile-prefix=x86_64-w64-mingw32-"])
+
+ jobs = env.GetOption("num_jobs")
+ make_cmd = ["make -C %s -j%s" % (build_dir, jobs), "make -C %s install_sw install_ssldirs -j%s" % (build_dir, jobs)]
+ if env["platform"] == "windows" and env.get("is_msvc", False):
+ make_cmd = ["cd %s && nmake install_sw install_ssldirs" % build_dir]
+ ssl_env.Execute(
+ [
+ Mkdir(build_dir),
+ Mkdir(install_dir),
+ "cd {} && perl -- {} {}".format(
+ build_dir, os.path.join(source_dir, "Configure"), " ".join(['"%s"' % a for a in args])
+ ),
+ ]
+ + make_cmd
+ )
+ return None
+
+
+def build_openssl(env):
+ # Since the OpenSSL build system does not support macOS universal binaries, we first need to build the two libraries
+ # separately, then we join them together using lipo.
+ if env["platform"] == "macos" and env["arch"] == "universal":
+ build_envs = {
+ "x86_64": env.Clone(),
+ "arm64": env.Clone(),
+ }
+ arch_ssl = []
+ for arch in build_envs:
+ benv = build_envs[arch]
+ benv["arch"] = arch
+ generate(benv)
+ ssl = benv.OpenSSLBuilder()
+ arch_ssl.extend(ssl)
+ benv.NoCache(ssl) # Needs refactoring to properly cache generated headers.
+
+ # x86_64 and arm64 includes are equivalent.
+ env["SSL_INCLUDE"] = build_envs["arm64"]["SSL_INCLUDE"]
+
+ # Join libraries using lipo.
+ ssl_libs = list(map(lambda arch: build_envs[arch]["SSL_LIBRARY"], build_envs))
+ ssl_crypto_libs = list(map(lambda arch: build_envs[arch]["SSL_CRYPTO_LIBRARY"], build_envs))
+ ssl = [
+ env.Command([env["SSL_LIBRARY"]], ssl_libs, "lipo $SOURCES -output $TARGETS -create"),
+ env.Command([env["SSL_CRYPTO_LIBRARY"]], ssl_libs, "lipo $SOURCES -output $TARGETS -create"),
+ ]
+ env.Depends(ssl, arch_ssl)
+ else:
+ ssl = env.OpenSSLBuilder()
+ env.NoCache(ssl) # Needs refactoring to properly cache generated headers.
+
+ env.Prepend(CPPPATH=[env["SSL_INCLUDE"]])
+ env.Prepend(LIBPATH=[env["SSL_BUILD"]])
+ if env["platform"] == "windows":
+ env.PrependUnique(LIBS=["crypt32", "ws2_32", "advapi32", "user32"])
+
+ env.Prepend(LIBS=env["SSL_LIBS"])
+
+ return ssl
+
+
+def options(opts):
+ opts.Add(PathVariable("openssl_source", "Path to the openssl sources.", "thirdparty/openssl"))
+ opts.Add("openssl_build", "Destination path of the openssl build.", "bin/thirdparty/openssl")
+ opts.Add(BoolVariable("openssl_debug", "Make a debug build of OpenSSL.", False))
+
+
+def exists(env):
+ return True
+
+
+def generate(env):
+ env["SSL_SOURCE"] = env.Dir(env["openssl_source"]).abspath
+ env["SSL_BUILD"] = env.Dir(
+ env["openssl_build"]
+ + "/{}/{}/{}".format(env["platform"], env["arch"], "debug" if env["openssl_debug"] else "release")
+ ).abspath
+ env["SSL_INSTALL"] = env.Dir(env["SSL_BUILD"] + "/dest").abspath
+ env["SSL_INCLUDE"] = env.Dir(env["SSL_INSTALL"] + "/include").abspath
+ lib_ext = ".lib" if env.get("is_msvc", False) else ".a"
+ env["SSL_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libssl" + lib_ext)
+ env["SSL_CRYPTO_LIBRARY"] = env.File(env["SSL_BUILD"] + "/libcrypto" + lib_ext)
+ env["SSL_LIBS"] = [env["SSL_LIBRARY"], env["SSL_CRYPTO_LIBRARY"]]
+ env.Append(BUILDERS={"OpenSSLBuilder": env.Builder(action=ssl_action, emitter=ssl_emitter)})
+ env.AddMethod(build_openssl, "OpenSSL")