diff --git a/.gitmodules b/.gitmodules index 997b6764b..11845060a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -18,6 +18,3 @@ path = client/3rd/qtgamepad url = https://github.com/amnezia-vpn/qtgamepad.git branch = 6.6 -[submodule "cmake/cmake-conan"] - path = cmake/cmake-conan - url = https://github.com/conan-io/cmake-conan.git diff --git a/CMakeLists.txt b/CMakeLists.txt index f5bf107be..34400fa85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,15 +4,23 @@ set(PROJECT AmneziaVPN) set(AMNEZIAVPN_VERSION 4.8.13.1) include(cmake/conan_bootstrap.cmake) -set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES ${CMAKE_SOURCE_DIR}/cmake/cmake-conan/conan_provider.cmake) +set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES ${CMAKE_SOURCE_DIR}/cmake/conan_provider.cmake) if(APPLE) - if(IOS) - set(CMAKE_OSX_ARCHITECTURES "arm64") + get_property(generator_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if (generator_is_multi_config) + set(CONAN_INSTALL_BUILD_CONFIGURATIONS Release Debug MinSizeRel RelWithDebInfo) + endif() + if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + set(CMAKE_OSX_DEPLOYMENT_TARGET "14.0" CACHE STRING "" FORCE) + set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE STRING "" FORCE) elseif(MACOS_NE) - set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64") + set(CONAN_INSTALL_ARGS "--build=missing;-o=&:macos_ne=True" CACHE STRING "" FORCE) + set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "" FORCE) + set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) else() - set(CMAKE_OSX_ARCHITECTURES "x86_64") + set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0" CACHE STRING "" FORCE) + set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "" FORCE) endif() endif() diff --git a/client/cmake/ios.cmake b/client/cmake/ios.cmake index b605de484..d8483e0ec 100644 --- a/client/cmake/ios.cmake +++ b/client/cmake/ios.cmake @@ -1,8 +1,6 @@ message("Client iOS build") -set(CMAKE_OSX_DEPLOYMENT_TARGET 13.0) set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) - enable_language(OBJC) enable_language(OBJCXX) enable_language(Swift) @@ -137,11 +135,3 @@ set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE add_subdirectory(ios/networkextension) add_dependencies(${PROJECT} networkextension) - -set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS - "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework" -) - -set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/) -target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-ios/OpenVPNAdapter.framework") - diff --git a/client/cmake/macos.cmake b/client/cmake/macos.cmake index 09c23b2d5..5b9b23cc4 100644 --- a/client/cmake/macos.cmake +++ b/client/cmake/macos.cmake @@ -23,9 +23,6 @@ set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE_SHORT_VERSION_STRING "${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}" MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}" ) -set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE INTERNAL "" FORCE) -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) - set(HEADERS ${HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/ui/macos_util.h diff --git a/client/cmake/macos_ne.cmake b/client/cmake/macos_ne.cmake index 749053757..1ea6939c5 100644 --- a/client/cmake/macos_ne.cmake +++ b/client/cmake/macos_ne.cmake @@ -1,7 +1,6 @@ message("Client ==> MacOS NE build") set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE) -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) @@ -152,19 +151,6 @@ message(${QtCore_location}) get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE) -set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS - "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos/OpenVPNAdapter.framework" -) - -set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos) -target_link_libraries("AmneziaVPNNetworkExtension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd-prebuilt/3rd-prebuilt/openvpn/apple/OpenVPNAdapter-macos/OpenVPNAdapter.framework") - add_custom_command(TARGET ${PROJECT} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory - $/Contents/Frameworks - COMMAND /usr/bin/find "$/Contents/Frameworks/OpenVPNAdapter.framework" -name "*.sha256" -delete - COMMAND /usr/bin/codesign --force --sign "Apple Distribution" - "$/Contents/Frameworks/OpenVPNAdapter.framework/Versions/Current/OpenVPNAdapter" COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $ -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR} - COMMENT "Signing OpenVPNAdapter framework" ) diff --git a/client/ios/networkextension/CMakeLists.txt b/client/ios/networkextension/CMakeLists.txt index 64b1c3c4d..4da051897 100644 --- a/client/ios/networkextension/CMakeLists.txt +++ b/client/ios/networkextension/CMakeLists.txt @@ -110,21 +110,14 @@ set_property(TARGET networkextension APPEND PROPERTY RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy ) -## Build wireguard-go-version.h -execute_process( - COMMAND go list -m golang.zx2c4.com/wireguard - WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo - OUTPUT_VARIABLE WG_VERSION_FULL -) -string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in - ${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h) -target_sources(networkextension PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h) - target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR}) target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/ios/arm64/libwg-go.a) +find_package(openvpnadapter REQUIRED) +target_link_libraries(networkextension PRIVATE amnezia::openvpnadapter) -target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework) +find_package(awg-apple REQUIRED) +target_link_libraries(networkextension PRIVATE amnezia::awg-apple) + +find_package(hev-socks5-tunnel REQUIRED) +target_link_libraries(networkextension PRIVATE heiher::hev-socks5-tunnel) diff --git a/client/ios/networkextension/wireguard-go-version.h.in b/client/ios/networkextension/wireguard-go-version.h.in deleted file mode 100644 index 860bc3c36..000000000 --- a/client/ios/networkextension/wireguard-go-version.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef WIREGUARD_GO_VERSION -#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@" -#endif // WIREGUARD_GO_VERSION \ No newline at end of file diff --git a/client/macos/networkextension/CMakeLists.txt b/client/macos/networkextension/CMakeLists.txt index efe1b8354..2e44b3629 100644 --- a/client/macos/networkextension/CMakeLists.txt +++ b/client/macos/networkextension/CMakeLists.txt @@ -114,25 +114,14 @@ set_property(TARGET AmneziaVPNNetworkExtension APPEND PROPERTY RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy ) -## Build wireguard-go-version.h -execute_process( - COMMAND go list -m golang.zx2c4.com/wireguard - WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo - OUTPUT_VARIABLE WG_VERSION_FULL -) -string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in - ${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h) -target_sources(AmneziaVPNNetworkExtension PRIVATE - ${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h) - target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}) target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/macos/universal2/libwg-go.a) +find_package(openvpnadapter REQUIRED) +target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::openvpnadapter) -message(${CLIENT_ROOT_DIR}) -message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a) -target_link_libraries(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a) +find_package(awg-apple REQUIRED) +target_link_libraries(AmneziaVPNNetworkExtension PRIVATE amnezia::awg-apple) -target_include_directories(AmneziaVPNNetworkExtension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers) +find_package(hev-socks5-tunnel REQUIRED) +target_link_libraries(AmneziaVPNNetworkExtension PRIVATE heiher::hev-socks5-tunnel) diff --git a/client/macos/networkextension/wireguard-go-version.h.in b/client/macos/networkextension/wireguard-go-version.h.in deleted file mode 100644 index 860bc3c36..000000000 --- a/client/macos/networkextension/wireguard-go-version.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef WIREGUARD_GO_VERSION -#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@" -#endif // WIREGUARD_GO_VERSION \ No newline at end of file diff --git a/cmake/cmake-conan b/cmake/cmake-conan deleted file mode 160000 index f578f7583..000000000 --- a/cmake/cmake-conan +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f578f75833e48d9432a6449a2762e325a88505c2 diff --git a/cmake/conan_provider.cmake b/cmake/conan_provider.cmake new file mode 100644 index 000000000..3a9fba602 --- /dev/null +++ b/cmake/conan_provider.cmake @@ -0,0 +1,722 @@ +# The MIT License (MIT) +# +# Copyright (c) 2024 JFrog +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set(CONAN_MINIMUM_VERSION 2.0.5) + +# Create a new policy scope and set the minimum required cmake version so the +# features behind a policy setting like if(... IN_LIST ...) behaves as expected +# even if the parent project does not specify a minimum cmake version or a minimum +# version less than this module requires (e.g. 3.0) before the first project() call. +# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html) +# +# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only +# affects the current policy scope, i.e. between the PUSH and POP in this case. +# +# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack +cmake_policy(PUSH) +cmake_minimum_required(VERSION 3.24) + + +function(detect_os os os_api_level os_sdk os_subsystem os_version) + # it could be cross compilation + message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}") + if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") + if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(${os} Macos PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") + set(${os} Neutrino PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") + set(${os} Windows PARENT_SCOPE) + set(${os_subsystem} cygwin PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS") + set(${os} Windows PARENT_SCOPE) + set(${os_subsystem} msys2 PARENT_SCOPE) + elseif(CMAKE_SYSTEM_NAME STREQUAL "Emscripten") + # https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L17C1-L17C34 + set(${os} Emscripten PARENT_SCOPE) + else() + set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE) + endif() + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + if(DEFINED ANDROID_PLATFORM) + string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM}) + elseif(DEFINED CMAKE_SYSTEM_VERSION) + set(_os_api_level ${CMAKE_SYSTEM_VERSION}) + endif() + message(STATUS "CMake-Conan: android api level=${_os_api_level}") + set(${os_api_level} ${_os_api_level} PARENT_SCOPE) + endif() + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS") + # CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja + # generators, but just has the original input string for Xcode. + if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT}) + set(_os_sdk ${CMAKE_OSX_SYSROOT}) + else() + if(CMAKE_OSX_SYSROOT MATCHES Simulator) + set(apple_platform_suffix simulator) + else() + set(apple_platform_suffix os) + endif() + if(CMAKE_OSX_SYSROOT MATCHES AppleTV) + set(_os_sdk "appletv${apple_platform_suffix}") + elseif(CMAKE_OSX_SYSROOT MATCHES iPhone) + set(_os_sdk "iphone${apple_platform_suffix}") + elseif(CMAKE_OSX_SYSROOT MATCHES Watch) + set(_os_sdk "watch${apple_platform_suffix}") + endif() + endif() + if(DEFINED os_sdk) + message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}") + set(${os_sdk} ${_os_sdk} PARENT_SCOPE) + endif() + if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) + message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}") + set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + + +function(detect_arch arch) + # CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one. + # Therefore this code only finds one. If the recipes support multiple architectures, the + # build will work. Otherwise, there will be a linker error for the missing architecture(s). + if(DEFINED CMAKE_OSX_ARCHITECTURES) + string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}") + list(LENGTH apple_arch_list apple_arch_count) + if(apple_arch_count GREATER 1) + message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.") + endif() + endif() + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "") + set(host_arch ${CMAKE_OSX_ARCHITECTURES}) + elseif(MSVC) + set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}) + else() + set(host_arch ${CMAKE_SYSTEM_PROCESSOR}) + endif() + if(host_arch MATCHES "aarch64|arm64|ARM64") + list(APPEND _arch armv8) + endif() + if(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7") + list(APPEND _arch armv7) + endif() + if(host_arch MATCHES armv7s) + list(APPEND _arch armv7s) + endif() + if(host_arch MATCHES "i686|i386|X86") + list(APPEND _arch x86) + endif() + if(host_arch MATCHES "AMD64|amd64|x86_64|x64") + list(APPEND _arch x86_64) + endif() + if(EMSCRIPTEN) + # https://github.com/emscripten-core/emscripten/blob/4.0.6/cmake/Modules/Platform/Emscripten.cmake#L294C1-L294C80 + list(APPEND _arch wasm) + endif() + message(STATUS "CMake-Conan: cmake_system_processor=${_arch}") + list(JOIN _arch "|" _arch) + set(${arch} ${_arch} PARENT_SCOPE) +endfunction() + + +function(detect_cxx_standard compiler cxx_standard) + set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE) + if(CMAKE_CXX_EXTENSIONS) + if(compiler STREQUAL "msvc") + set(${cxx_standard} "${CMAKE_CXX_STANDARD}" PARENT_SCOPE) + else() + set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE) + endif() + endif() +endfunction() + + +macro(detect_gnu_libstdcxx) + # _conan_is_gnu_libstdcxx true if GNU libstdc++ + check_cxx_source_compiles(" + #include + #if !defined(__GLIBCXX__) && !defined(__GLIBCPP__) + static_assert(false); + #endif + int main(){}" _conan_is_gnu_libstdcxx) + + # _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI + check_cxx_source_compiles(" + #include + static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\"); + int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi) + + set(_conan_gnu_libstdcxx_suffix "") + if(_conan_gnu_libstdcxx_is_cxx11_abi) + set(_conan_gnu_libstdcxx_suffix "11") + endif() + unset (_conan_gnu_libstdcxx_is_cxx11_abi) +endmacro() + + +macro(detect_libcxx) + # _conan_is_libcxx true if LLVM libc++ + check_cxx_source_compiles(" + #include + #if !defined(_LIBCPP_VERSION) + static_assert(false); + #endif + int main(){}" _conan_is_libcxx) +endmacro() + + +function(detect_lib_cxx lib_cxx) + if(CMAKE_SYSTEM_NAME STREQUAL "Android") + message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}") + set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE) + return() + endif() + + include(CheckCXXSourceCompiles) + + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + detect_gnu_libstdcxx() + set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") + set(${lib_cxx} "libc++" PARENT_SCOPE) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows") + # Check for libc++ + detect_libcxx() + if(_conan_is_libcxx) + set(${lib_cxx} "libc++" PARENT_SCOPE) + return() + endif() + + # Check for libstdc++ + detect_gnu_libstdcxx() + if(_conan_is_gnu_libstdcxx) + set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE) + return() + endif() + + # TODO: it would be an error if we reach this point + elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + # Do nothing - compiler.runtime and compiler.runtime_type + # should be handled separately: https://github.com/conan-io/cmake-conan/pull/516 + return() + else() + # TODO: unable to determine, ask user to provide a full profile file instead + endif() +endfunction() + + +function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type) + if(DEFINED CMAKE_CXX_COMPILER_ID) + set(_compiler ${CMAKE_CXX_COMPILER_ID}) + set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION}) + else() + if(NOT DEFINED CMAKE_C_COMPILER_ID) + message(FATAL_ERROR "C or C++ compiler not defined") + endif() + set(_compiler ${CMAKE_C_COMPILER_ID}) + set(_compiler_version ${CMAKE_C_COMPILER_VERSION}) + endif() + + message(STATUS "CMake-Conan: CMake compiler=${_compiler}") + message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}") + + if(_compiler MATCHES MSVC) + set(_compiler "msvc") + string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version) + # Configure compiler.runtime and compiler.runtime_type settings for MSVC + if(CMAKE_MSVC_RUNTIME_LIBRARY) + set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY}) + else() + set(_msvc_runtime_library MultiThreaded$<$:Debug>DLL) # default value documented by CMake + endif() + + set(_KNOWN_MSVC_RUNTIME_VALUES "") + list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL) + list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL) + list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$:Debug> MultiThreaded$<$:Debug>DLL) + + # only accept the 6 possible values, otherwise we don't don't know to map this + if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES) + message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings") + endif() + + # Runtime is "dynamic" in all cases if it ends in DLL + if(_msvc_runtime_library MATCHES ".*DLL$") + set(_compiler_runtime "dynamic") + else() + set(_compiler_runtime "static") + endif() + message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}") + + # Only define compiler.runtime_type when explicitly requested + # If a generator expression is used, let Conan handle it conditional on build_type + if(NOT _msvc_runtime_library MATCHES ":Debug>") + if(_msvc_runtime_library MATCHES "Debug") + set(_compiler_runtime_type "Debug") + else() + set(_compiler_runtime_type "Release") + endif() + message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}") + endif() + + unset(_KNOWN_MSVC_RUNTIME_VALUES) + + elseif(_compiler MATCHES AppleClang) + set(_compiler "apple-clang") + string(REPLACE "." ";" VERSION_LIST ${_compiler_version}) + list(GET VERSION_LIST 0 _compiler_version) + elseif(_compiler MATCHES Clang) + set(_compiler "clang") + string(REPLACE "." ";" VERSION_LIST ${_compiler_version}) + list(GET VERSION_LIST 0 _compiler_version) + elseif(_compiler MATCHES GNU) + set(_compiler "gcc") + string(REPLACE "." ";" VERSION_LIST ${_compiler_version}) + list(GET VERSION_LIST 0 _compiler_version) + endif() + + message(STATUS "CMake-Conan: [settings] compiler=${_compiler}") + message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}") + if (_compiler_runtime) + message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}") + endif() + if (_compiler_runtime_type) + message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}") + endif() + + set(${compiler} ${_compiler} PARENT_SCOPE) + set(${compiler_version} ${_compiler_version} PARENT_SCOPE) + set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE) + set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE) +endfunction() + + +function(detect_build_type build_type) + get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(NOT multiconfig_generator) + # Only set when we know we are in a single-configuration generator + # Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined + set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE) + endif() +endfunction() + + +macro(set_conan_compiler_if_appleclang lang command output_variable) + if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang") + execute_process(COMMAND xcrun --find ${command} + OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE) + cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path) + cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path) + if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}") + set(${output_variable} "") + endif() + unset(_xcrun_out) + unset(_xcrun_toolchain_path) + unset(_compiler_parent_path) + endif() +endmacro() + + +macro(append_compiler_executables_configuration) + set(_conan_c_compiler "") + set(_conan_cpp_compiler "") + set(_conan_rc_compiler "") + set(_conan_compilers_list "") + if(CMAKE_C_COMPILER) + set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"") + set_conan_compiler_if_appleclang(C cc _conan_c_compiler) + list(APPEND _conan_compilers_list ${_conan_c_compiler}) + else() + message(WARNING "CMake-Conan: The C compiler is not defined. " + "Please define CMAKE_C_COMPILER or enable the C language.") + endif() + if(CMAKE_CXX_COMPILER) + set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"") + set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler) + list(APPEND _conan_compilers_list ${_conan_cpp_compiler}) + else() + message(WARNING "CMake-Conan: The C++ compiler is not defined. " + "Please define CMAKE_CXX_COMPILER or enable the C++ language.") + endif() + if(CMAKE_RC_COMPILER) + set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"") + list(APPEND _conan_compilers_list ${_conan_rc_compiler}) + # Not necessary to warn if RC not defined + endif() + if(NOT "x${_conan_compilers_list}" STREQUAL "x") + if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}") + string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n") + endif() + endif() + unset(_conan_c_compiler) + unset(_conan_cpp_compiler) + unset(_conan_rc_compiler) + unset(_conan_compilers_list) +endmacro() + + +function(detect_host_profile output_file) + detect_os(os os_api_level os_sdk os_subsystem os_version) + detect_arch(arch) + detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type) + detect_cxx_standard(${compiler} compiler_cppstd) + detect_lib_cxx(compiler_libcxx) + detect_build_type(build_type) + + set(profile "") + string(APPEND profile "[settings]\n") + if(arch) + string(APPEND profile arch=${arch} "\n") + endif() + if(os) + string(APPEND profile os=${os} "\n") + endif() + if(os_api_level) + string(APPEND profile os.api_level=${os_api_level} "\n") + endif() + if(os_version) + string(APPEND profile os.version=${os_version} "\n") + endif() + if(os_sdk) + string(APPEND profile os.sdk=${os_sdk} "\n") + endif() + if(os_subsystem) + string(APPEND profile os.subsystem=${os_subsystem} "\n") + endif() + if(compiler) + string(APPEND profile compiler=${compiler} "\n") + endif() + if(compiler_version) + string(APPEND profile compiler.version=${compiler_version} "\n") + endif() + if(compiler_runtime) + string(APPEND profile compiler.runtime=${compiler_runtime} "\n") + endif() + if(compiler_runtime_type) + string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n") + endif() + if(compiler_cppstd) + string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n") + endif() + if(compiler_libcxx) + string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n") + endif() + if(build_type) + string(APPEND profile "build_type=${build_type}\n") + endif() + + if(NOT DEFINED output_file) + set(file_name "${CMAKE_BINARY_DIR}/profile") + else() + set(file_name ${output_file}) + endif() + + string(APPEND profile "[conf]\n") + string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n") + + # propagate compilers via profile + append_compiler_executables_configuration() + + if(os STREQUAL "Android") + string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n") + endif() + + message(STATUS "CMake-Conan: Creating profile ${file_name}") + file(WRITE ${file_name} ${profile}) + message(STATUS "CMake-Conan: Profile: \n${profile}") +endfunction() + + +function(conan_profile_detect_default) + message(STATUS "CMake-Conan: Checking if a default profile exists") + execute_process(COMMAND ${CONAN_COMMAND} profile path default + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_stdout + ERROR_VARIABLE conan_stderr + ECHO_ERROR_VARIABLE # show the text output regardless + ECHO_OUTPUT_VARIABLE + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + if(NOT ${return_code} EQUAL "0") + message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.") + execute_process(COMMAND ${CONAN_COMMAND} profile detect + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_stdout + ERROR_VARIABLE conan_stderr + ECHO_ERROR_VARIABLE # show the text output regardless + ECHO_OUTPUT_VARIABLE + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() +endfunction() + + +function(conan_install) + set(conan_output_folder ${CMAKE_BINARY_DIR}/conan) + # Invoke "conan install" with the provided arguments + set(conan_args -of=${conan_output_folder}) + message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}") + + + # In case there was not a valid cmake executable in the PATH, we inject the + # same we used to invoke the provider to the PATH + if(DEFINED PATH_TO_CMAKE_BIN) + set(old_path $ENV{PATH}) + set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}") + endif() + + execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_stdout + ERROR_VARIABLE conan_stderr + ECHO_ERROR_VARIABLE # show the text output regardless + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + if(DEFINED PATH_TO_CMAKE_BIN) + set(ENV{PATH} "${old_path}") + endif() + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + + # the files are generated in a folder that depends on the layout used, if + # one is specified, but we don't know a priori where this is. + # TODO: this can be made more robust if Conan can provide this in the json output + string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder) + cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder) + + message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}") + set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}") + # reconfigure on conanfile changes + string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label) + message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}") + set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}") + # success + set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE) + +endfunction() + + +function(conan_get_version conan_command conan_current_version) + execute_process( + COMMAND ${conan_command} --version + OUTPUT_VARIABLE conan_output + RESULT_VARIABLE conan_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(conan_result) + message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan") + endif() + + string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output}) + set(${conan_current_version} ${conan_version} PARENT_SCOPE) +endfunction() + + +function(conan_version_check) + set(options ) + set(one_value_args MINIMUM CURRENT) + set(multi_value_args ) + cmake_parse_arguments(conan_version_check + "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) + + if(NOT conan_version_check_MINIMUM) + message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!") + endif() + if(NOT conan_version_check_CURRENT) + message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!") + endif() + + if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM) + message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later") + endif() +endfunction() + + +macro(construct_profile_argument argument_variable profile_list) + set(${argument_variable} "") + if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE") + set(_arg_flag "--profile:host=") + elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE") + set(_arg_flag "--profile:build=") + endif() + + set(_profile_list "${${profile_list}}") + list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile") + list(TRANSFORM _profile_list PREPEND ${_arg_flag}) + set(${argument_variable} ${_profile_list}) + + unset(_arg_flag) + unset(_profile_list) +endmacro() + + +macro(conan_provide_dependency method package_name) + set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE) + get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) + if(NOT _conan_install_success) + find_program(CONAN_COMMAND "conan" REQUIRED) + conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION) + conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION}) + message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan") + if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE) + conan_profile_detect_default() + endif() + if("auto-cmake" IN_LIST CONAN_HOST_PROFILE) + detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile) + endif() + construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE) + construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE) + if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py") + file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile) + if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*") + message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile") + endif() + elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt") + file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile) + if(NOT "${outfile}" MATCHES ".*CMakeConfigDeps.*") + message(WARNING "Cmake-conan: CMakeConfigDeps generator was not defined in the conanfile") + endif() + endif() + + get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + + if(DEFINED CONAN_INSTALL_BUILD_CONFIGURATIONS) + # Configurations are specified by the project or user + set(_build_configs "${CONAN_INSTALL_BUILD_CONFIGURATIONS}") + list(LENGTH _build_configs _build_configs_length) + if(NOT _multiconfig_generator AND _build_configs_length GREATER 1) + message(FATAL_ERROR "cmake-conan: when using a single-config CMake generator, " + "please only specify a single configuration in CONAN_INSTALL_BUILD_CONFIGURATIONS") + endif() + unset(_build_configs_length) + else() + # No configuration overrides, provide sensible defaults + if(_multiconfig_generator) + set(_build_configs Release Debug) + else() + set(_build_configs ${CMAKE_BUILD_TYPE}) + endif() + + endif() + + list(JOIN _build_configs ", " _build_configs_msg) + message(STATUS "CMake-Conan: Installing configuration(s): ${_build_configs_msg}") + foreach(_build_config IN LISTS _build_configs) + set(_self_build_config "") + if(NOT _multiconfig_generator AND NOT _build_config STREQUAL "${CMAKE_BUILD_TYPE}") + set(_self_build_config -s &:build_type=${CMAKE_BUILD_TYPE}) + endif() + conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=${_build_config} ${_self_build_config} ${CONAN_INSTALL_ARGS}) + endforeach() + + get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) + if(EXISTS "${_conan_generators_folder}/conan_cmakedeps_paths.cmake") + message(STATUS "CMake-Conan: Loading conan_cmakedeps_paths.cmake file") + include(${_conan_generators_folder}/conan_cmakedeps_paths.cmake) + endif() + + unset(_self_build_config) + unset(_multiconfig_generator) + unset(_build_configs) + unset(_build_configs_msg) + unset(_host_profile_flags) + unset(_build_profile_flags) + unset(_conan_install_success) + else() + message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran") + unset(_conan_install_success) + endif() + + get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) + + # Ensure that we consider Conan-provided packages ahead of any other, + # irrespective of other settings that modify the search order or search paths + # This follows the guidelines from the find_package documentation + # (https://cmake.org/cmake/help/latest/command/find_package.html): + # find_package ( PATHS paths... NO_DEFAULT_PATH) + # find_package () + + # Filter out `REQUIRED` from the argument list, as the first call may fail + set(_find_args_${package_name} "${ARGN}") + list(REMOVE_ITEM _find_args_${package_name} "REQUIRED") + if(NOT "MODULE" IN_LIST _find_args_${package_name}) + find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + unset(_find_args_${package_name}) + endif() + + # Invoke find_package a second time - if the first call succeeded, + # this will simply reuse the result. If not, fall back to CMake default search + # behaviour, also allowing modules to be searched. + if(NOT ${package_name}_FOUND) + list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index) + if(_index EQUAL -1) + list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}") + endif() + unset(_index) + find_package(${package_name} ${ARGN} BYPASS_PROVIDER) + list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}") + endif() +endmacro() + + +cmake_language( + SET_DEPENDENCY_PROVIDER conan_provide_dependency + SUPPORTED_METHODS FIND_PACKAGE +) + + +macro(conan_provide_dependency_check) + set(_conan_provide_dependency_invoked FALSE) + get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED) + if(NOT _conan_provide_dependency_invoked) + message(WARNING "Conan is correctly configured as dependency provider, " + "but Conan has not been invoked. Please add at least one " + "call to `find_package()`.") + if(DEFINED CONAN_COMMAND) + # supress warning in case `CONAN_COMMAND` was specified but unused. + set(_conan_command ${CONAN_COMMAND}) + unset(_conan_command) + endif() + endif() + unset(_conan_provide_dependency_invoked) +endmacro() + + +# Add a deferred call at the end of processing the top-level directory +# to check if the dependency provider was invoked at all. +cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check) + +# Configurable variables for Conan profiles +set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile") +set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile") +set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install") + +find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH) +if(NOT _cmake_program) + get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY) + set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is") +endif() + +cmake_policy(POP) diff --git a/conanfile.py b/conanfile.py index cbfd38135..80b8a1c4a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -4,12 +4,18 @@ class AmneziaVPN(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeConfigDeps" + options = { + "macos_ne": [True, False] + } + default_options = { + "macos_ne": False + } + def requirements(self): os = str(self.settings.os) - arch = str(self.settings.arch) - has_service = os == "Windows" or os == "Linux" or (os == "Macos" and arch == "x86_64") - has_network_extension = os == "iOS" or (os == "Macos" and not has_service) + has_ne = os == "iOS" or (os == "Macos" and self.options.macos_ne) + has_service = os == "Windows" or os == "Linux" or (os == "Macos" and not has_ne) if has_service: if os == "Windows": @@ -21,13 +27,15 @@ class AmneziaVPN(ConanFile): self.requires("tun2socks/2.6.0") self.requires("openvpn/2.7.0") - if has_network_extension: + if has_ne: self.requires("awg-apple/2.0.1") + self.requires("hev-socks5-tunnel/2.14.4", options={"as_framework": True}) + self.requires("openvpnadapter/1.0.0") if os == "Android": self.requires("amnezia-libxray/1.0.0") self.requires("awg-android/1.1.7") self.requires("openvpn-pt-android/1.0.0") - self.requires("libssh-local/0.11.3") + self.requires("libssh/0.11.3@amnezia") self.requires("openssl/3.5.5") diff --git a/recipes/awg-apple/conanfile.py b/recipes/awg-apple/conanfile.py index a1e2cd0b7..0fe6385da 100644 --- a/recipes/awg-apple/conanfile.py +++ b/recipes/awg-apple/conanfile.py @@ -1,59 +1,69 @@ from conan import ConanFile from conan.errors import ConanInvalidConfiguration from conan.tools.layout import basic_layout -from conan.tools.files import get, copy, collect_libs +from conan.tools.files import get, copy, collect_libs, chdir +from conan.tools.apple import is_apple_os +from conan.tools.gnu import AutotoolsToolchain, Autotools import os +_uniarch_separator = "|" + class AwgApple(ConanFile): name = "awg-apple" version = "2.0.1" settings = "os", "arch" - - _os_map = { - "iOS": "iphoneos", - "Macos": "macosx" + options = { + "as_framework": [True, False] + } + default_options = { + "as_framework": False } - _arch_map = { - "x86_64": "x86_64", - "armv8": "arm64" - } + @property + def goarch(self): + arch_map = { + "armv8": "arm64", + "x86_64": "x86_64", + } + archs = str(self.settings.arch).split(_uniarch_separator) + return " ".join(arch_map.get(arch, arch) for arch in archs) def build_requirements(self): self.tool_requires("go/1.26.0") - if self.settings.os == "Windows": - self.tool_requires("mingw-builds/15.1.0") - else: - self.build_requires("make/4.4.1") - - def configure(self): - self._goos = self._os_map.get(str(self.settings.os)) - if not self._goos: - raise ConanInvalidConfiguration( - f"{self.name} v{self.version} does not support {self._goos}" - ) - - self._goarch = self._arch_map.get(str(self.settings.arch)) - if not self._goarch: - raise ConanInvalidConfiguration( - f"{self.name} v{self.version} does not support {self._goarch}" - ) def layout(self): basic_layout(self, build_folder=os.path.join(self.folders.source, "Sources/WireGuardKitGo")) + def validate(self): + if not is_apple_os(self): + raise ConanInvalidConfiguration( + f"{self.name} v{self.version} does not support {self.settings.os}" + ) + def source(self): get(self, f"https://github.com/amnezia-vpn/amneziawg-apple/archive/refs/tags/v{self.version}.zip", sha256="9fe4f8cfbb6a751558b54b7979db3a5ea46e49731912aae99f093e84a1433e97", strip_root=True ) + def generate(self): + tc = AutotoolsToolchain(self) + sdk = self.settings.get_safe("os.sdk", "macosx") + tc.make_args = [ + f"ARCHS={self.goarch}", + f"PLATFORM_NAME={sdk}" + ] + tc.generate() + def build(self): - self.run(f"ARCHS={self._goarch} PLATFORM_NAME={self._goos} make") + autotools = Autotools(self) + autotools.make() + autotools.make("version-header") def package(self): copy(self, "wireguard.h", src=self.build_folder, dst=os.path.join(self.package_folder, "include")) + copy(self, "*.h", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "include")) copy(self, "*.a", src=os.path.join(self.build_folder, "out"), dst=os.path.join(self.package_folder, "lib")) def package_info(self): diff --git a/recipes/hev-socks5-tunnel/conanfile.py b/recipes/hev-socks5-tunnel/conanfile.py index 84dd946a2..f7f00ed27 100644 --- a/recipes/hev-socks5-tunnel/conanfile.py +++ b/recipes/hev-socks5-tunnel/conanfile.py @@ -1,5 +1,99 @@ from conan import ConanFile +from conan.tools.layout import basic_layout +from conan.tools.scm import Git +from conan.tools.files import copy, collect_libs +from conan.internal.model.pkg_type import PackageType +from conan.tools.gnu import AutotoolsToolchain, Autotools +from conan.tools.apple import is_apple_os + +import platform +import os +import shutil + + +required_conan_version = ">=2.26" + class HevSocks5Tunnel(ConanFile): name = "hev-socks5-tunnel" - version = "1.0.0" \ No newline at end of file + version = "2.14.4" + settings = "os", "arch" + options = { + "shared": [True, False], + "as_framework": [True, False], + } + default_options = { + "shared": False, + "as_framework": False + } + + def config_options(self): + if not is_apple_os(self): + del self.options.as_framework + + def configure(self): + if self.options.get_safe("as_framework"): + self.options.shared = False + + def layout(self): + basic_layout(self, build_folder=".") + + def source(self): + git = Git(self) + git.clone( + url="https://github.com/heiher/hev-socks5-tunnel.git", + target=".", + args=["--recurse-submodules", "--branch", self.version] + ) + + def generate(self): + tc = AutotoolsToolchain(self) + tc.generate() + + def build(self): + autotools = Autotools(self) + autotools.make("shared" if self.options.shared else "static") + + if self.options.get_safe("as_framework"): + lib_path = os.path.join(self.build_folder, "bin", "libhev-socks5-tunnel.a") + self.run( + f"libtool -static -o {lib_path}" + f" {lib_path}" + f" {os.path.join(self.build_folder, "third-part", "lwip", "bin", "liblwip.a")}" + f" {os.path.join(self.build_folder, "third-part", "yaml", "bin", "libyaml.a")}" + f" {os.path.join(self.build_folder, "third-part", "hev-task-system", "bin", "libhev-task-system.a")}" + ) + + include_dir = os.path.join(self.build_folder, "framework_include") + copy(self, "hev-main.h", src=os.path.join(self.source_folder, "src"), dst=include_dir) + copy(self, "module.modulemap", src=os.path.join(self.source_folder), dst=include_dir) + + self.run('xcodebuild -create-xcframework' + f' -library {lib_path}' + f' -headers {include_dir}' + f' -output {os.path.join(self.build_folder, "HevSocks5Tunnel.xcframework")}' + ) + + def package(self): + if self.options.get_safe("as_framework"): + shutil.copytree(src=os.path.join(self.build_folder, "HevSocks5Tunnel.xcframework"), + dst=os.path.join(self.package_folder, "HevSocks5Tunnel.xcframework")) + else: + copy(self, "hev-main.h", src=os.path.join(self.source_folder, "src"), dst=os.path.join(self.package_folder, "include")) + copy(self, "*.a", src=os.path.join(self.build_folder, "bin"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.so", src=os.path.join(self.build_folder, "bin"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "lwip"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "lwip"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "yaml"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "yaml"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.a", src=os.path.join(self.build_folder, "bin", "third-part", "hev-task-system"), dst=os.path.join(self.package_folder, "lib")) + copy(self, "*.so", src=os.path.join(self.build_folder, "bin", "third-part", "hev-task-system"), dst=os.path.join(self.package_folder, "lib")) + + def package_info(self): + self.cpp_info.set_property("cmake_target_name", "heiher::hev-socks5-tunnel") + if self.options.get_safe("as_framework"): + self.cpp_info.type = PackageType.STATIC + self.cpp_info.package_framework = True + self.cpp_info.location = os.path.join(self.package_folder, "HevSocks5Tunnel.xcframework") + else: + self.cpp_info.libraries = collect_libs(self) diff --git a/recipes/libssh-local/conanfile.py b/recipes/libssh/conanfile.py similarity index 98% rename from recipes/libssh-local/conanfile.py rename to recipes/libssh/conanfile.py index f49548a3a..30f71a67b 100644 --- a/recipes/libssh-local/conanfile.py +++ b/recipes/libssh/conanfile.py @@ -10,9 +10,10 @@ import os required_conan_version = ">=2.21" -class LibsshLocal(ConanFile): - name = "libssh-local" +class LibSSHRecipe(ConanFile): + name = "libssh" version = "0.11.3" + user = "amnezia" license = "LGPL-2.1" homepage = "https://www.libssh.org/" description = "multiplatform C library implementing the SSHv2 protocol on client and server side" diff --git a/recipes/openvpnadapter/conanfile.py b/recipes/openvpnadapter/conanfile.py new file mode 100644 index 000000000..a6bce48ad --- /dev/null +++ b/recipes/openvpnadapter/conanfile.py @@ -0,0 +1,70 @@ +from conan import ConanFile +from conan.tools.layout import basic_layout +from conan.tools.apple import is_apple_os +from conan.errors import ConanInvalidConfiguration +from conan.tools.scm import Git +from conan.internal.model.pkg_type import PackageType +from conan.tools.files import chdir + +import os +import shutil + +class OpenVPNAdapter(ConanFile): + name = "openvpnadapter" + version = "1.0.0" + settings = "os", "build_type" + + @property + def _platform(self): + sdk = self.settings.get_safe("os.sdk", "macosx") + return { + "macosx": "macOS", + "iphoneos": "iOS", + "iphonesimulator": "iOS Simulator" + }.get(sdk) + + @property + def _configuration(self): + return "Debug" if self.settings.get_safe("build_type") == "Debug" else "Release" + + def layout(self): + basic_layout(self) + + def validate(self): + if not is_apple_os(self): + raise ConanInvalidConfiguration( + f"There is absolutely no point building Apple framework for {self.settings.os}" + ) + + def source(self): + git = Git(self) + git.clone( + url="https://github.com/amnezia-vpn/OpenVPNAdapter.git", + target=".", + args=["--recurse-submodules", "--branch", "master-amnezia"] + ) + + def build(self): + sdk = self.settings.get_safe("os.sdk", "macosx") + with chdir(self, self.source_folder): + self.run("xcrun xcodebuild" + " -project OpenVPNAdapter.xcodeproj" + " -scheme OpenVPNAdapter" + " -configuration Release" + f" -destination 'generic/platform={self._platform}'" + f" -sdk {sdk}" + f' "CONFIGURATION_BUILD_DIR={self.build_folder}"' + f' "BUILT_PRODUCTS_DIR={self.build_folder}"' + " BUILD_LIBRARY_FOR_DISTRIBUTION=YES" + " CODE_SIGNING_ALLOWED=NO" + ) + + def package(self): + shutil.copytree(os.path.join(self.build_folder, "OpenVPNAdapter.framework"), + os.path.join(self.package_folder, "OpenVPNAdapter.framework")) + + def package_info(self): + self.cpp_info.set_property("cmake_target_name", "amnezia::openvpnadapter") + self.cpp_info.type = PackageType.STATIC + self.cpp_info.package_framework = True + self.cpp_info.location = os.path.join(self.package_folder, "OpenVPNAdapter.framework")