cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

if(POLICY CMP0048)
    cmake_policy(SET CMP0048 NEW)
endif()
if(POLICY CMP0058)
    cmake_policy(SET CMP0058 NEW)
endif()
if(POLICY CMP0114)
    cmake_policy(SET CMP0114 NEW)
endif()
if(POLICY CMP0148)
    cmake_policy(SET CMP0148 NEW)
endif()

project(cqasm LANGUAGES C CXX)

# If cqasm was already included elsewhere in the project, don't include it again.
# There should be only one place for it and one version per project.
if(NOT TARGET cqasm)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)

# Library type option. Default is a static library.
option(BUILD_SHARED_LIBS
    "whether the cqasm library should be built as a shared object or as a static library"
    OFF
)

# Whether tests should be built.
option(LIBQASM_BUILD_TESTS
    "whether the tests should be built and added to `make test`"
    OFF
)

# Whether the Python module should be built.
# This should only be enabled for setup.py's builds.
option(LIBQASM_BUILD_PYTHON
    "Whether the Python module should be built"
    OFF
)
mark_as_advanced(LIBQASM_BUILD_PYTHON)

# Where the "libQasm" Python module should be built.
set(LIBQASM_PYTHON_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/python/libQasm"
    CACHE STRING "Where to install the libQasm Python module"
)
mark_as_advanced(LIBQASM_PYTHON_DIR)

# Where the "cqasm" Python module should be built.
set(LIBQASM_CQASM_PYTHON_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/python/cqasm"
    CACHE STRING "Where to install the cqasm Python module"
)
mark_as_advanced(LIBQASM_CQASM_PYTHON_DIR)

# Used to override the (base)name of the Python extension.
set(LIBQASM_PYTHON_EXT ""
    CACHE STRING "Basename for the Python extension, or \"\" to let CMake's SWIG implementation handle it"
)
mark_as_advanced(LIBQASM_PYTHON_EXT)

# Make an output directory to store the Python files generated by tree-gen in.
set(LIBQASM_GENERATED_PYTHON_FILES ${CMAKE_CURRENT_BINARY_DIR}/py_gen)
file(MAKE_DIRECTORY ${LIBQASM_GENERATED_PYTHON_FILES})

# Address sanitizer
if(ASAN_ENABLED)
    if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug")
        string(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
        message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n")

        # /MTd is needed to link clang_rt.asan-i386.lib statically.
        # Otherwise the path to clang_rt.asan-i386.dll should be provided.
        add_compile_options(/fsanitize=address /MTd)
    elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
        add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
        add_link_options(-fsanitize=address,undefined)
    endif()
endif()

# emscripten
if(LIBQASM_BUILD_EMSCRIPTEN)
    add_compile_options(-fwasm-exceptions -Os -sSTRICT)

    # --no-entry is needed by -sSTRICT
    add_link_options(-fwasm-exceptions -Os --no-entry -sENVIRONMENT=web -sEXPORT_ES6=1 -sFILESYSTEM=0 -sMODULARIZE=1 -sSTRICT)
endif()

# Jump to where the new API and the core of libqasm lives.
add_subdirectory(src)

# Add the test directory.
if(LIBQASM_BUILD_TESTS)
    enable_testing()
    include(CTest)
    include(GoogleTest)
    set(CMAKE_CTEST_ARGUMENTS "--output-on-failure")
    add_subdirectory(test)
endif()

# Include the tests directory if requested.
if(LIBQASM_BUILD_PYTHON)
    add_subdirectory(python)
endif()

# Add the emscripten directory.
if(LIBQASM_BUILD_EMSCRIPTEN)
    add_subdirectory(emscripten)
endif()

endif()  # NOT TARGET cqasm
