# ============================================================================ #
# Copyright (c) 2022 - 2026 NVIDIA Corporation & Affiliates.                   #
# All rights reserved.                                                         #
#                                                                              #
# This source code and the accompanying materials are made available under     #
# the terms of the Apache License 2.0 which accompanies this distribution.     #
# ============================================================================ #

include(HandleLLVMOptions)
set(LIBRARY_NAME cudaq-common)

set(COMMON_EXTRA_DEPS "")
set(COMMON_RUNTIME_SRC
  CodeGenConfig.cpp
  cudaq_json.cpp
  CustomOp.cpp
  DeviceCodeRegistry.cpp
  Environment.cpp
  ExecutionContext.cpp
  Executor.cpp
  ExtraPayloadProvider.cpp
  Future.cpp
  NoiseModel.cpp
  RecordLogParser.cpp
  Resources.cpp
  RuntimeTarget.cpp
  SampleResult.cpp
  ServerHelper.cpp
  Trace.cpp
  CompiledModule.cpp
  KernelArgs.cpp
  "${CMAKE_BINARY_DIR}/runtime/common/Version.cpp"
)

# Create the cudaq-common library
add_library(${LIBRARY_NAME} SHARED ${COMMON_RUNTIME_SRC})

# Add into runtime_libs property
set_property(GLOBAL APPEND PROPERTY CUDAQ_RUNTIME_LIBS ${LIBRARY_NAME})

# Setup the includes
target_include_directories(${LIBRARY_NAME}
    PRIVATE .
        $<BUILD_INTERFACE:${LLVM_INCLUDE_DIRS}>
        ${CMAKE_SOURCE_DIR}/tpls/eigen
        ${CMAKE_SOURCE_DIR}/runtime
	${CMAKE_SOURCE_DIR}/include
)

target_link_libraries(${LIBRARY_NAME}
  PUBLIC
    cudaq-operator
    CUDAQTargetConfig
  PRIVATE
    cudaq-logger
    fmt::fmt-header-only
)

# Bug in GCC 12 leads to spurious warnings (-Wrestrict)
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105329
# Scope to CXX-language compiles via a generator expression so the flag
# does NOT propagate through cmake's PUBLIC interface options into nvcc
# command lines for consumer CUDA targets. nvcc forwards host options to
# its own host compiler, which can be a different gcc than CMAKE_CXX_COMPILER
# (e.g. CMAKE_CXX_COMPILER=gcc-12 but CMAKE_CUDA_HOST_COMPILER=gcc-13, where
# gcc-13 has removed --param=evrp-mode= and would error on it).
if (CMAKE_COMPILER_IS_GNUCXX
  AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12.0.0
  AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0.0)
  target_compile_options(${LIBRARY_NAME} PUBLIC $<$<COMPILE_LANGUAGE:CXX>:--param=evrp-mode=legacy>)
endif()

# We can only build the RestClient support if we have OpenSSL
if(OPENSSL_FOUND)
  message(STATUS "OpenSSL Found, building REST Client.")

  target_sources(${LIBRARY_NAME} PRIVATE RestClient.cpp)
  # --start-group is a GNU ld flag for circular dependencies; Apple's ld doesn't support it
  if(APPLE)
    target_link_libraries(${LIBRARY_NAME} PRIVATE cpr::cpr ZLIB::ZLIB)
  else()
    target_link_libraries(${LIBRARY_NAME} PRIVATE cpr::cpr -Wl,--start-group ZLIB::ZLIB ${CMAKE_DL_LIBS})
  endif()
  target_compile_definitions(${LIBRARY_NAME} PRIVATE -DCUDAQ_RESTCLIENT_AVAILABLE)
endif()


# Add a flag to indicate this is a debug build
string(TOUPPER "${CMAKE_BUILD_TYPE}" CUDAQ_UPPERCASE_CMAKE_BUILD_TYPE)
if (CUDAQ_UPPERCASE_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
  target_compile_definitions(${LIBRARY_NAME} PUBLIC CUDAQ_DEBUG)
endif()

# Install the target
install(TARGETS ${LIBRARY_NAME}
        EXPORT cudaq-common-targets
        DESTINATION lib
        COMPONENT Runtime)
install(EXPORT cudaq-common-targets
        FILE CUDAQCommonTargets.cmake
        NAMESPACE cudaq::
        DESTINATION lib/cmake/cudaq
        COMPONENT Development)
if(EXISTS "$ENV{CURL_INSTALL_PREFIX}/cacert.pem")
  # Copy to build directory so that developers can run from the build directory
  file(COPY "$ENV{CURL_INSTALL_PREFIX}/cacert.pem" DESTINATION "${CMAKE_BINARY_DIR}")
  # Also include it as an install target
  install(FILES "$ENV{CURL_INSTALL_PREFIX}/cacert.pem"
          DESTINATION .
          COMPONENT Runtime)
endif()
