cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(fossil C)
include(ExternalProject)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(default_build_type "RelWithDebInfo")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
else()
message(STATUS "'${CMAKE_BUILD_TYPE}' build type")
endif()
set(isDebugBuild FALSE)
if(CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]" )
set(isDebugBuild TRUE)
endif()
## VARIABLES ---------------------------------------------------------------
## Additional parameters can be passed in the following variables which can
## be defined on cmake command line (or in cache).
##
## The parameters correspond to the ones used in the external fossil build
## process (as specified at configure, make, and make test)
##
if(FOSSIL_CONFIGURE)
message(STATUS "Fossil build configuration '${FOSSIL_CONFIGURE}'")
set(configure_FLAGS ${FOSSIL_CONFIGURE})
endif()
if(FOSSIL_BUILD)
message(STATUS "Fossil build variables '${FOSSIL_BUILD}'")
set(build_FLAGS ${FOSSIL_BUILD})
endif()
if(FOSSIL_TEST)
message(STATUS "Fossil test configuration '${FOSSIL_TEST}'")
set(test_FLAGS ${FOSSIL_TEST})
endif()
add_executable(fossil-exe IMPORTED)
set(fossil_INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR})
set(fossil_EXE_DIR "${fossil_INSTALL_DIR}/bin")
set(fossil_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(fossil_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/fossil)
if(MSVC)
set(fossil_BUILD_DIR ${fossil_BINARY_DIR}/msvcbld)
else(MSVC)
set(fossil_BUILD_DIR ${fossil_BINARY_DIR}/bld)
endif(MSVC)
set(fossil_TEST_DIR "${fossil_BINARY_DIR}/test")
set(EXE ${CMAKE_EXECUTABLE_SUFFIX})
set(fossil_EXE "${fossil_EXE_DIR}/fossil${EXE}")
file(TO_NATIVE_PATH "${fossil_EXE}" fossil_EXE)
set_target_properties(fossil-exe PROPERTIES
IMPORTED_LOCATION "${fossil_EXE}"
)
## SETUP IDE ---------------------------------------------------------------
## Setup Project Sources View
## Add more source files for convenience; otherwise only actual dependencies
## would appear in the Projects tree pane.
##
file(GLOB_RECURSE project_sources_DIRS
#"autosetup/*" #may be useful when debuging configure
"skins/*"
"src/*"
"test/*.test" "test/tester.tcl"
"win/*"
"www/*.wiki" "www/*.md" "www/*.html"
)
file(GLOB project_sources_FILES
"auto.def"
"configure"
"Makefile.in"
"fossil.1"
"manifest.uuid"
"VERSION"
"${fossil_BINARY_DIR}/autoconfig.h"
"${fossil_BINARY_DIR}/Makefile*"
"${fossil_BUILD_DIR}/*.[h]"
#"${fossil_BUILD_DIR}/main_.c"
)
include_directories(
"${fossil_BUILD_DIR}"
"${fossil_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/src"
"${PROJECT_SOURCE_DIR}"
)
add_custom_target(project-sources ALL
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
SOURCES ${project_sources_DIRS} ${project_sources_FILES}
)
## CONFIGURE ---------------------------------------------------------------
##
set(fossil_configure_FLAGS "")
if(configure_FLAGS)
set(fossil_configure_FLAGS ${configure_FLAGS})
endif()
if(isDebugBuild)
if(MSVC)
if(NOT "${fossil_configure_FLAGS}" MATCHES "FOSSIL_DEBUG")
set(fossil_configure_FLAGS "FOSSIL_DEBUG=1" ${fossil_configure_FLAGS})
endif()
else(MSVC)
if(NOT "${fossil_configure_FLAGS}" MATCHES "--fossil-debug")
set(fossil_configure_FLAGS "--fossil-debug" ${fossil_configure_FLAGS})
endif()
endif(MSVC)
endif()
## BUILD ---------------------------------------------------------------
##
# Build fossil as an external project; just pass the options for configure and
# build stages. This way we rely upon the existing build scripts.
#
# Install the resulting binary into the local binary dir, such that the fossil
# binary can be located at the fixed location on target platform.
#
# Then we define CMake install targets to copy the binaries from the local
# binary dir.
#
if(isDebugBuild)
set_property(DIRECTORY APPEND PROPERTY
COMPILE_DEFINITIONS FOSSIL_DEBUG
)
endif()
set(fossil_build_FLAGS "")
if(build_FLAGS)
set(fossil_build_FLAGS ${build_FLAGS})
endif()
separate_arguments(fossil_configure_FLAGS)
separate_arguments(fossil_build_FLAGS)
if(MSVC)
file(RELATIVE_PATH fossil_DESTDIR "${fossil_BUILD_DIR}" "${fossil_EXE_DIR}")
file(TO_NATIVE_PATH "${fossil_DESTDIR}" fossil_DESTDIR)
## Work around the suprisingly obstinate "simplification" of buildmsvc.bat
## which mandates the use of BUILDDIR env variable to be able to build
## out-of-source, instead of inferring the path automatically from the
## current work directory, as it's commonly done.
##
## Create a wrapper which defines BUILDDIR then starts the build.
file(TO_NATIVE_PATH "${fossil_BUILD_DIR}" fossil_BUILD_DIR_WIN)
file(TO_NATIVE_PATH "${fossil_SOURCE_DIR}/win/buildmsvc.bat" fossil_BUILDMSVC)
file(WRITE "${fossil_BINARY_DIR}/build.cmd"
"set \"BUILDDIR=${fossil_BUILD_DIR_WIN}\"\n\"${fossil_BUILDMSVC}\" %*\n")
ExternalProject_Add(fossil
PREFIX fossil
SOURCE_DIR "${fossil_SOURCE_DIR}"
CONFIGURE_COMMAND ""
BINARY_DIR "${fossil_BINARY_DIR}"
BUILD_COMMAND "${fossil_BINARY_DIR}/build.cmd"
${fossil_configure_FLAGS}
${fossil_build_FLAGS}
all
install DESTDIR=${fossil_DESTDIR}
VERBATIM
INSTALL_COMMAND ""
STEP_TARGETS configure build install
)
else(MSVC)
set_property(DIRECTORY APPEND PROPERTY
COMPILE_DEFINITIONS HAVE_AUTOCONFIG_H;_HAVE_SQLITE_CONFIG_H
)
file(RELATIVE_PATH fossil_DESTDIR "${fossil_BINARY_DIR}" "${fossil_INSTALL_DIR}")
ExternalProject_Add(fossil
PREFIX fossil
SOURCE_DIR "${fossil_SOURCE_DIR}"
CONFIGURE_COMMAND "${fossil_SOURCE_DIR}/configure"
--prefix=/ ${fossil_configure_FLAGS}
VERBATIM
BINARY_DIR "${fossil_BINARY_DIR}"
BUILD_COMMAND "${CMAKE_MAKE_PROGRAM}"
${fossil_build_FLAGS}
VERBATIM
INSTALL_COMMAND "${CMAKE_MAKE_PROGRAM}" install
DESTDIR=${fossil_DESTDIR}
STEP_TARGETS configure build install
)
endif(MSVC)
set_property(DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES "${fossil_BUILD_DIR}"
"${fossil_EXE_DIR}"
)
ExternalProject_Add_Step(fossil forcebuild
COMMAND "${CMAKE_COMMAND}" -E echo "Build fossil"
DEPENDEES configure
DEPENDERS build
ALWAYS 1
)
add_dependencies(fossil-exe fossil)
## We need an executable target, so that IDEs can infer what to run/debug.
## Define a substitute executable target to stand in for the actual fossil binary
## that we just built via ExternalProject_Add.
## Keep the actual fossil binary, clean up the built substitute artifacts.
get_filename_component(app_NAME "${fossil_EXE}" NAME_WE)
get_filename_component(app_DIR "${fossil_EXE}" DIRECTORY)
file(TO_NATIVE_PATH "${app_DIR}" app_DIR)
file(WRITE "${CMAKE_BINARY_DIR}/app.c" "int main(){ return 0; }\n")
add_executable(app app.c)
set_target_properties(app PROPERTIES
OUTPUT_NAME "${app_NAME}"
RUNTIME_OUTPUT_DIRECTORY "${app_DIR}"
)
if(MSVC)
set_target_properties(app PROPERTIES
LINK_FLAGS "/INCREMENTAL:NO /MANIFEST:NO"
)
if(isDebugBuild)
set_target_properties(app PROPERTIES
PDB_NAME "${app_NAME}"
)
endif()
endif()
add_custom_command(TARGET app PRE_LINK
COMMAND "${CMAKE_COMMAND}" -E chdir "$<TARGET_FILE_DIR:app>"
"${CMAKE_COMMAND}" -E rename "$<TARGET_FILE_NAME:app>"
"$<TARGET_FILE_NAME:app>-imported"
)
if(MSVC AND isDebugBuild)
add_custom_command(TARGET app PRE_LINK
COMMAND "${CMAKE_COMMAND}" -E chdir "$<TARGET_FILE_DIR:app>"
"${CMAKE_COMMAND}" -E rename "$<TARGET_PROPERTY:app,PDB_NAME>.pdb"
"$<TARGET_PROPERTY:app,PDB_NAME>.pdb-imported"
)
endif()
add_custom_command(TARGET app POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E chdir "$<TARGET_FILE_DIR:app>"
"${CMAKE_COMMAND}" -E remove "$<TARGET_FILE_NAME:app>"
COMMAND "${CMAKE_COMMAND}" -E chdir "$<TARGET_FILE_DIR:app>"
"${CMAKE_COMMAND}" -E rename "$<TARGET_FILE_NAME:app>-imported"
"$<TARGET_FILE_NAME:app>"
)
if(MSVC AND isDebugBuild)
add_custom_command(TARGET app POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E chdir "$<TARGET_FILE_DIR:app>"
"${CMAKE_COMMAND}" -E rename "$<TARGET_PROPERTY:app,PDB_NAME>.pdb-imported"
"$<TARGET_PROPERTY:app,PDB_NAME>.pdb"
)
endif()
add_dependencies(app fossil-exe)
## TEST ---------------------------------------------------------------
##
add_custom_target(test-fossil-setup
COMMENT "Setting up test-fossil"
DEPENDS fossil-install
)
add_custom_command(TARGET test-fossil-setup PRE_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${fossil_SOURCE_DIR}/test" "${fossil_TEST_DIR}"
WORKING_DIRECTORY "${fossil_BINARY_DIR}"
COMMENT "Copying data for test-fossil"
VERBATIM
)
add_custom_command(TARGET test-fossil-setup POST_BUILD
WORKING_DIRECTORY "${fossil_TEST_DIR}"
COMMENT "Setting up test-fossil"
VERBATIM
)
# Run the test suite.
# Other flags that can be included in TESTFLAGS are:
#
# -halt Stop testing after the first failed test
# -keep Keep the temporary workspace for debugging
# -prot Write a detailed log of the tests to the file ./prot
# -verbose Include even more details in the output
# -quiet Hide most output from the terminal
# -strict Treat known bugs as failures
#
# TESTFLAGS can also include names of specific test files to limit
# the run to just those test cases.
set(TCL "tclsh")
if( test_FLAGS )
set(fossil_test_FLAGS ${test_FLAGS})
endif()
separate_arguments(fossil_test_FLAGS)
add_custom_target(test-fossil
COMMAND "${TCL}" tester.tcl "${fossil_EXE}" -quiet ${fossil_test_FLAGS}
VERBATIM
WORKING_DIRECTORY "${fossil_TEST_DIR}"
COMMENT "Running test-fossil"
DEPENDS fossil-install
)
add_custom_target(test-fossil-clean
COMMENT "Tearing down test-fossil"
DEPENDS fossil-install
)
add_custom_command(TARGET test-fossil-clean POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${fossil_TEST_DIR}"
WORKING_DIRECTORY "${fossil_BINARY_DIR}"
COMMENT "Removing data for test-fossil"
VERBATIM
)
add_custom_target(clean-fossil
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${fossil_EXE_DIR}"
VERBATIM
COMMAND "${CMAKE_MAKE_PROGRAM}" clean
VERBATIM
WORKING_DIRECTORY "${fossil_BINARY_DIR}"
COMMENT "Cleaning fossil build artifacts"
DEPENDS fossil-configure
)
enable_testing()
add_test(NAME 01-setup
COMMAND "${CMAKE_COMMAND}" --build . --target test-fossil-setup
)
add_test(NAME 02-test
COMMAND "${CMAKE_COMMAND}" --build . --target test-fossil
)
add_test(NAME 03-clean
COMMAND "${CMAKE_COMMAND}" --build . --target test-fossil-clean
)
set_property(TEST 02-test APPEND PROPERTY
DEPENDS 01-setup)
set_property(TEST 03-clean APPEND PROPERTY
DEPENDS 01-setup)
add_custom_target(check
COMMAND "${CMAKE_CTEST_COMMAND}" -V
)
## INSTALL ---------------------------------------------------------------
##
install(DIRECTORY ${fossil_EXE_DIR}/
DESTINATION ${CMAKE_INSTALL_PREFIX}/bin/
USE_SOURCE_PERMISSIONS
)