# CMakeLists.txt for MRC Image 2010

# Test cmake / make install command:
# cmake -H. -Bbuild
# make -C build && make install -C build
# -H = source directory, -B = build directory

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
enable_language(Fortran)
project(ccpem)

# Set all variables needed through whole file
# Add static flag to all.  Exception on Mac systems as statically linked libs are not supported by OS X
# See:
#    https://developer.apple.com/library/mac/qa/qa1118/_index.html
# For testing set shared to true
# set(BUILD_SHARED "${BUILD_SHARED}")
set(BUILD_SHARED TRUE)

#### Set install directory, if not set install locally
#set(install_dir "${install_dir}")
#if(DEFINED ${install_dir})
#  set(CMAKE_INSTALL_PREFIX "${install_dir}")
#else()
#  set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/install)
#endif()
#message("\n\nInstall directory : "${CMAKE_INSTALL_PREFIX})

if(BUILD_SHARED)
    set(LIBRARY_TYPE SHARED)
else()
    set(LIBRARY_TYPE STATIC)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
endif()

if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
  # gfortran
  set (CMAKE_Fortran_FLAGS "-w  -ffixed-line-length-132")
  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGFORTRAN")
elseif (CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
  # ifort untested)
  set (CMAKE_Fortran_FLAGS "-extend-source 132")
  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DIFORT")
else ()
  set (CMAKE_Fortran_FLAGS "-O0")
endif ()

# Set vars to help with cross-compilation - to make all libraries static
# add_library to create shared libraries if on (unless library explicitly added as static)
if(NOT BUILD_SHARED)
  set(BUILD_SHARED_LIBS ON)
  set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .a)
endif()

set(imliblibs ${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(BUILD_BINARY_DIR ${PROJECT_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILD_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILD_BINARY_DIR}/lib)
set(CMAKE_Fortran_MODULE_DIRECTORY ${BUILD_BINARY_DIR}/src/image2010/modules)

set(MRCsourcedir ${CMAKE_CURRENT_SOURCE_DIR})
set(MRCexternaldirrel share/MRCImageLibraries)
set(MRCexternaldir ${BUILD_BINARY_DIR}/${MRCexternaldirrel})
set(mrcimagesrc ${CMAKE_CURRENT_SOURCE_DIR}/source)
set(postscriptsrc ${CMAKE_CURRENT_SOURCE_DIR}/laser/postscript)
include_directories(${BUILD_BINARY_DIR}/lib)
#
# XXX TODO -> if x11 not found do not build sleuth / xmdisp
find_package(X11)
if(NOT X11_FOUND)
  message(FATAL_ERROR "Failed to find X11 which is required to build")
endif(NOT X11_FOUND)
include_directories(${X11_INCLUDE_DIR})

# Build MRC Image Libraries
message("Configuring MRC Image Libraries")

# XXX TODO Check fsplit, where is the .csh script?
message(STATUS "Configuring fsplit") # maybe we shouldn't actually bother with this!
add_executable(fsplit ${imliblibs}/fsplit.c)
install(TARGETS fsplit DESTINATION bin)
message(STATUS "Configuring imlib2010") # the csh script runs fsplit here, compiles the *.f files indivually, then repackages them into an archive; doesn't seem much advantage?
add_library(imlib2010 STATIC ${imliblibs}/imsubs2010.for)
install(TARGETS imlib2010 DESTINATION lib)
message(STATUS "Configuring genlib")

# m4 preprocessing of unix.m4 to unix.for
find_program(M4_EXECUTABLE m4 DOC "The M4 macro processor")
if(NOT M4_EXECUTABLE)
   message(SEND_ERROR "Failed to find the M4 macro processor")
else()
   message(STATUS "m4 preprocessor found")
endif()

if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
add_custom_command(
   OUTPUT ${imliblibs}/unix.for
   COMMAND m4 -D_gfort=1 ${imliblibs}/unix.m4 > ${imliblibs}/unix.for
   VERBATIM
)
elseif (CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
add_custom_command(
   OUTPUT ${imliblibs}/unix.for
   COMMAND m4 -D_ifct=8 ${imliblibs}/unix.m4 > ${imliblibs}/unix.for
   VERBATIM
)
else ()
add_custom_command(
   OUTPUT ${imliblibs}/unix.for
   COMMAND m4 -D_gfort=1 ${imliblibs}/unix.m4 > ${imliblibs}/unix.for
   VERBATIM
)
endif ()

# genlib
add_library(genlib STATIC ${imliblibs}/unix.for
                          ${imliblibs}/ccplib.for
                          ${imliblibs}/subs.for
                          ${imliblibs}/parser.for
                          ${imliblibs}/keyparse.for
                          ${imliblibs}/ccp4_array.c
                          ${imliblibs}/ccp4_diskio_f.c
                          ${imliblibs}/ccp4_general.c
                          ${imliblibs}/ccp4_general_f.c
                          ${imliblibs}/ccp4_parser.c
                          ${imliblibs}/ccp4_parser_f.c
                          ${imliblibs}/ccp4_program.c
                          ${imliblibs}/ccp4_unitcell.c
                          ${imliblibs}/cmtzlib.c
                          ${imliblibs}/cmtzlib_f.c
                          ${imliblibs}/csymlib.c
                          ${imliblibs}/csymlib_f.c
                          ${imliblibs}/cvecmat.c
                          ${imliblibs}/library_err.c
                          ${imliblibs}/library_file.c
                          ${imliblibs}/library_utils.c
                          ${imliblibs}/library_f.c
                          ${imliblibs}/subsc.c
                          )
install(TARGETS genlib DESTINATION lib)

# plot2klip
message(STATUS "Configuring plot2klib")
add_library(plot2klib STATIC ${imliblibs}/plot2k.c)
install(TARGETS plot2klib DESTINATION lib)

# misclib
message(STATUS "Configuring misclib")
add_library(misclib STATIC ${imliblibs}/lcflib.for ${imliblibs}/miscsubs.for ${imliblibs}/lkyasn.for)
install(TARGETS misclib DESTINATION lib)

# ifftlib
message(STATUS "Configuring ifftlib")
add_library(ifftlib STATIC ${imliblibs}/ifftsub.for)
install(TARGETS ifftlib DESTINATION lib)

message(STATUS "Finished configuring MRC Image Libraries")

##
# MRC Image binaries
##

message("Configuring MRC Image Programs")

# postscript
add_library(postscript STATIC ${postscriptsrc}/postscript.for)
install(TARGETS postscript DESTINATION lib)

# mergediff
add_executable(mrc_mergediff ${mrcimagesrc}/mergediff.for ${mrcimagesrc}/mergesubs.for)
install(TARGETS mrc_mergediff DESTINATION bin)

# byte_swap_map
# N.B. C not fortran
add_executable(mrc_byte_swap_map ${mrcimagesrc}/byte_swap_map.c)
install(TARGETS mrc_byte_swap_map DESTINATION bin)

# mrc_lasertone
# 
add_executable(mrc_lasertone ${postscriptsrc}/lasertone.for)
target_link_libraries(mrc_lasertone postscript imlib2010 genlib)
install(TARGETS mrc_lasertone DESTINATION bin)

# mrc fortran progs
set(MRC_fortran_progs allspacea autocorrl avrgamphs ccunbendk ctfapplyk ctffind2 ctffinda ctftilt ctfsearch divideq emtilt halfstat latlinek latlinprescal maketran masktrana mmboxa mmlatref mmtomklcf origtiltk pltiltk prepmklcf quadserchk scalimamp3d ttboxk ttmask ttrefine histok curvy2k surf light autoindexk avrgfdelf avrgintens backautok pickautok pickprofk syncfitp3 bandpass boxim boximage fftrans header image_convert imedit interpo interpo3d label mrc2tif padbox padcorcut remorig smooth taperedgek tif2mrc trmask trnout twofile hlxsearch hlxdump hlxfit hlxfitt hlxavg hlxfour hlxproj hlxsepdat hlxsepr hlxllout hlxsimul hlxdyad rfiltim rotav imrotran) 

set(MRC_fortran_progs_renamed "")
list(LENGTH MRC_fortran_progs nMRCprogs)
math(EXPR nMRCprogs ${nMRCprogs}-1)
foreach(i RANGE ${nMRCprogs})
  list(GET MRC_fortran_progs ${i} x)
  message(STATUS "Configuring mrc_${x}")
  list(APPEND MRC_fortran_progs_renamed "mrc_${x}")
  add_executable(mrc_${x} ${mrcimagesrc}/${x}.for)
  target_link_libraries(mrc_${x} imlib2010 misclib ifftlib genlib plot2klib)
  install(TARGETS mrc_${x} DESTINATION bin)
endforeach()

# ximdisp & sleuth
# disable for windows systems as dependant on x11
if(NOT WIN32)
  add_subdirectory(Ximdisp)
  add_subdirectory(sleuth)
endif()

##
# Flags for libraries and exes (taken from original MRC bash build scripts)
#  XXX TODO check below:
#  - n.b lots more compilations in the MRC g77 bld files have -fno-second-underscore than the gfortran - does this matter?
##
set_target_properties(genlib PROPERTIES CMAKE_C_FLAGS "-w")
set_target_properties(imlib2010 genlib ifftlib misclib ${MRC_fortran_progs_renamed} Ximagelib harwell Ximdisp sleuth PROPERTIES CMAKE_Fortran_FLAGS "-w -ffixed-line-length-132")
set_target_properties(mrc_histok mrc_curvy2k mrc_surf mrc_light mrc_hlxsearch mrc_hlxfit mrc_hlxfitt mrc_hlxavg mrc_hlxfour mrc_hlxproj mrc_hlxsepdat mrc_hlxsepr mrc_hlxllout mrc_hlxsimul mrc_hlxdyad PROPERTIES CMAKE_Fortran_FLAGS "-O")
set_target_properties(mrc_hlxdump mrc_hlxavg mrc_hlxsepr mrc_hlxllout mrc_taperedgek  Ximagelib PROPERTIES CMAKE_Fortran_FLAGS "-fno-second-underscore")


#  Add non-compiled files to the build / installation dirs
file(COPY ${MRCsourcedir}/com DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/com DESTINATION ${MRCexternaldirrel} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)

file(COPY ${MRCsourcedir}/doc DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc DESTINATION ${MRCexternaldirrel} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)

file(COPY ${MRCsourcedir}/laser DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE PATTERN "*.for" EXCLUDE) 
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/laser DESTINATION ${MRCexternaldirrel} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE PATTERN "*.for" EXCLUDE)

file(COPY ${MRCsourcedir}/local DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/local DESTINATION ${MRCexternaldirrel} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)

file(COPY ${MRCsourcedir}/FAQ DESTINATION ${MRCexternaldir}/doc USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/FAQ DESTINATION ${MRCexternaldirrel}/doc)

file(COPY ${MRCsourcedir}/index.html DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/index.html DESTINATION ${MRCexternaldirrel})

file(COPY ${MRCsourcedir}/laserlinks DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/laserlinks DESTINATION ${MRCexternaldirrel})

file(COPY ${MRCsourcedir}/lasertext.doc DESTINATION ${MRCexternaldir}/doc USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lasertext.doc DESTINATION ${MRCexternaldirrel}/doc)

file(COPY ${MRCsourcedir}/README DESTINATION ${MRCexternaldir} USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README DESTINATION ${MRCexternaldirrel})

# Can't copy and rename together, so copy to a temp folder, use RENAME to move, then delete the temp folder
file(COPY ${MRCsourcedir}/lib/README DESTINATION ${MRCexternaldir}/READMElib USE_SOURCE_PERMISSIONS PATTERN ".svn" EXCLUDE)
file(RENAME ${MRCexternaldir}/READMElib/README ${MRCexternaldir}/lib_README)
file(REMOVE_RECURSE ${MRCexternaldir}/READMElib)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/lib/README DESTINATION ${MRCexternaldirrel} RENAME "lib_README")

# Configure image.setup-csh.in
set(IMAGE_CSH_IN "${CMAKE_CURRENT_SOURCE_DIR}/com/image.setup-csh.in")
set(IMAGE_CSH "${CMAKE_INSTALL_PREFIX}/bin/image.setup-csh")
configure_file(${IMAGE_CSH_IN} ${IMAGE_CSH} @ONLY)
# Configure image.setup-sh.in
set(IMAGE_SH_IN "${CMAKE_CURRENT_SOURCE_DIR}/com/image.setup-sh.in")
set(IMAGE_SH "${CMAKE_INSTALL_PREFIX}/bin/image.setup-sh")
configure_file(${IMAGE_SH_IN} ${IMAGE_SH} @ONLY)
message(STATUS "image.setup-sh and image.setup-csh configured")


message("Finished configuring MRC Image 2010")
