# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Build script used by `flutter pub run webcrypto:setup` to create
# `.dart_tool/webcrypto/webcrypto.{so|dylib|dll}` for use by `flutter test`.
#
# When running as a plugin platform specific build scripts will be used:
#  - `android/CMakeLists.txt`, for Android,
#  -  TODO: `ios/podspec...`
#
# This script is very similar to platform specific build scripts.

cmake_minimum_required(VERSION 3.6.0)
project(webcrypto)

enable_language(ASM)

# Set as required by ../third_party/boringssl/sources.cmake included below
set(BORINGSSL_ROOT ../third_party/boringssl/)

# Import sources as generated by tool/update-boringssl.py
# This provides variables, and requires BORINGSSL_ROOT to be set.
#  - crypto_sources
#  - crypto_sources_linux_aarch64
#  - crypto_sources_linux_arm
#  - crypto_sources_linux_ppc64le
#  - crypto_sources_linux_x86
#  - crypto_sources_linux_x86_64
#  - crypto_sources_mac_x86
#  - crypto_sources_mac_x86_64
#  - crypto_sources_win_x86
#  - crypto_sources_win_x86_64
include(
  ../third_party/boringssl/sources.cmake
)

# Tradeoff performance for smaller binary size, see:
# https://boringssl.googlesource.com/boringssl/+/HEAD/BUILDING.md#binary-size
add_definitions(-DOPENSSL_SMALL)

# Logic from CMakeLists.txt in BoringSSL
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
  set(ARCH "x86_64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64")
  set(ARCH "x86_64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    set(ARCH "x86_64")
  else()
    set(ARCH "x86")
  endif()
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86")
  set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
  set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
  set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
  set(ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64")
  set(ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64e")
  set(ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm*")
  set(ARCH "arm")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ppc64le")
  set(ARCH "ppc64le")
else()
  set(ARCH "generic")
endif()

# https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_NAME.html
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
  set(PLATFORM "win")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
  set(PLATFORM "mac")
else()
  # Assume we're on linux or similar platform
  set(PLATFORM "linux")
endif()

# If there is no assembly files disable ASM and set empty sources list
if(NOT DEFINED crypto_sources_${PLATFORM}_${ARCH})
  add_definitions(-DOPENSSL_NO_ASM)
  set(crypto_sources_${PLATFORM}_${ARCH})
endif()

if(MSVC)
  # Windows/MSVC option from CMakeLists.txt in BoringSSL
  set(MSVC_DISABLED_WARNINGS_LIST
      "C4100" # 'exarg' : unreferenced formal parameter
      "C4127" # conditional expression is constant
      "C4244" # 'function' : conversion from 'int' to 'uint8_t',
              # possible loss of data
      "C4267" # conversion from 'size_t' to 'int', possible loss of data
      "C4706" # assignment within conditional expression
      "C4141"
      )
  string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
                            ${MSVC_DISABLED_WARNINGS_LIST})
  set(CMAKE_C_FLAGS   "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")
  set(CMAKE_CXX_FLAGS "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")

  # Hack because Windows compilers will put .dll files in
  # $CMAKE_BINARY_DIR/Debug/ folder.
  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}>)
endif()
if(WIN32)
  # Windows/MSVC option from CMakeLists.txt in BoringSSL
  # Use NASM on Windows.
  enable_language(ASM_NASM)
  set(OPENSSL_NASM TRUE)
  set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8")
  # On Windows, prefer cl over gcc if both are available. By default most of
  # the CMake generators prefer gcc, even on Windows.
  set(CMAKE_GENERATOR_CC cl)
  add_definitions(-D_HAS_EXCEPTIONS=0)
  add_definitions(-DWIN32_LEAN_AND_MEAN)
  add_definitions(-DNOMINMAX)
  # Allow use of fopen.
  add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()

add_library(
  webcrypto
  
  # Build a shared library
  SHARED
  
  # Source files
  ../src/webcrypto.c
  ../src/symbols.generated.c
  ${crypto_sources}
  ${crypto_sources_${PLATFORM}_${ARCH}}
)

target_include_directories(
  webcrypto

  PRIVATE

  ../third_party/boringssl/src/include/
)

set_target_properties(
  webcrypto

  PROPERTIES
  
  C_VISIBILITY_PRESET hidden
  VISIBILITY_INLINES_HIDDEN 1
)
