cmake_minimum_required (VERSION 2.8)

cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0048 NEW)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

project(lib3mf)


include(GNUInstallDirs)

# Define Version
set(LIB3MF_VERSION_MAJOR 2)        # increase on every backward-compatibility breaking change of the API
set(LIB3MF_VERSION_MINOR 0)        # increase on every backward compatible change of the API
set(LIB3MF_VERSION_MICRO 0)        # increase on on every change that does not alter the API
set(LIB3MF_VERSION_PRERELEASE "")  # denotes pre-release information of a version of lib3mf

set(CMAKE_INSTALL_BINDIR bin CACHE PATH "directory for installing binary files")
set(CMAKE_INSTALL_LIBDIR lib CACHE PATH "directory for installing library files")
set(CMAKE_INSTALL_INCLUDEDIR include/lib3mf CACHE PATH "directory for installing header files")

option(USE_INCLUDED_ZLIB "Use included zlib" ON)
option(USE_INCLUDED_LIBZIP "Use included libzip" ON)

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  # using GCC
  add_definitions(-DBUILD_DLL)
  add_compile_options(-Wall)
  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2")
elseif ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
  # using GCC
  add_definitions(-DBUILD_DLL)
  add_compile_options(-Wall) 
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2")
  set(CMAKE_MACOSX_RPATH ON)
endif()

if (${MSVC})
  # using Visual Studio C++

  # this ensures that the min/max macros of minwindef.h are not used
  add_definitions(-DNOMINMAX /W3)

  add_definitions(/W3)
  
  # add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS)
  # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
  # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif()

### The API generation target
if(UNIX OR MINGW)
  if(APPLE)
    set(ACT_COMMANDENDING darwin)
  else()
    set(ACT_COMMANDENDING linux)
  endif()
elseif(WIN32)
  set(ACT_COMMANDENDING exe)
endif()

set(CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED ${CMAKE_CURRENT_BINARY_DIR}/Autogenerated)
set(CMAKE_TEMP_HEADER_FOLDER "${CMAKE_CURRENT_SOURCE_DIR}/AutomaticComponentToolkit/Lib3MF_component")
set(ACT_GENERATED_SOURCE
  ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Source/Implementation/lib3mf_interfaceexception.cpp
  ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Source/Implementation/lib3mf_interfacewrapper.cpp
  ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Source/Implementation/lib3mf_interfacejournal.cpp 
)
add_custom_command(
  BYPRODUCTS
    ${ACT_GENERATED_SOURCE}
  OUTPUT
    ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/LIB3MFACTGENERATIONSTAMP
  WORKING_DIRECTORY
    ${CMAKE_CURRENT_SOURCE_DIR}/AutomaticComponentToolkit
  COMMAND
    cmake -E make_directory "${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}"
  COMMAND
    cmake -E touch "${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/LIB3MFACTGENERATIONSTAMP"
  COMMAND
    ${CMAKE_CURRENT_SOURCE_DIR}/AutomaticComponentToolkit/bin/act.${ACT_COMMANDENDING} ${CMAKE_CURRENT_SOURCE_DIR}/AutomaticComponentToolkit/lib3mf.xml
  COMMAND
    cmake -E remove_directory "${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Source"
  COMMAND
    cmake -E remove_directory "${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Bindings"
  COMMAND
    cmake -E copy_directory "${CMAKE_TEMP_HEADER_FOLDER}/Bindings" ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Bindings
  COMMAND
    cmake -E copy_directory "${CMAKE_TEMP_HEADER_FOLDER}/Implementations/Cpp/Interfaces" "${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Source/Implementation"
  COMMAND
    cmake -E remove_directory "${CMAKE_TEMP_HEADER_FOLDER}"
  COMMENT
    "Generating hourglass API bindings and implementation stub"
  DEPENDS
    ${CMAKE_CURRENT_SOURCE_DIR}/AutomaticComponentToolkit/lib3mf.xml
  VERBATIM
)

add_custom_target(lib3mfACT
  DEPENDS
    ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/LIB3MFACTGENERATIONSTAMP
  SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/AutomaticComponentToolkit/lib3mf.xml
)

include(Source/CMakeLists.txt)
#########################################################
# Set version info
if(DEFINED ENV{BUILD_NUMBER})
  set(BUILD_NUMBER $ENV{BUILD_NUMBER})
else()
  set(BUILD_NUMBER 0)
endif()

if (WIN32)
  message("BUILD_NUMBER ... " ${BUILD_NUMBER})
  set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/Include/VersionInfo)

  include(generate_product_version)
    generate_product_version(
    VERSION_FILES_OUTPUTLOCATION
    NAME "lib3mf"
    FILE_DESCRIPTION "lib3mf is an implementation of the 3D Manufacturing Format file standard"
    BUNDLE "3MF Consortium"
    VERSION_MAJOR ${LIB3MF_VERSION_MAJOR}
    VERSION_MINOR ${LIB3MF_VERSION_MINOR}
    VERSION_PATCH ${LIB3MF_VERSION_MICRO}
    VERSION_REVISION ${BUILD_NUMBER}
    PRODUCT_VERSION_MAJOR ${LIB3MF_VERSION_MAJOR}
    PRODUCT_VERSION_MINOR ${LIB3MF_VERSION_MINOR}
    PRODUCT_VERSION_PATCH ${LIB3MF_VERSION_MICRO}
    PRODUCT_VERSION_REVISION ${LIB3MF_VERSION_PRERELEASE}
    COMPANY_NAME "3MF Consortium"
  )
  message("VERSION_FILES_OUTPUTLOCATION ... " ${VERSION_FILES_OUTPUTLOCATION})
else()
  set(VERSION_FILES_OUTPUTLOCATION "")
endif()


#########################################################
# Shared library
add_library(${PROJECT_NAME} SHARED ${SRCS_COMMON} ${HDRS_COMMON}
  ${ACT_GENERATED_SOURCE}
  ${VERSION_FILES_OUTPUTLOCATION}
)
SOURCE_GROUP("Source Files\\Autogenerated" FILES ${ACT_GENERATED_SOURCE})

add_dependencies(${PROJECT_NAME} lib3mfACT)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Source/Implementation)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include/API)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/Include)

set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" IMPORT_PREFIX "" )
# This makes sure symbols are exported
target_compile_options(${PROJECT_NAME} PRIVATE "-D__LIB3MF_EXPORTS")
# The following two properties are crucial to reduce the number of undesirably exported symbols
set_target_properties(${PROJECT_NAME} PROPERTIES C_VISIBILITY_PRESET hidden)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden)
set_target_properties(${PROJECT_NAME} PROPERTIES VISIBILITY_INLINES_HIDDEN ON)

set(STARTUPPROJECT ${PROJECT_NAME})

#########################################################
if (UNIX OR MINGW)
  # Uncomment the following to put the version info into the .so-file.
  set_target_properties(${PROJECT_NAME} PROPERTIES VERSION "${LIB3MF_VERSION_MAJOR}.${LIB3MF_VERSION_MINOR}.${LIB3MF_VERSION_MICRO}.${BUILD_NUMBER}")
  set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION "${LIB3MF_VERSION_MAJOR}")
  if (NOT APPLE)
    set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS -s)
  endif()
else()
  # wd4996 masks the deprecated-warning
  target_compile_options(${PROJECT_NAME} PUBLIC "$<$<CONFIG:DEBUG>:/Od;/Ob0;/sdl;/W3;/WX;/FC;/wd4996>")
  target_compile_options(${PROJECT_NAME} PUBLIC "$<$<CONFIG:RELEASE>:/O2;/sdl;/WX;/Oi;/Gy;/FC;/wd4996>")
endif()

install(TARGETS ${PROJECT_NAME}
  ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR_AUTOGENERATED}/Bindings DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")

#########################################################
option(LIB3MF_TESTS "Switch whether the tests of lib3mf should be build" ON)
message("LIB3MF_TESTS ... " ${LIB3MF_TESTS})
if(LIB3MF_TESTS)
  enable_testing()
  add_subdirectory(Tests)
endif()

#########################################################
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  IF(${CMAKE_VERSION} VERSION_LESS 3.6.3)
    MESSAGE ("Note: You need to manually select a StartUp-project in Visual Studio.")
  ELSE()
    set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${STARTUPPROJECT})
  ENDIF()
endif()