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 "$" "${CMAKE_COMMAND}" -E rename "$" "$-imported" ) if(MSVC AND isDebugBuild) add_custom_command(TARGET app PRE_LINK COMMAND "${CMAKE_COMMAND}" -E chdir "$" "${CMAKE_COMMAND}" -E rename "$.pdb" "$.pdb-imported" ) endif() add_custom_command(TARGET app POST_BUILD COMMAND "${CMAKE_COMMAND}" -E chdir "$" "${CMAKE_COMMAND}" -E remove "$" COMMAND "${CMAKE_COMMAND}" -E chdir "$" "${CMAKE_COMMAND}" -E rename "$-imported" "$" ) if(MSVC AND isDebugBuild) add_custom_command(TARGET app POST_BUILD COMMAND "${CMAKE_COMMAND}" -E chdir "$" "${CMAKE_COMMAND}" -E rename "$.pdb-imported" "$.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 )