# CMake config file for building simx
# Author: Sunil Thulasidasan

project(simx)
set(TARGET_NAME "core")
set(TARGET_MODULE "core")
cmake_minimum_required(VERSION 2.6)
enable_language(CXX)

# if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)
#   #release comes with -O3 by default
#   set(CMAKE_BUILD_TYPE None CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
# endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CXX_FLAGS)

include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-fpermissive" HAVE_FPERMISSIVE)
if(NOT HAVE_FPERMISSIVE)
  message(FATAL_ERROR "flag '-fpermissive' does not work")
endif(NOT HAVE_FPERMISSIVE)
#set(CMAKE_CXX_FLAGS "-g -fpermissive" CACHE STRING "" FORCE)

#set(CMAKE_BUILD_TYPE Release)
#set(CMAKE_CXX_FLAGS "-O2 -fpermissive")
#set(CMAKE_CXX_FLAGS "-g -fpermissive")

#for MPI
if(SIMX_USE_MPI)
    find_package(MPI REQUIRED)
    if (MPI_FOUND)
	include_directories(${MPI_INCLUDE_PATH} ${MPI_CXX_INCLUDE_PATH})
	ADD_DEFINITIONS("-DHAVE_MPI_H")
    else()
	message(FATAL_ERROR "MPI not found. Install MPI or build without MPI (-DSIMX_USE_MPI=0)")
    endif()
else()
    #compiling without MPI, make sure we're using SSF
    if(NOT SIMX_USE_PRIME)
	message(FATAL_ERROR "non-MPI build must use SSF. Rebuild with SSF enabled (-DSIMX_USE_PRIME=1)")
    endif()
endif()

# for boost
set(Boost_USE_STATIC_LIBS  OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost COMPONENTS
		   python
		   REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
ADD_DEFINITIONS( "-DHAS_BOOST" )
link_directories(${Boost_LIBRARY_DIRS})


# for python
find_package(PythonInterp 2 REQUIRED)
find_package(PythonLibs 2 REQUIRED)
include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIR} ${PYTHON_INCLUDE_PATH})
link_directories(${PYTHON_LIBRARY_DIRS})

# for simx sources
file(GLOB_RECURSE SIMX_SOURCES src/simx/*.C)
file(GLOB_RECURSE NOT_SIMX_SOURCES src/simx/main*.C)
list(REMOVE_ITEM SIMX_SOURCES ${NOT_SIMX_SOURCES})
set(ALL_SOURCES "")
# simx headers
file(GLOB_RECURSE ALL_HEADERS src/simx/*.h)

# for SSF
if (SIMX_USE_PRIME)
  ADD_DEFINITIONS("-DSIMX_USE_PRIME")
  add_subdirectory(src/minissf)
  file(GLOB_RECURSE SSF_HEADERS src/minissf/*.h)
  list(APPEND ALL_HEADERS ${SSF_HEADERS})
  include_directories("${CMAKE_SOURCE_DIR}/src/minissf")
  include_directories("${CMAKE_SOURCE_DIR}/src/minissf/metis")
  # below include to make sure ssf_config.h is visible
  include_directories("${CMAKE_BINARY_DIR}/src/minissf")
  #link_directories("${CMAKE_BINARY_DIR}/minissf")
  #link_directories("${CMAKE_BINARY_DIR}/minissf/metis")
  # add autogenerated ssf_config header to this
  list(APPEND ALL_HEADERS "${CMAKE_BINARY_DIR}/src/minissf/ssf_config.h")
endif()
 
# all sources
list(APPEND ALL_SOURCES ${SIMX_SOURCES})


include_directories(${CMAKE_SOURCE_DIR} src src/simx) 
#					${MPI_INCLUDE_PATH}
#					${Boost_INCLUDE_DIRS}
#					${PYTHON_INCLUDE_DIR})


# message(STATUS "ALL_SOURCES = ${ALL_SOURCES}")

add_library(${TARGET_NAME} SHARED
		    ${ALL_SOURCES})

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/simx")
set_target_properties(${TARGET_NAME} PROPERTIES 
    PREFIX "" 
    SUFFIX ".so")
  
#LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/simx )
    



list(APPEND SIMX_LINK_LIBRARIES ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
if(SIMX_USE_MPI)
    list(APPEND SIMX_LINK_LIBRARIES ${MPI_CXX_LIBRARIES} ${MPI_LIBRARIES})
endif()

# target_link_libraries(${TARGET_NAME}
#         ${Boost_LIBRARIES}
# 	${BOOST_PYTHON_LIBRARY}
#         ${PYTHON_LIBRARIES}
# 	${MPI_CXX_LIBRARIES} ${MPI_LIBRARIES})

target_link_libraries(${TARGET_NAME} ${SIMX_LINK_LIBRARIES})


#	ssf metis)

#add_library(simx_static ${SIMX_SOURCES} src/simx/Global/main_MPI.C)

#######################
# Helloworld stuff. 
#######################
# include_directories(examples/HelloWorld/cpp)
# if (SIMX_USE_PRIME)
#   file(GLOB_RECURSE HELLOWORLD_SOURCES examples/HelloWorld/*.C src/simx/Global/main_dassf.C) 
# else()
#   file(GLOB_RECURSE HELLOWORLD_SOURCES examples/HelloWorld/*.C src/simx/Global/main_MPI.C)
# endif()
# add_executable(HelloWorld ${HELLOWORLD_SOURCES})
# target_link_libraries(HelloWorld ${TARGET_NAME})

## end Helloworld stuff

#########################
# Write to config.py
#########################

file(WRITE config.py "#Autogenerated via CMake

")


file(APPEND config.py "from setuptools import Extension
from setuptools.extension import Library
import os.path as op
from glob import glob

")

#flags
file(APPEND config.py "
CXX_FLAGS = '${CMAKE_CXX_FLAGS}'.split()

")

#compiler definitions
file(APPEND config.py "CXX_DEFINES = [")
get_property(cxx_defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY COMPILE_DEFINITIONS )
foreach(define ${cxx_defines})
  file(APPEND config.py "\"-D${define}\",")
endforeach()
file(APPEND config.py "]

")

#combine the flag definition list with compiler defines.
file(APPEND config.py "CXX_FLAGS += CXX_DEFINES

")

#include directories
file(APPEND config.py "include_dirs = [")
get_property(include_dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${include_dirs})
  file(APPEND config.py "\"${dir}\",")
endforeach()
file(APPEND config.py "]

")

#library directories
file(APPEND config.py "library_dirs = [")
get_property(lib_dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY LINK_DIRECTORIES)
foreach(dir ${lib_dirs})
  file(APPEND config.py "\"${dir}\",")
endforeach()
file(APPEND config.py "]

")

#link libraties
file(APPEND config.py "libraries = [")
foreach(lib ${SIMX_LINK_LIBRARIES})
  file(APPEND config.py "\"${lib}\",")
endforeach()
file(APPEND config.py "]

")


#more library directories, but  remove duplicate entries
file(APPEND config.py "library_dirs = list(set(library_dirs+map(op.dirname,libraries)))

")

# Remove directory, leading "lib" and trailing ".so" from the
# library names
file(APPEND config.py "
    
def revise_lib(lib):
    path, lib = op.split(op.normpath(lib))
    if not path=='':
        x = lib.rfind('.')
        if x >= 0: lib = lib[:x]
        if lib[:3]=='lib' : lib = lib[3:]
    return lib
    
libraries = map(revise_lib, libraries)

")




#write source list to config.py
file(APPEND config.py "all_sources = [")
foreach(src_file ${ALL_SOURCES})
  file(APPEND config.py "\"${src_file}\",")
endforeach()
file(APPEND config.py "]

")


# setup.py needs relative paths. The above file list contains absolute paths
# since that's the way of CMake. So, embed code in config.py for converting absolute
# paths to relative paths.
file(APPEND config.py "all_sources = map(op.relpath,all_sources)

")


#write header list to config.py
file(APPEND config.py "all_headers = [")
foreach(hdr_file ${ALL_HEADERS})
  file(APPEND config.py "\"${hdr_file}\",")
endforeach()
file(APPEND config.py "]

")

# setup.py needs relative paths. The above file list contains absolute paths
# since that's the way of CMake. So, embed code in config.py for converting absolute
# paths to relative paths.
file(APPEND config.py "all_headers = map(op.relpath,all_headers)

")



#create entry for extension
file(APPEND config.py "${TARGET_NAME}_ext = Extension('simx.${TARGET_MODULE}.${TARGET_NAME}',
sources = all_sources,
include_dirs = include_dirs,
library_dirs = library_dirs,
libraries = libraries,
depends = all_headers +['${CMAKE_BINARY_DIR}/CMakeCache.txt'],
extra_compile_args = CXX_FLAGS)

")

file(APPEND config.py "extension_list = [${TARGET_NAME}_ext]
")
