# Build for the Memory Profiler runtime support library.

set(MEMPROF_SOURCES
  memprof_allocator.cpp
  memprof_descriptions.cpp
  memprof_flags.cpp
  memprof_interceptors.cpp
  memprof_interceptors_memintrinsics.cpp
  memprof_linux.cpp
  memprof_malloc_linux.cpp
  memprof_mibmap.cpp
  memprof_posix.cpp
  memprof_rawprofile.cpp
  memprof_rtl.cpp
  memprof_shadow_setup.cpp
  memprof_stack.cpp
  memprof_stats.cpp
  memprof_thread.cpp
  )

set(MEMPROF_CXX_SOURCES
  memprof_new_delete.cpp
  )

set(MEMPROF_PREINIT_SOURCES
  memprof_preinit.cpp
  )

SET(MEMPROF_HEADERS
  memprof_allocator.h
  memprof_descriptions.h
  memprof_flags.h
  memprof_flags.inc
  memprof_init_version.h
  memprof_interceptors.h
  memprof_interceptors_memintrinsics.h
  memprof_interface_internal.h
  memprof_internal.h
  memprof_mapping.h
  memprof_meminfoblock.h
  memprof_mibmap.h
  memprof_rawprofile.h
  memprof_stack.h
  memprof_stats.h
  memprof_thread.h
  )

include_directories(..)

set(MEMPROF_CFLAGS ${SANITIZER_COMMON_CFLAGS})
set(MEMPROF_COMMON_DEFINITIONS "")

# Too many existing bugs, needs cleanup.
append_list_if(COMPILER_RT_HAS_WNO_FORMAT -Wno-format MEMPROF_CFLAGS)

append_rtti_flag(OFF MEMPROF_CFLAGS)

set(MEMPROF_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})

set(MEMPROF_DYNAMIC_DEFINITIONS
  ${MEMPROF_COMMON_DEFINITIONS} MEMPROF_DYNAMIC=1)

set(MEMPROF_DYNAMIC_CFLAGS ${MEMPROF_CFLAGS})
append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
  -ftls-model=initial-exec MEMPROF_DYNAMIC_CFLAGS)

set(MEMPROF_DYNAMIC_LIBS ${SANITIZER_CXX_ABI_LIBRARIES} ${SANITIZER_COMMON_LINK_LIBS})

append_list_if(COMPILER_RT_HAS_LIBDL dl MEMPROF_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBRT rt MEMPROF_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBM m MEMPROF_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread MEMPROF_DYNAMIC_LIBS)
append_list_if(COMPILER_RT_HAS_LIBLOG log MEMPROF_DYNAMIC_LIBS)

# Compile MemProf sources into an object library.

add_compiler_rt_object_libraries(RTMemprof_dynamic
  OS ${SANITIZER_COMMON_SUPPORTED_OS}
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  SOURCES ${MEMPROF_SOURCES} ${MEMPROF_CXX_SOURCES}
  ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
  CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
  DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
  DEPS ${MEMPROF_DEPS})

add_compiler_rt_object_libraries(RTMemprof
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  SOURCES ${MEMPROF_SOURCES}
  ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
  CFLAGS ${MEMPROF_CFLAGS}
  DEFS ${MEMPROF_COMMON_DEFINITIONS}
  DEPS ${MEMPROF_DEPS})
add_compiler_rt_object_libraries(RTMemprof_cxx
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  SOURCES ${MEMPROF_CXX_SOURCES}
  ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
  CFLAGS ${MEMPROF_CFLAGS}
  DEFS ${MEMPROF_COMMON_DEFINITIONS}
  DEPS ${MEMPROF_DEPS})
add_compiler_rt_object_libraries(RTMemprof_preinit
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  SOURCES ${MEMPROF_PREINIT_SOURCES}
  ADDITIONAL_HEADERS ${MEMPROF_HEADERS}
  CFLAGS ${MEMPROF_CFLAGS}
  DEFS ${MEMPROF_COMMON_DEFINITIONS}
  DEPS ${MEMPROF_DEPS})

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
add_compiler_rt_object_libraries(RTMemprof_dynamic_version_script_dummy
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
  CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
  DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
  DEPS ${MEMPROF_DEPS})

# Build MemProf runtimes shipped with Clang.
add_compiler_rt_component(memprof)

# Build separate libraries for each target.

set(MEMPROF_COMMON_RUNTIME_OBJECT_LIBS
  RTInterception
  RTSanitizerCommon
  RTSanitizerCommonLibc
  RTSanitizerCommonCoverage
  RTSanitizerCommonSymbolizer)

add_compiler_rt_runtime(clang_rt.memprof
  STATIC
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  OBJECT_LIBS RTMemprof_preinit
              RTMemprof
              ${MEMPROF_COMMON_RUNTIME_OBJECT_LIBS}
  CFLAGS ${MEMPROF_CFLAGS}
  DEFS ${MEMPROF_COMMON_DEFINITIONS}
  PARENT_TARGET memprof)

add_compiler_rt_runtime(clang_rt.memprof_cxx
  STATIC
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  OBJECT_LIBS RTMemprof_cxx
  CFLAGS ${MEMPROF_CFLAGS}
  DEFS ${MEMPROF_COMMON_DEFINITIONS}
  PARENT_TARGET memprof)

add_compiler_rt_runtime(clang_rt.memprof-preinit
  STATIC
  ARCHS ${MEMPROF_SUPPORTED_ARCH}
  OBJECT_LIBS RTMemprof_preinit
  CFLAGS ${MEMPROF_CFLAGS}
  DEFS ${MEMPROF_COMMON_DEFINITIONS}
  PARENT_TARGET memprof)

foreach(arch ${MEMPROF_SUPPORTED_ARCH})
  if (UNIX)
    add_sanitizer_rt_version_list(clang_rt.memprof-dynamic-${arch}
                                  LIBS clang_rt.memprof-${arch} clang_rt.memprof_cxx-${arch}
                                  EXTRA memprof.syms.extra)
    set(VERSION_SCRIPT_FLAG
         -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.memprof-dynamic-${arch}.vers)
    set_property(SOURCE
      ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp
      APPEND PROPERTY
      OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.memprof-dynamic-${arch}.vers)
  else()
    set(VERSION_SCRIPT_FLAG)
  endif()

  set(MEMPROF_DYNAMIC_WEAK_INTERCEPTION)

  add_compiler_rt_runtime(clang_rt.memprof
    SHARED
    ARCHS ${arch}
    OBJECT_LIBS ${MEMPROF_COMMON_RUNTIME_OBJECT_LIBS}
            RTMemprof_dynamic
            # The only purpose of RTMemprof_dynamic_version_script_dummy is to
            # carry a dependency of the shared runtime on the version script.
            # Replacing it with a straightforward
            # add_dependencies(clang_rt.memprof-dynamic-${arch} clang_rt.memprof-dynamic-${arch}-version-list)
            # generates an order-only dependency in ninja.
            RTMemprof_dynamic_version_script_dummy
            ${MEMPROF_DYNAMIC_WEAK_INTERCEPTION}
    CFLAGS ${MEMPROF_DYNAMIC_CFLAGS}
    LINK_FLAGS ${MEMPROF_DYNAMIC_LINK_FLAGS}
              ${VERSION_SCRIPT_FLAG}
    LINK_LIBS ${MEMPROF_DYNAMIC_LIBS}
    DEFS ${MEMPROF_DYNAMIC_DEFINITIONS}
    PARENT_TARGET memprof)

  if (SANITIZER_USE_SYMBOLS)
    add_sanitizer_rt_symbols(clang_rt.memprof_cxx
      ARCHS ${arch})
    add_dependencies(memprof clang_rt.memprof_cxx-${arch}-symbols)
    add_sanitizer_rt_symbols(clang_rt.memprof
      ARCHS ${arch}
      EXTRA memprof.syms.extra)
    add_dependencies(memprof clang_rt.memprof-${arch}-symbols)
  endif()
endforeach()


if(COMPILER_RT_INCLUDE_TESTS)
  add_subdirectory(tests)
endif()
