# - Find tools needed for building RPM Packages
#   on Linux systems and defines macro that helps to
#   build source or binary RPM, the MACRO assumes
#   CMake 2.4.x which includes CPack support.
#   CPack is used to build tar.gz source tarball
#   which may be used by a custom user-made spec file.
#
# - Define RPMTools_ADD_RPM_TARGETS which defines
#   two (top-level) CUSTOM targets for building
#   source and binary RPMs
#
# Those CMake macros are provided by the TSP Developer Team
# https://savannah.nongnu.org/projects/tsp
#
# Modified by Werner to use the SoureDistribution variables and
# files instead of CPack stuff. Only minor changes.

IF (WIN32)  
  MESSAGE(STATUS "RPM tools not available on Win32 systems")
ENDIF(WIN32)

IF (UNIX)
  # Look for RPM builder executable
  FIND_PROGRAM(RPMTools_RPMBUILD_EXECUTABLE 
    NAMES rpmbuild
    PATHS "/usr/bin;/usr/lib/rpm"
    PATH_SUFFIXES bin
    DOC "The RPM builder tool")
  
  IF (RPMTools_RPMBUILD_EXECUTABLE)
    MESSAGE(STATUS "Looking for RPMTools... - found rpmuild is ${RPMTools_RPMBUILD_EXECUTABLE}")
    SET(RPMTools_RPMBUILD_FOUND "YES")
    GET_FILENAME_COMPONENT(RPMTools_BINARY_DIRS ${RPMTools_RPMBUILD_EXECUTABLE} PATH)
  ELSE (RPMTools_RPMBUILD_EXECUTABLE) 
    SET(RPMTools_RPMBUILD_FOUND "NO")
    MESSAGE(STATUS "Looking for RPMTools... - rpmbuild NOT FOUND")
  ENDIF (RPMTools_RPMBUILD_EXECUTABLE) 
  
  # Detect if CourceDistribution was initialized or not
  IF (NOT DEFINED "SRC_DIST_DIR") 
    MESSAGE(FATAL_ERROR "SourceDistribution was not initialized")
  ENDIF (NOT DEFINED "SRC_DIST_DIR")
  
  IF (RPMTools_RPMBUILD_FOUND)
    SET(RPMTools_FOUND TRUE)    
    #
    # - first arg  (ARGV0) is RPM name
    # - second arg (ARGV1) is the RPM spec file path [optional]
    # - third arg  (ARGV2) is the RPM ROOT DIRECTORY used to build RPMs [optional]
    #
    MACRO(RPMTools_ADD_RPM_TARGETS RPMNAME)

      #
      # If no spec file is provided create a minimal one
      #
      IF ("${ARGV1}" STREQUAL "")
        SET(SPECFILE_PATH "${CMAKE_BINARY_DIR}/${RPMNAME}.spec")
      ELSE ("${ARGV1}" STREQUAL "")
        SET(SPECFILE_PATH "${ARGV1}")
      ENDIF("${ARGV1}" STREQUAL "")
      
      # Verify whether if RPM_ROOTDIR was provided or not
      IF("${ARGV2}" STREQUAL "") 
        SET(RPM_ROOTDIR ${CMAKE_BINARY_DIR}/RPM)
      ELSE ("${ARGV2}" STREQUAL "")
        SET(RPM_ROOTDIR "${ARGV2}") 
      ENDIF("${ARGV2}" STREQUAL "")
      MESSAGE(STATUS "RPMTools:: Using RPM_ROOTDIR=${RPM_ROOTDIR}")

      # Prepare RPM build tree
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR})
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR}/tmp)
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR}/BUILD)
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR}/RPMS)
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR}/SOURCES)
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR}/SPECS)
      FILE(MAKE_DIRECTORY ${RPM_ROOTDIR}/SRPMS)

      #
      # We check whether if the provided spec file is
      # to be configure or not.
      # 
      IF ("${ARGV1}" STREQUAL "")
        SET(SPECFILE_PATH "${RPM_ROOTDIR}/SPECS/${RPMNAME}.spec")
        SET(SPECFILE_NAME "${RPMNAME}.spec")
        MESSAGE(STATUS "No Spec file given generate a minimal one --> ${RPM_ROOTDIR}/SPECS/${RPMNAME}.spec")
        FILE(WRITE ${RPM_ROOTDIR}/SPECS/${RPMNAME}.spec
      "# -*- rpm-spec -*-
Summary:        ${RPMNAME}
Name:           ${RPMNAME}
Version:        ${PACKAGE_VERSION}
Release:        1
License:        Unknown
Group:          Unknown
Source:         ${SRC_DIST_DIR}.tar.gz
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires:  cmake

%define prefix /opt/${RPMNAME}-%{version}
%define rpmprefix $RPM_BUILD_ROOT%{prefix}
%define srcdirname %{name}-%{version}-Source

%description
${RPMNAME} : No description for now

%prep
%setup -q -n %{srcdirname}

%build
cd ..
rm -rf build_tree
mkdir build_tree
cd build_tree
cmake -DCMAKE_INSTALL_PREFIX=%{rpmprefix} ../%{srcdirname}
make
  
%install 
cd ../build_tree
make install

%clean
rm -rf %{srcdirname}
rm -rf build_tree

%files
%defattr(-,root,root,-)
%dir %{prefix}
%{prefix}/*

%changelog
* Wed Feb 28 2007 Erk <eric.noulard@gmail.com>
  Generated by CMake UseRPMTools macros"
        )

      ELSE ("${ARGV1}" STREQUAL "")
        SET(SPECFILE_PATH "${ARGV1}")
    
        GET_FILENAME_COMPONENT(SPECFILE_EXT ${SPECFILE_PATH} EXT)      
        IF ("${SPECFILE_EXT}" STREQUAL ".spec")
        # This is a 'ready-to-use' spec file which does not need to be CONFIGURED
          GET_FILENAME_COMPONENT(SPECFILE_NAME ${SPECFILE_PATH} NAME)
          MESSAGE(STATUS "Simple copy spec file <${SPECFILE_PATH}> --> <${RPM_ROOTDIR}/SPECS/${SPECFILE_NAME}>")
          CONFIGURE_FILE(
            ${SPECFILE_PATH} 
            ${RPM_ROOTDIR}/SPECS/${SPECFILE_NAME}
            COPYONLY)
        ELSE ("${SPECFILE_EXT}" STREQUAL ".spec")
        # This is a to-be-configured spec file
          GET_FILENAME_COMPONENT(SPECFILE_NAME ${SPECFILE_PATH} NAME_WE)
          SET(SPECFILE_NAME "${SPECFILE_NAME}.spec")
          MESSAGE(STATUS "Configuring spec file <${SPECFILE_PATH}> --> <${RPM_ROOTDIR}/SPECS/${SPECFILE_NAME}>")
          CONFIGURE_FILE(
            ${SPECFILE_PATH} 
            ${RPM_ROOTDIR}/SPECS/${SPECFILE_NAME}
            @ONLY)
        ENDIF ("${SPECFILE_EXT}" STREQUAL ".spec")
      ENDIF("${ARGV1}" STREQUAL "")
            
      ADD_CUSTOM_TARGET(${RPMNAME}_srpm
        COMMAND ${CMAKE_BUILD_TOOL} src_dist
        COMMAND ${CMAKE_COMMAND} -E copy ${SRC_DIST_DIR}.tar.gz ${RPM_ROOTDIR}/SOURCES    
        COMMAND ${RPMTools_RPMBUILD_EXECUTABLE} -bs --define=\"_topdir ${RPM_ROOTDIR}\" --buildroot=${RPM_ROOTDIR}/tmp ${RPM_ROOTDIR}/SPECS/${SPECFILE_NAME} 
        )
      
      ADD_CUSTOM_TARGET(${RPMNAME}_rpm
        COMMAND ${CMAKE_BUILD_TOOL} src_dist
        COMMAND ${CMAKE_COMMAND} -E copy ${SRC_DIST_DIR}.tar.gz ${RPM_ROOTDIR}/SOURCES    
        COMMAND ${RPMTools_RPMBUILD_EXECUTABLE} -bb --define=\"_topdir ${RPM_ROOTDIR}\" --buildroot=${RPM_ROOTDIR}/tmp ${RPM_ROOTDIR}/SPECS/${SPECFILE_NAME} 
        )  
    ENDMACRO(RPMTools_ADD_RPM_TARGETS)

  ELSE (RPMTools_RPMBUILD_FOUND)
    SET(RPMTools FALSE)
  ENDIF (RPMTools_RPMBUILD_FOUND)  
  
ENDIF (UNIX)
