From e21ca084fe4236e3afd32ef5ca1ffafe4ca92f39 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sat, 24 Jun 2023 14:39:33 +0200 Subject: [PATCH] Use OpenSSL on windows too, build libgit2, ssh2 with cmake. And update the libraries. --- .github/workflows/build.yml | 1 + SConstruct | 16 +++-- godot-git-plugin/SCsub | 4 +- thirdparty/SCsub | 6 -- thirdparty/git2/SCsub | 131 ---------------------------------- thirdparty/git2/libgit2 | 2 +- thirdparty/ssh2/SCsub | 110 ----------------------------- thirdparty/ssh2/libssh2 | 2 +- tools/cmake.py | 135 ++++++++++++++++++++++++++++++++++++ tools/git2.py | 65 +++++++++++++++++ tools/ssh2.py | 50 +++++++++++++ 11 files changed, 265 insertions(+), 257 deletions(-) delete mode 100644 thirdparty/SCsub delete mode 100644 thirdparty/git2/SCsub delete mode 100644 thirdparty/ssh2/SCsub create mode 100644 tools/cmake.py create mode 100644 tools/git2.py create mode 100644 tools/ssh2.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0593767..d9850b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,6 +29,7 @@ jobs: python-version: "3.x" architecture: "x64" - uses: ilammy/msvc-dev-cmd@v1 + - uses: ilammy/setup-nasm@v1 - name: build-windows-editor-x64 run: | git submodule update --init --recursive diff --git a/SConstruct b/SConstruct index 3ef0eff..e6296b2 100644 --- a/SConstruct +++ b/SConstruct @@ -23,21 +23,27 @@ if ARGUMENTS.get("custom_api_file", "") != "": ARGUMENTS["target"] = "editor" env = SConscript("godot-cpp/SConstruct").Clone() +env.PrependENVPath("PATH", os.getenv("PATH")) # Prepend PATH, done upstream in recent godot-cpp verions. # OpenSSL Builder env.Tool("openssl", toolpath=["tools"]) +# SSH2 Builder +env.Tool("cmake", toolpath=["tools"]) +env.Tool("ssh2", toolpath=["tools"]) +env.Tool("git2", toolpath=["tools"]) + opts.Update(env) -if env["platform"] != "windows": # Windows does not need OpenSSL - ssl = env.OpenSSL() -else: - ssl = [] +ssl = env.OpenSSL() +ssh2 = env.BuildSSH2(ssl) +ssl += ssh2 +git2 = env.BuildGIT2(ssl) Export("ssl") Export("env") -SConscript("thirdparty/SCsub") +#SConscript("thirdparty/SCsub") SConscript("godot-git-plugin/SCsub") diff --git a/godot-git-plugin/SCsub b/godot-git-plugin/SCsub index 6a20748..3f3d0bf 100644 --- a/godot-git-plugin/SCsub +++ b/godot-git-plugin/SCsub @@ -43,9 +43,7 @@ elif env["platform"] == "windows": env.Append(CPPPATH=[".", "src/"]) -env.Append(CPPPATH=["../thirdparty/git2/libgit2/include/"]) -env.Append(LIBPATH=["../thirdparty/bin/"]) -env.Prepend(LIBS=["git2", "ssh2"]) +env.Append(CPPPATH=["#thirdparty/git2/libgit2/include/"]) lib_sources = Glob("src/*.cpp") env.Depends(lib_sources, ssl) diff --git a/thirdparty/SCsub b/thirdparty/SCsub deleted file mode 100644 index 9b9252e..0000000 --- a/thirdparty/SCsub +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env python - -Import("env") - -SConscript("ssh2/SCsub") -SConscript("git2/SCsub") diff --git a/thirdparty/git2/SCsub b/thirdparty/git2/SCsub deleted file mode 100644 index 1bfbc08..0000000 --- a/thirdparty/git2/SCsub +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python - -# Adopted from https://github.com/goostengine/goost/blob/20d8ce4c7d74c26832d69283305b25a72165784a/modules/git/SCsub - -Import("env") -Import("ssl") - -env_git = env.Clone() - -# Thirdparty source files. -libgit2_sources = [] -libgit2_sources += Glob("libgit2/src/" + "*.c") -libgit2_sources += Glob("libgit2/src/allocators/" + "*.c") -libgit2_sources += Glob("libgit2/src/hash/sha1/sha1dc/sha1.c") -libgit2_sources += Glob("libgit2/src/hash/sha1/sha1dc/ubc_check.c") -libgit2_sources += Glob("libgit2/src/hash/sha1/collisiondetect.c") -libgit2_sources += Glob("libgit2/src/transports/" + "*.c") -libgit2_sources += Glob("libgit2/src/hash/transports/" + "*.c") -libgit2_sources += Glob("libgit2/src/hash/xdiff/" + "*.c") -libgit2_sources += Glob("libgit2/src/xdiff/" + "*.c") -libgit2_sources += Glob("libgit2/src/streams/" + "*.c") - -libgit2_sources += Glob("libgit2/deps/http-parser/" + "*.c") -libgit2_sources += Glob("libgit2/deps/pcre/" + "*.c") -libgit2_sources += Glob("libgit2/deps/zlib/" + "*.c") - -if "32" in env["arch"]: - env_git.Prepend(CPPDEFINES=["GIT_ARCH_32"]) -else: - env_git.Prepend(CPPDEFINES=["GIT_ARCH_64"]) - -env_git.Prepend( - CPPPATH=[ - "libgit2/include/", - "libgit2/src/", - "libgit2/deps/http-parser/", - "libgit2/deps/pcre/", - "libgit2/deps/zlib/", - "libgit2/deps/ntlmclient/", - "../ssh2/libssh2/include/", - ] -) - -env_git.Prepend( - CPPDEFINES=[ - "GIT_THREADS", - "GIT_SSH", - "GIT_SSH_MEMORY_CREDENTIALS", - "LIBGIT2_NO_FEATURES_H", - "GIT_SHA1_COLLISIONDETECT", - "GIT_HTTPS", - "SRC_UTIL_H_", - "GIT_REGEX_BUILTIN", - ] -) - -if env_git["platform"] == "windows": - libgit2_sources += Glob("libgit2/src/win32/" + "*.c") - env_git.Prepend( - CPPDEFINES=[ - "GIT_WINHTTP", - "HAVE_SYS_STAT_H", - "HAVE_SYS_TYPES_H", - "HAVE_WINDOWS_H", - "HAVE_STDINT_H", - "HAVE_INTTYPES_H", - "HAVE_MEMMOVE", - "HAVE_STRERROR", - "HAVE_STRTOLL", - "HAVE__STRTOI64", - "SUPPORT_PCRE8", - "NO_RECURSE", - "HAVE_LONG_LONG", - "HAVE_UNSIGNED_LONG_LONG", - ("NEWLINE", "10"), - ("POSIX_MALLOC_THRESHOLD", "10"), - ("LINK_SIZE", "2"), - ("PARENS_NEST_LIMIT", "250"), - ("MATCH_LIMIT", "10000000"), - ("MATCH_LIMIT_RECURSION", "10000000"), - "PCREGREP_BUFSIZE", - ("MAX_NAME_SIZE", "32"), - ("MAX_NAME_COUNT", "10000"), - "HAVE_WINCNG", - "LIBSSH2_WINCNG" - ] - ) - -if env_git["platform"] in ["linux", "macos"]: - env_git.Append(CCFLAGS="-fPIC") - libgit2_sources += Glob("libgit2/src/unix/" + "*.c") - libgit2_sources += [ - "libgit2/deps/ntlmclient/crypt_openssl.c", - "libgit2/deps/ntlmclient/unicode_builtin.c" - ] - env_git.Prepend( - CPPDEFINES=[ - "HAVE_DIRENT_H", - "HAVE_SYS_STAT_H", - "HAVE_SYS_TYPES_H", - "HAVE_UNISTD_H", - "HAVE_STDINT_H", - "HAVE_INTTYPES_H", - "HAVE_BCOPY", - "HAVE_MEMMOVE", - "HAVE_STRERROR", - "HAVE_STRTOLL", - "HAVE_STRTOQ", - "SUPPORT_PCRE8", - "NO_RECURSE", - "HAVE_LONG_LONG", - "HAVE_UNSIGNED_LONG_LONG", - ("NEWLINE", "10"), - ("POSIX_MALLOC_THRESHOLD", "10"), - ("LINK_SIZE", "2"), - ("PARENS_NEST_LIMIT", "250"), - ("MATCH_LIMIT", "10000000"), - ("MATCH_LIMIT_RECURSION", "10000000"), - "PCREGREP_BUFSIZE", - ("MAX_NAME_SIZE", "32"), - ("MAX_NAME_COUNT", "10000"), - "GIT_OPENSSL", - "GIT_USE_FUTIMENS", - "GIT_USE_STAT_MTIM", - "CRYPT_OPENSSL", - "UNICODE_BUILTIN" - ] - ) - env_git.Depends(libgit2_sources, ssl) - -env_git.StaticLibrary(target="../bin/" + "git2", source=libgit2_sources) diff --git a/thirdparty/git2/libgit2 b/thirdparty/git2/libgit2 index b7bad55..3e2baa6 160000 --- a/thirdparty/git2/libgit2 +++ b/thirdparty/git2/libgit2 @@ -1 +1 @@ -Subproject commit b7bad55e4bb0a285b073ba5e02b01d3f522fc95d +Subproject commit 3e2baa6d0bfb42f9016e24cba1733a6ae26a8ae6 diff --git a/thirdparty/ssh2/SCsub b/thirdparty/ssh2/SCsub deleted file mode 100644 index ec1306b..0000000 --- a/thirdparty/ssh2/SCsub +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python - -# Adopted from https://github.com/nodegit/nodegit/blob/4561dcb7c120474a4553baa27e4c4c2f4be23a2b/vendor/libgit2.gyp - -Import("env") -Import("ssl") - -env_ssh2 = env.Clone() - -# Thirdparty source files. -libssh2_sources = [ - "libssh2/src/agent.c", - "libssh2/src/bcrypt_pbkdf.c", - "libssh2/src/blowfish.c", - "libssh2/src/crypt.c", - "libssh2/src/keepalive.c", - "libssh2/src/libgcrypt.c", - "libssh2/src/openssl.c", - "libssh2/src/publickey.c", - "libssh2/src/sftp.c", - "libssh2/src/version.c", - "libssh2/src/channel.c", - "libssh2/src/global.c", - "libssh2/src/kex.c", - "libssh2/src/mac.c", - "libssh2/src/packet.c", - "libssh2/src/scp.c", - "libssh2/src/transport.c", - "libssh2/src/comp.c", - "libssh2/src/hostkey.c", - "libssh2/src/knownhost.c", - "libssh2/src/misc.c", - "libssh2/src/pem.c", - "libssh2/src/session.c", - "libssh2/src/userauth_kbd_packet.c", - "libssh2/src/userauth.c", -] - -env_ssh2.Prepend( - CPPPATH=[ - "libssh2/include/" - "libssh2/src/" - ] -) - -if env_ssh2["platform"] == "windows": - env_ssh2.Append( - CPPPATH=[ - "libssh2/include/", - "libssh2/win32/" - ] - ) - libssh2_sources += ["libssh2/src/agent_win.c", "libssh2/src/wincng.c"] - env_ssh2.Append( - CPPDEFINES=[ - "LIBSSH2_WINCNG", - "HAVE_WINCNG" - ] - ) - env_ssh2.Append(LIBS=["crypt32", "user32"]) - -if env_ssh2["platform"] in ["linux", "macos"]: - env_ssh2.Append(CCFLAGS="-fPIC") - env_ssh2.Append( - CPPPATH=[ - ".", - "libssh2/include/", - ] - ) - libssh2_sources += ["libssh2/src/openssl.c"] - env_ssh2.Append( - CPPDEFINES=[ - "LIBSSH2_CONFIG_H", - "HAVE_SYS_UIO_H", - ("HAVE_ALLOCA", 1), - ("HAVE_ALLOCA_H", 1), - ("HAVE_ARPA_INET_H", 1), - ("HAVE_ERRNO_H", 1), - ("HAVE_FCNTL_H", 1), - ("HAVE_GETTIMEOFDAY", 1), - ("HAVE_GETTIMEOFDAY", 1), - ("HAVE_INTTYPES_H", 1), - ("HAVE_LONGLONG", 1), - ("HAVE_NETINET_IN_H", 1), - ("HAVE_O_NONBLOCK", 1), - ("HAVE_SELECT", 1), - ("HAVE_STDINT_H", 1), - ("HAVE_STDIO_H", 1), - ("HAVE_STDLIB_H", 1), - ("HAVE_STRINGS_H", 1), - ("HAVE_STRING_H", 1), - ("HAVE_STRTOLL", 1), - ("HAVE_SYS_IOCTL_H", 1), - ("HAVE_SYS_SOCKET_H", 1), - ("HAVE_SYS_STAT_H", 1), - ("HAVE_SYS_TIME_H", 1), - ("HAVE_SYS_TYPES_H", 1), - ("HAVE_SYS_UIO_H", 1), - ("HAVE_SYS_UN_H", 1), - ("HAVE_UNISTD_H", 1), - ("LIBSSH2_CLEAR_MEMORY", 1), - ("LIBSSH2_DH_GEX_NEW", 1), - ("LIBSSH2_OPENSSL", 1), - ("LT_OBJDIR", ".libs/"), - ("STDC_HEADERS", 1) - ] - ) - env_ssh2.Depends(libssh2_sources, ssl) - -env_ssh2.StaticLibrary(target="../bin/" + "ssh2", source=libssh2_sources) diff --git a/thirdparty/ssh2/libssh2 b/thirdparty/ssh2/libssh2 index 6cba487..1c3f1b7 160000 --- a/thirdparty/ssh2/libssh2 +++ b/thirdparty/ssh2/libssh2 @@ -1 +1 @@ -Subproject commit 6cba487395e79775482fc80dcbc4146e3b17c773 +Subproject commit 1c3f1b7da588f2652260285529ec3c1f1125eb4e diff --git a/tools/cmake.py b/tools/cmake.py new file mode 100644 index 0000000..39957d8 --- /dev/null +++ b/tools/cmake.py @@ -0,0 +1,135 @@ +import os, sys + +import SCons.Util +import SCons.Builder +import SCons.Action + + +def cmake_default_flags(env): + if env.get("cmake_default_flags", ""): + return SCons.Util.CLVar(env["cmake_default_flags"]) + + config = {} + + if "CC" in env: + config["CMAKE_C_COMPILER"] = env["CC"] + if "CXX" in env: + config["CMAKE_CXX_COMPILER"] = env["CXX"] + + if env["platform"] == "android": + api = env["android_api_level"] + abi = { + "arm64": "arm64-v8a", + "arm32": "armeabi-v7a", + "x86_32": "x86", + "x86_64": "x86_64", + }[env["arch"]] + config["CMAKE_SYSTEM_NAME"] = "Android" + config["CMAKE_SYSTEM_VERSION"] = api + config["CMAKE_ANDROID_ARCH_ABI"] = abi + config["ANDROID_ABI"] = abi + config["CMAKE_TOOLCHAIN_FILE"] = "%s/build/cmake/android.toolchain.cmake" % env.get( + "ANDROID_NDK_ROOT", os.environ.get("ANDROID_NDK_ROOT", "") + ) + config["CMAKE_ANDROID_STL_TYPE"] = "c++_static" + + elif env["platform"] == "linux": + linux_flags = { + "x86_64": "-m64", + "x86_32": "-m32", + }.get(env["arch"], "") + if linux_flags: + config["CMAKE_C_FLAGS"] = linux_flags + config["CMAKE_CXX_FLAGS"] = linux_flags + + elif env["platform"] == "macos": + if env["arch"] == "universal": + config["CMAKE_OSX_ARCHITECTURES"] = '"x86_64;arm64"' + else: + config["CMAKE_OSX_ARCHITECTURES"] = env["arch"] + if env["macos_deployment_target"] != "default": + config["CMAKE_OSX_DEPLOYMENT_TARGET"] = env["macos_deployment_target"] + + if env["platform"] == "macos" and sys.platform != "darwin" and "OSXCROSS_ROOT" in os.environ: + config["CMAKE_AR"] = env["AR"] + config["CMAKE_RANLIB"] = env["RANLIB"] + if env["arch"] == "universal": + flags = "-arch x86_64 -arch arm64" + else: + flags = "-arch " + env["arch"] + if env["macos_deployment_target"] != "default": + flags += " -mmacosx-version-min=" + env["macos_deployment_target"] + config["CMAKE_C_FLAGS"] = flags + config["CMAKE_CXX_FLAGS"] = flags + + elif env["platform"] == "ios": + if env["arch"] == "universal": + raise ValueError("iOS architecture not supported: %s" % env["arch"]) + config["CMAKE_SYSTEM_NAME"] = "iOS" + config["CMAKE_OSX_ARCHITECTURES"] = env["arch"] + if env.get("ios_min_version", "default") != "default": + config["CMAKE_OSX_DEPLOYMENT_TARGET"] = env["ios_min_version"] + if env["ios_simulator"]: + config["CMAKE_OSX_SYSROOT"] = "iphonesimulator" + + elif env["platform"] == "windows": + config["CMAKE_SYSTEM_NAME"] = "Windows" + + flags = ["-D%s=%s" % it for it in config.items()] + if env["CMAKEGENERATOR"]: + flags.extend(["-G", env["CMAKEGENERATOR"]]) + elif env["platform"] == "windows": + if env.get("is_msvc", False): + flags.extend(["-G", "NMake Makefiles"]) + elif sys.platform in ["win32", "msys", "cygwin"]: + flags.extend(["-G", "Ninja"]) + else: + flags.extend(["-G", "Unix Makefiles"]) + return flags + + +def cmake_emitter(target, source, env): + return [str(target[0]) + "/CMakeCache.txt"] + target[1:], [str(source[0]) + "/CMakeLists.txt"] + source[1:] + + +def cmake_generator(target, source, env, for_signature): + # Strip the -j option for signature to avoid rebuilding when num_jobs changes. + build = env["CMAKEBUILDCOM"].replace("-j$CMAKEBUILDJOBS", "") if for_signature else env["CMAKEBUILDCOM"] + return [ + SCons.Action.Action("$CMAKECONFCOM", "$CMAKECONFCOMSTR"), + SCons.Action.Action(build, "$CMAKEBUILDCOMSTR"), + ] + + +def cmake_build(env, target_dir, source_dir, cmake_outputs=[], cmake_targets=[], cmake_options=[], dependencies=[]): + cmake_env = env.Clone() + target = env.Dir("{}/{}/{}".format(target_dir, env["platform"], env["arch"])) + source = env.Dir(source_dir) + builder_targets = [target] + [str(target) + "/" + f for f in cmake_outputs] + builder_sources = [source] + dependencies + cmake_env.Append(CMAKECONFFLAGS=["-D%s=%s" % it for it in cmake_options.items()]) + if len(cmake_targets) > 0: + cmake_env.Append(CMAKEBUILDFLAGS=["-t"] + [t for t in cmake_targets]) + return cmake_env.CMake(builder_targets, builder_sources) + + +def options(opts): + opts.Add("cmake_default_flags", "Default CMake platform flags override, will be autodetected if not specified.", "") + + +def exists(env): + return True + + +def generate(env): + env["CMAKE"] = "cmake" + env["_cmake_default_flags"] = cmake_default_flags + env["CMAKEDEFAULTFLAGS"] = "${_cmake_default_flags(__env__)}" + env["CMAKEGENERATOR"] = "" + env["CMAKECONFFLAGS"] = SCons.Util.CLVar("") + env["CMAKECONFCOM"] = "$CMAKE -B ${TARGET.dir} $CMAKEDEFAULTFLAGS $CMAKECONFFLAGS ${SOURCE.dir}" + env["CMAKEBUILDJOBS"] = "${__env__.GetOption('num_jobs')}" + env["CMAKEBUILDFLAGS"] = SCons.Util.CLVar("") + env["CMAKEBUILDCOM"] = "$CMAKE --build ${TARGET.dir} $CMAKEBUILDFLAGS -j$CMAKEBUILDJOBS" + env["BUILDERS"]["CMake"] = SCons.Builder.Builder(generator=cmake_generator, emitter=cmake_emitter) + env.AddMethod(cmake_build, "CMakeBuild") diff --git a/tools/git2.py b/tools/git2.py new file mode 100644 index 0000000..bba3d6d --- /dev/null +++ b/tools/git2.py @@ -0,0 +1,65 @@ +import os + + +def build_library(env, deps): + config = { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release", + "OPENSSL_USE_STATIC_LIBS": 1, + "OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"], + "OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"], + "OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"], + "OPENSSL_ROOT_DIR": env["SSL_INSTALL"], + "BUILD_TESTS": 0, + "BUILD_CLI": 0, + "BUILD_EXAMPLES": 0, + "BUILD_FUZZERS": 0, + "USE_SSH": 1, + "USE_HTTPS": 1, + "USE_SHA1": 1, + "USE_BUNDLED_ZLIB": 1, + "USE_HTTP_PARSER": "builtin", + "REGEX_BACKEND": "builtin", + "USE_HTTPS": "OpenSSL", + "USE_SHA1": "OpenSSL", + "BUILD_SHARED_LIBS": 0, + "LINK_WITH_STATIC_LIBRARIES": 1, + "LIBSSH2_INCLUDE_DIR": env.Dir("#thirdparty/ssh2/libssh2/include").abspath, + "LIBSSH2_LIBRARY": deps[-1], + "USE_WINHTTP": 0, + "STATIC_CRT": 0, + } + + if env["platform"] != "windows": + config["CMAKE_C_FLAGS"] = "-fPIC" + else: + config["OPENSSL_ROOT_DIR"] = env["SSL_BUILD"] + + is_msvc = env.get("is_msvc", False) + lib_ext = ".lib" if is_msvc else ".a" + lib_prefix = "" if is_msvc else "lib" + libs = ["{}git2{}".format(lib_prefix, lib_ext)] + + source = env.Dir("#thirdparty/git2/libgit2").abspath + target = env.Dir("#bin/thirdparty/libgit2").abspath + + git2 = env.CMakeBuild( + "#bin/thirdparty/git2/", + "#thirdparty/git2/libgit2", + cmake_options=config, + cmake_outputs=libs, + cmake_targets=[], + dependencies=deps, + ) + + env.Append(CPPPATH=["#thirdparty/git2/libgit2/include"]) + env.Prepend(LIBS=git2[1:]) + + return git2 + + +def exists(env): + return "CMake" in env + + +def generate(env): + env.AddMethod(build_library, "BuildGIT2") diff --git a/tools/ssh2.py b/tools/ssh2.py new file mode 100644 index 0000000..a5cbe60 --- /dev/null +++ b/tools/ssh2.py @@ -0,0 +1,50 @@ +import os + + +def build_library(env, deps): + config = { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" if env["debug_symbols"] else "Release", + "OPENSSL_USE_STATIC_LIBS": 1, + "OPENSSL_INCLUDE_DIR": env["SSL_INCLUDE"], + "OPENSSL_SSL_LIBRARY": env["SSL_LIBRARY"].abspath, + "OPENSSL_CRYPTO_LIBRARY": env["SSL_CRYPTO_LIBRARY"].abspath, + "OPENSSL_ROOT_DIR": env["SSL_INSTALL"], + "BUILD_EXAMPLES": 0, + "BUILD_TESTING": 0, + "BUILD_SHARED_LIBS": 0, + "CRYPTO_BACKEND": "OpenSSL", + } + + if env["platform"] != "windows": + config["CMAKE_C_FLAGS"] = "-fPIC" + else: + config["OPENSSL_ROOT_DIR"] = env["SSL_BUILD"] + + is_msvc = env.get("is_msvc", False) + lib_ext = ".lib" if is_msvc else ".a" + libs = ["src/libssh2{}".format(lib_ext)] + + source = env.Dir("#thirdparty/ssh2/libssh2").abspath + target = env.Dir("#bin/thirdparty/libssh2").abspath + + ssh2 = env.CMakeBuild( + "#bin/thirdparty/ssh2/", + "#thirdparty/ssh2/libssh2", + cmake_options=config, + cmake_outputs=libs, + cmake_targets=[], + dependencies=deps, + ) + + env.Append(CPPPATH=["#thirdparty/ssh2/libssh2/include"]) + env.Prepend(LIBS=ssh2[1:]) + + return ssh2 + + +def exists(env): + return "CMake" in env + + +def generate(env): + env.AddMethod(build_library, "BuildSSH2")