project (dmmlib-library C)

set(DMMLIB_PUBLIC_INCLUDE_DIRS
  ${CMAKE_SOURCE_DIR}/include
  CACHE INTERNAL "dmmlib public include directories"
)

set(DMMLIB_PRIVATE_INCLUDE_DIRS
	${CMAKE_SOURCE_DIR}/private-include
	${CMAKE_BINARY_DIR}
)

if (WITH_SHARED_LIB)
  set(DMMLIB_SHARED_LIBRARY
    dmm_shared
    CACHE INTERNAL "dmmlib shared library"
)
endif (WITH_SHARED_LIB)

if (WITH_STATIC_LIB)
  set(DMMLIB_STATIC_LIBRARY
    dmm_static
    CACHE INTERNAL "dmmlib static library"
  )
endif (WITH_STATIC_LIB)

set(dmmlib_SRCS
  padding.c
  raw_block.c
  )

if(NOT WITH_SYSTEM_CALLS STREQUAL "none")
  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    malloc.c
    free.c
    calloc.c
    initialize.c
    release_memory.c
    other.c
    )
endif(NOT WITH_SYSTEM_CALLS STREQUAL "none")

if(RAW_BLOCKS_TYPE STREQUAL "freelist")

  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    freelist/block_header_funcs.c
    freelist/malloc.c
    freelist/free.c
    freelist/initialize.c
    )

  if(FITTING_POLICY STREQUAL "best")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/fitting/best.c
      )
  elseif(FITTING_POLICY STREQUAL "exact")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/fitting/exact.c
      )
  elseif(FITTING_POLICY STREQUAL "first")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/fitting/first.c
      )
  elseif(FITTING_POLICY STREQUAL "good")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/fitting/good.c
      )
  endif(FITTING_POLICY STREQUAL "best")

  if(ORDERING_POLICY STREQUAL "address")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/ordering/address.c
      )
  elseif(ORDERING_POLICY STREQUAL "fifo")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/ordering/fifo.c
      )
  elseif(ORDERING_POLICY STREQUAL "lifo")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/ordering/lifo.c
      )
  elseif(ORDERING_POLICY STREQUAL "size")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/ordering/size.c
      )
  endif(ORDERING_POLICY STREQUAL "address")

  if(COALESCING_FIXED OR COALESCING_VARIABLE)
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/coalesce.c
      )
  endif(COALESCING_FIXED OR COALESCING_VARIABLE)

  if(SPLITTING_FIXED OR SPLITTING_VARIABLE)
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/split.c
      )
  endif(SPLITTING_FIXED OR SPLITTING_VARIABLE)

  if(WITH_REALLOC)
    set(dmmlib_SRCS ${dmmlib_SRCS} freelist/realloc.c)
  endif(WITH_REALLOC)

  if(WITH_DEBUG)
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/debug.c
      )
  endif(WITH_DEBUG)

elseif(RAW_BLOCKS_TYPE STREQUAL "bitmap")

  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    bitmap/other.c
    bitmap/malloc.c
    bitmap/free.c
    )

  if(WITH_REALLOC)
    set(dmmlib_SRCS ${dmmlib_SRCS} bitmap/realloc.c)
  endif(WITH_REALLOC)

  if(WITH_DEBUG)
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      bitmap/debug.c
      )
  endif(WITH_DEBUG)

endif(RAW_BLOCKS_TYPE STREQUAL "freelist")

if(WITH_SYSTEM_CALLS STREQUAL "none")
  set(NO_SYSTEM_CALLS ON)
elseif(WITH_SYSTEM_CALLS STREQUAL "sbrk")
  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    request_memory_sbrk.c
  )
elseif(WITH_SYSTEM_CALLS STREQUAL "mmap")
  if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      request_memory_mmap_linux.c
    )
  elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      request_memory_mmap_osx.c
    )
  endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")

endif(WITH_SYSTEM_CALLS STREQUAL "none")

if(WITH_DEBUG)
  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    debug.c
  )
endif(WITH_DEBUG)

if(WITH_KNOBS)
  set(dmmlib_SRCS ${dmmlib_SRCS} knobs.c)
endif(WITH_KNOBS)

if(NOT STATS STREQUAL "none")
  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    statistics.c
  )
endif(NOT STATS STREQUAL "none")

if(WITH_REALLOC)
  set(DMMLIB_PRIVATE_INCLUDE_DIRS
    ${DMMLIB_PRIVATE_INCLUDE_DIRS}
    ${CMAKE_SOURCE_DIR}/contrib/memcpy/include
  )

  set_source_files_properties(${CMAKE_SOURCE_DIR}/contrib/memcpy/src/memcpy.c
    COMPILE_FLAGS "-Wno-conversion")

  # memcpy needs a define flag on 64-bit architectures
  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    set_source_files_properties(${CMAKE_SOURCE_DIR}/contrib/memcpy/src/memcpy.c
      COMPILE_FLAGS "-Wno-conversion -DMEMCPY_64BIT")
  endif(CMAKE_SIZEOF_VOID_P EQUAL 8)

  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    realloc.c
    ${CMAKE_SOURCE_DIR}/contrib/memcpy/src/memcpy.c
  )

endif(WITH_REALLOC)

if(WITH_CALLOC)
  set(dmmlib_SRCS ${dmmlib_SRCS} calloc.c)
endif(WITH_CALLOC)

if(WITH_MEMALIGN)
  set(dmmlib_SRCS
    ${dmmlib_SRCS}
    memalign.c
  )

  if(RAW_BLOCKS_TYPE STREQUAL "freelist")
    set(dmmlib_SRCS
      ${dmmlib_SRCS}
      freelist/memalign.c
      )
  endif(RAW_BLOCKS_TYPE STREQUAL "freelist")
endif(WITH_MEMALIGN)

if(PARSE_ENV)
  set(dmmlib_SRCS ${dmmlib_SRCS} parse_env.c)
endif(PARSE_ENV)

include_directories(
  ${DMMLIB_PUBLIC_INCLUDE_DIRS}
  ${DMMLIB_PRIVATE_INCLUDE_DIRS}
)

if (WITH_SHARED_LIB)
  add_library(${DMMLIB_SHARED_LIBRARY} SHARED ${dmmlib_SRCS})

  set_target_properties(
    ${DMMLIB_SHARED_LIBRARY}
      PROPERTIES
        POSITION_INDEPENDENT_CODE
          ON
        OUTPUT_NAME
          dmm
  )

  install(
    TARGETS
      ${DMMLIB_SHARED_LIBRARY}
    DESTINATION
      ${LIB_INSTALL_DIR}
    COMPONENT
      libraries
  )
endif (WITH_SHARED_LIB)

if (WITH_STATIC_LIB)
  add_library(${DMMLIB_STATIC_LIBRARY} STATIC ${dmmlib_SRCS})

  set_target_properties(
    ${DMMLIB_STATIC_LIBRARY}
      PROPERTIES
        POSITION_INDEPENDENT_CODE
          ON
  )

  install(
    TARGETS
      ${DMMLIB_STATIC_LIBRARY}
    DESTINATION
      ${LIB_INSTALL_DIR}
    COMPONENT
      libraries
  )

endif (WITH_STATIC_LIB)

