
function(libkernel_generate_bitcode_library)
  set(options)
  set(one_value_keywords OUTPUT TRIPLE SOURCE)
  set(multi_value_keywords ADDITIONAL_ARGS)
  cmake_parse_arguments(GENERATE_BITCODE_LIBRARY
    "${options}"
    "${one_value_keywords}"
    "${multi_value_keywords}"
    ${ARGN}
  )

  set(output ${GENERATE_BITCODE_LIBRARY_OUTPUT})
  set(source ${GENERATE_BITCODE_LIBRARY_SOURCE})
  set(triple ${GENERATE_BITCODE_LIBRARY_TRIPLE})
  set(additional ${GENERATE_BITCODE_LIBRARY_ADDITIONAL_ARGS})

  set(target_output_file ${output})
  if(ACPP_LLVM_COMPONENT)
    set(target_depends clang)
  endif()
  if(WIN32)
    set(platform_specific -DWIN32_LEAN_AND_MEAN -DNOMINMAX -D_USE_MATH_DEFINES)
  elseif(APPLE)
    # make overriding easier
    if(CMAKE_SYSROOT)
      set(platform_specific -isysroot ${CMAKE_SYSROOT})
    else()
      set(platform_specific -isysroot ${CMAKE_OSX_SYSROOT})
    endif()
  endif()

  add_custom_command(
      OUTPUT ${target_output_file}
      COMMAND ${CLANG_EXECUTABLE_PATH} -target ${triple} -fno-exceptions -fno-rtti -O3 -emit-llvm -std=c++17 -DHIPSYCL_SSCP_LIBKERNEL_LIBRARY
                    -I ${HIPSYCL_SOURCE_DIR}/include ${additional} ${platform_specific} -o ${target_output_file} -c ${CMAKE_CURRENT_SOURCE_DIR}/${source}
      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${source} ${target_depends}
      VERBATIM)

  install(FILES ${target_output_file} DESTINATION lib/hipSYCL/bitcode)
endfunction()

function(libkernel_generate_bitcode_target)
  set(options)
  set(one_value_keywords TARGETNAME TRIPLE)
  set(multi_value_keywords SOURCES ADDITIONAL_ARGS)

  cmake_parse_arguments(GENERATE_BITCODE_TARGET
    "${options}"
    "${one_value_keywords}"
    "${multi_value_keywords}"
    ${ARGN}
  )

  set(target ${GENERATE_BITCODE_TARGET_TARGETNAME})
  set(sources ${GENERATE_BITCODE_TARGET_SOURCES})
  set(triple ${GENERATE_BITCODE_TARGET_TRIPLE})
  set(additional ${GENERATE_BITCODE_TARGET_ADDITIONAL_ARGS})

  set(output_files )
  file(MAKE_DIRECTORY ${ADAPTIVE_CPP_BINARY_DIR}/lib/hipSYCL/bitcode)
  foreach(source ${sources})
    get_filename_component(target_source ${source} NAME_WE)
    set(output_file ${ADAPTIVE_CPP_BINARY_DIR}/lib/hipSYCL/bitcode/libkernel-sscp-${target}-${target_source}.bc)
    list(APPEND output_files ${output_file})
    
    libkernel_generate_bitcode_library(
      OUTPUT ${output_file}
      TRIPLE ${triple} 
      SOURCE ${source}
      ADDITIONAL_ARGS ${additional})
  endforeach()

  if(ACPP_LLVM_COMPONENT)
    set(target_depends llvm-link)
  endif()

  set(linked_output ${ADAPTIVE_CPP_BINARY_DIR}/lib/hipSYCL/bitcode/libkernel-sscp-${target}-full.bc)
  add_custom_command(
    OUTPUT ${linked_output}
    COMMAND ${LLVM_TOOLS_BINARY_DIR}/llvm-link -o=${linked_output} ${output_files}
    DEPENDS llvm-link clang ${output_files} ${target_depends}
  )

  install(FILES ${linked_output} DESTINATION lib/hipSYCL/bitcode)

  add_custom_target(libkernel-sscp-${target} ALL
    WORKING_DIRECTORY ${ADAPTIVE_CPP_BINARY_DIR}/lib/hipSYCL/bitcode
    DEPENDS ${linked_output}
  )

endfunction()

add_subdirectory(spirv)
add_subdirectory(ptx)
add_subdirectory(amdgpu)
add_subdirectory(host)
