# Copyright (c) <2014-2017> <Newton Game Dynamics>
#
# This software is provided 'as-is', without any express or implied
# warranty. In no event will the authors be held liable for any damages
# arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely.

cmake_minimum_required(VERSION 3.9.0 FATAL_ERROR)

option("NEWTON_EXCLUDE_TEST" "generate test project" "OFF")
option("NEWTON_BUILD_SANDBOX_DEMOS" "generates demos projects" "ON")
option("NEWTON_BUILD_PROFILER" "build profiler" OFF)
option("NEWTON_BUILD_SINGLE_THREADED" "single threaded" OFF)
option("NEWTON_BUILD_SHARED_LIBS" "build shared library" ON)
option("NEWTON_ENABLE_AVX2_SOLVER" "enable AVX2 solver"  ON)
option("NEWTON_ENABLE_CUDA_SOLVER" "enable cuda solver" OFF)
option("NEWTON_ENABLE_OPENCL_SOLVER" "enable gpu solver" OFF)
option("NEWTON_DOUBLE_PRECISION" "generate double precision" OFF)
option("NEWTON_NO_SIMD_INTRINSICS" "generate simd vector class" OFF)
option("NEWTON_BUILD_NEWTON_JAVA" "build a sharp wrapper" OFF)
option("NEWTON_BUILD_NEWTON_PYTHON" "build python wrapper" OFF)
option("NEWTON_BUILD_NEWTON_C_SHARP" "build a sharp wrapper" OFF)
option("NEWTON_BUILD_NEWTON_BLENDER" "build blender wrapper" OFF)
option("NEWTON_BUILD_ANDROID_STUDIO" "build a android studio package" OFF)
option("NEWTON_STATIC_RUNTIME_LIBRARIES" "use windows static libraries" OFF)
option("NEWTON_BUILD_CREATE_SUB_PROJECTS" "generate independent subproject" OFF)
option("NEWTON_USE_DEFAULT_NEW_AND_DELETE" "overload new and delete when building dll" OFF)

set(CMAKE_CONFIGURATION_TYPES Debug RelWithDebInfo Release)
set(CMAKE_DEBUG_POSTFIX "_d")

project(NewtonSDK)

# determine if we are compiling for a 32bit or 64bit system
include(CheckTypeSize)
CHECK_TYPE_SIZE("void*" PTR_SIZE BUILTIN_TYPES_ONLY)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Don't use e.g. GNU extension (like -std=gnu++11) for portability
set(CMAKE_CXX_EXTENSIONS OFF)

if(NEWTON_NO_SIMD_INTRINSICS)
	add_definitions(-DD_SCALAR_VECTOR_CLASS)
endif()

if(NEWTON_DOUBLE_PRECISION)
	add_definitions(-DD_NEWTON_USE_DOUBLE)
endif()

if(NEWTON_BUILD_SINGLE_THREADED)
	add_definitions(-DD_USE_THREAD_EMULATION)
endif()

if(NEWTON_BUILD_SHARED_LIBS)
    add_definitions(-D_D_CORE_DLL)
	add_definitions(-D_D_TINY_DLL)
	add_definitions(-D_D_NEWTON_DLL)
	add_definitions(-D_D_COLLISION_DLL)
endif(NEWTON_BUILD_SHARED_LIBS)

#If no build type set, Release as default
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING
          "Choose the type of build, options are: Debug RelWithDebInfo Release"
          FORCE)
endif(NOT CMAKE_BUILD_TYPE)

#check for MAC
if(APPLE)
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fms-extensions")
endif(APPLE)

#check for UNIX
if(UNIX)
  # ----------------------------------------------------------------------
  # Ensure the RPATH for libndNewton is set correctly both inside the build
  # tree as well as in the installed location (ie after `make install`).
  #
  # The following settings were adapted from here
  # https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/RPATH-handling

  # Use the full RPATH for the build tree.
  set(CMAKE_SKIP_BUILD_RPATH FALSE)

  # Do not use the install RPATH during building but use later on when we install the library.
  set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

  # Set this RPATH in the installed library.
  # NOTE: specify CMAKE_INSTALL_PREFIX as an absolute path or it will almost certainly not work.
  set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")

  # Add the automatically determined parts of the RPATH which point to directories
  # outside the build tree to the install RPATH.
  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

  # Only use the RPATH if the target is not a system directory.
  list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
  if("${isSystemDir}" STREQUAL "-1")
    set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
  endif("${isSystemDir}" STREQUAL "-1")
  # ----------------------------------------------------------------------

  set(CMAKE_POLICY_DEFAULT_CMP0072 NEW)
	if(NOT NEWTON_BUILD_SHARED_LIBS)
		add_compile_options(-fPIC)
	endif()

	include("GNUInstallDirs")

	# uninstall target
	if(NOT TARGET uninstall)
		configure_file(
			"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
			"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
			IMMEDIATE @ONLY)

		add_custom_target(uninstall
			COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
	endif()

	#if(NOT ANDROID OR NOT APPLE)
	#	add_compile_options(-msse3)
	#endif()

	#add_compile_options(-fpermissive)

	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
endif ()

if (MSVC)
	add_definitions(-D_CRT_SECURE_NO_WARNINGS)

	if (PTR_SIZE EQUAL 8)
		set(CMAKE_INSTALL_PREFIX "win64sdk" CACHE PATH "..." FORCE)
	else()
		set(CMAKE_INSTALL_PREFIX "win32sdk" CACHE PATH "..." FORCE)
	endif ()

	if(NEWTON_STATIC_RUNTIME_LIBRARIES)
		message ("link to static runtime libraries")
		set(CMAKE_C_FLAGS_DEBUG "/MTd")
		set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MT")
		set(CMAKE_C_FLAGS_RELEASE "/MT")
		set(CMAKE_CXX_FLAGS_DEBUG "/MTd")
		set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MT")
		set(CMAKE_CXX_FLAGS_RELEASE "/MT")
	else()
		message ("link to dynamic runtime libraries")
		set(CMAKE_C_FLAGS_DEBUG "/MDd")
		set(CMAKE_C_FLAGS_RELWITHDEBINFO "/MD")
		set(CMAKE_C_FLAGS_RELEASE "/MD")
		set(CMAKE_CXX_FLAGS_DEBUG "/MDd")
		set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD")
		set(CMAKE_CXX_FLAGS_RELEASE "/MD")
	endif()

	message("Compiler Id: ${CMAKE_CXX_COMPILER_ID}") 
	
	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Zi /Od /fp:fast")
	set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /Zi /O2 /fp:fast")
	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /GS /Ox /Oi /Ot /Ob2 /Oy /fp:fast")
	set(CMAKE_WARNINGS "/Wall /wd4061 /wd4201 /wd4324 /wd4505 /wd4514 /wd4582 /wd4587 /wd4625 /wd4626 /wd4710 /wd4711 /wd4371 /wd4571 /wd4623 /wd4668 /wd4774 /wd4820 /wd5026 /wd5027 /wd5039 /wd5045 /wd5264")

	message("CMAKE_WARNINGS is ${CMAKE_WARNINGS}")
	message("CMAKE_CXX_FLAGS_DEBUG is ${CMAKE_CXX_FLAGS_DEBUG}")
	message("CMAKE_CXX_FLAGS_RELEASE is ${CMAKE_CXX_FLAGS_RELEASE}")
	message("CMAKE_CXX_FLAGS_RELWITHDEBINFO is ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")

	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_WARNINGS}")
	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_WARNINGS}")
	set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_WARNINGS}")

	set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Zi /Od")
	set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi /Od")
	set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Zi /Od")

elseif(MINGW)
	add_compile_options(-msse3)

	if(CMAKE_CL_64)
		message("build 64 bit")
	else()
		message("build 32 bit")
	endif()
endif()

if(NEWTON_BUILD_PROFILER)
	add_definitions(-DD_PROFILER)
endif()

add_subdirectory(sdk)
add_subdirectory(thirdParty)
add_subdirectory(applications)

if (NOT NEWTON_EXCLUDE_TEST)
	message("building unit tests")
	file(REMOVE_RECURSE ${PROJECT_BINARY_DIR}/_deps)
	add_subdirectory(tests)
endif()


