set(CMAKE_POLICY_DEFAULT_CMP0074 NEW) set(CMAKE_POLICY_DEFAULT_CMP0075 NEW) set(CMAKE_POLICY_DEFAULT_CMP0079 NEW) cmake_minimum_required(VERSION 3.5) project(SWI-Prolog) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # While GCC is good at optimization large functions, MSVC is bad at it # and using VMI functions more then doubles the performance. For Clang # the picture is less clear. The difference is small, with a slight win # on either depending on CPU and workload. if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL Clang) set(DEFAULT_VMI_FUNCTIONS ON) else() set(DEFAULT_VMI_FUNCTIONS OFF) endif() option(MULTI_THREADED "Enable multiple Prolog threads" ON) option(ENGINES "Enable multiple Prolog engines" OFF) option(VMI_FUNCTIONS "Create a function for each VM instruction" ${DEFAULT_VMI_FUNCTIONS}) option(USE_SIGNALS "Enable signal handling" ON) option(USE_GMP "Use GNU MP Bignum library (LGPL)" ON) if(APPLE) # tcmalloc breaks setlocale() on MacOS 12 (Monterey) option(USE_TCMALLOC "Use Google tcmalloc instead of default malloc" OFF) else() option(USE_TCMALLOC "Use Google tcmalloc instead of default malloc" ON) endif() option(SWIPL_SHARED_LIB "Put kernel in a shared library" ON) option(SWIPL_VERSIONED_DIR "Install into a versioned directory" OFF) option(SWIPL_INSTALL_IN_LIB "Install library in ${CMAKE_INSTALL_PREFIX}/lib" OFF) option(SWIPL_INSTALL_IN_SHARE "Install docs in ${CMAKE_INSTALL_PREFIX}/share/swipl" OFF) option(SWIPL_M32 "Build 32-bit version on 64-bit Linux using multilib and gcc -m32" OFF) option(INSTALL_DOCUMENTATION "Install the HTML documentation files" ON) option(BUILD_PDF_DOCUMENTATION "Build the PDF manuals from source" OFF) option(MACOS_UNIVERSAL_BINARY "Build a universal binary for x86_64 and arm64" OFF) option(BUILD_MACOS_BUNDLE "Install for a MacOS bundle (SWI-Prolog.app)" OFF) option(BUILD_TESTING "Build test files and setup for ctest" ON) option(SKIP_SSL_TESTS "Skip the SSL tests" OFF) option(TEST_PROTOBUFS_PROTOC "Run protobuf tests that require protoc, etc." OFF) option(BUILD_SWIPL_LD "Create the swipl-ld utility" ON) option(INSTALL_TESTS "Install script and files needed to run tests of the final installation" OFF) option(GCOV "Compile for coverage analysis using gcov (gcc)" OFF) option(STATIC_EXTENSIONS "Add foreign extensions statically" OFF) if(EMSCRIPTEN) set(DEFAULT_CCACHE OFF) else() set(DEFAULT_CCACHE ON) endif() option(CCACHE "Use ccache when available" ${DEFAULT_CCACHE}) set(JNIDIR "" CACHE STRING "Directory for linking Java JNI components") if(NOT SWIPL_SHARED_LIB) set(CMAKE_ENABLE_EXPORTS ON) endif() set(CMAKE_C_STANDARD 11) include(Utils) include(BuildType) include(Version) include(PGO) include(Ports) include(Locations) include(InstallSource) include(QLF) include(PackageSelection) include(Dependencies) include(DocDepends) if(GMP_FOUND) set(USE_LIBBF_DEFAULT OFF) else() set(USE_LIBBF_DEFAULT ON) endif() option(USE_LIBBF "Use LibBF for bignums (MIT)" ${USE_LIBBF_DEFAULT}) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set_install_prefix() message("-- Using install prefix \"${CMAKE_INSTALL_PREFIX}\"") endif() # Verbosity set(CMAKE_INSTALL_MESSAGE NEVER) if(CCACHE) find_program(PROG_CCACHE ccache) if(PROG_CCACHE) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${PROG_CCACHE}) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${PROG_CCACHE}) endif(PROG_CCACHE) endif(CCACHE) ################ # Installation directories if(WIN32 AND NOT MSYS2) set(SWIPL_INSTALL_DIR "." CACHE STRING "Directory below for installation") set(SWIPL_INSTALL_PREFIX ${SWIPL_INSTALL_DIR}) set(SWIPL_INSTALL_ARCH_EXE ${SWIPL_INSTALL_PREFIX}/bin) set(SWIPL_INSTALL_ARCH_LIB ${SWIPL_INSTALL_PREFIX}/bin) set(SWIPL_INSTALL_MODULES ${SWIPL_INSTALL_PREFIX}/bin) # Place all .exe and .dll in one directory set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src) set(SWIPL_TMP_DIR "c:/tmp" CACHE STRING "Directory to be used if the environment variable TEMP is not set") else() if(SWIPL_VERSIONED_DIR) set(SWIPL_INSTALL_DIR_DEF swipl-${SWIPL_VERSION_STRING}) else() set(SWIPL_INSTALL_DIR_DEF swipl) endif() set(SWIPL_INSTALL_DIR ${SWIPL_INSTALL_DIR_DEF} CACHE STRING "Directory below for installation") set(SWIPL_TMP_DIR "/tmp" CACHE STRING "Directory to be used if the environment variable TMP is not set") if(BUILD_MACOS_BUNDLE) set(SWIPL_INSTALL_PREFIX SWI-Prolog.app/Contents/swipl) set(SWIPL_INSTALL_ARCH_EXE SWI-Prolog.app/Contents/MacOS) set(SWIPL_INSTALL_ARCH_LIB SWI-Prolog.app/Contents/Frameworks) set(SWIPL_INSTALL_MANPAGES SWI-Prolog.app/Contents/man) set(SWIPL_INSTALL_PKGCONFIG SWI-Prolog.app/Contents/pkgconfig) set(SWIPL_INSTALL_RESOURCES SWI-Prolog.app/Contents/Resources) else() set(SWIPL_INSTALL_PREFIX lib/${SWIPL_INSTALL_DIR}) if(SWIPL_INSTALL_IN_SHARE) set(SWIPL_INSTALL_SHARE_PREFIX share/${SWIPL_INSTALL_DIR}) endif() set(SWIPL_INSTALL_ARCH_EXE ${SWIPL_INSTALL_PREFIX}/bin/${SWIPL_ARCH}) set(SWIPL_INSTALL_ARCH_LIB ${SWIPL_INSTALL_PREFIX}/lib/${SWIPL_ARCH}) set(SWIPL_INSTALL_MANPAGES share/man/man1 CACHE STRING "Directory for man pages") set(SWIPL_INSTALL_PKGCONFIG share/pkgconfig CACHE STRING "Directory for pkg-config pages") endif() set(SWIPL_INSTALL_MODULES ${SWIPL_INSTALL_PREFIX}/lib/${SWIPL_ARCH}) endif() set(SWIPL_CMAKE_NAMESPACE swipl::) set(SWIPL_INSTALL_CMAKE_CONFIG_DIR lib/cmake/swipl) if(NOT SWIPL_INSTALL_SHARE_PREFIX) set(SWIPL_INSTALL_SHARE_PREFIX "${SWIPL_INSTALL_PREFIX}") endif() set(SWIPL_BOOT_BASE "boot.prc") set(SWIPL_BOOT_FILE "${CMAKE_CURRENT_BINARY_DIR}/home/${SWIPL_BOOT_BASE}") set(SWIPL_INSTALL_LIBRARY ${SWIPL_INSTALL_PREFIX}/library) set(SWIPL_INSTALL_BOOT ${SWIPL_INSTALL_PREFIX}/boot) set(SWIPL_INSTALL_INCLUDE ${SWIPL_INSTALL_PREFIX}/include) set(SWIPL_INSTALL_DOC ${SWIPL_INSTALL_SHARE_PREFIX}/doc) if(INSTALL_TESTS) set(INSTALL_TESTS_DIR ${SWIPL_INSTALL_PREFIX}/test) endif() if(NOT SWIPL_PKG_NAME) if(SWIPL_INSTALL_DIR STREQUAL "swi-prolog") set(SWIPL_PKG_NAME ${SWIPL_INSTALL_DIR}) else() set(SWIPL_PKG_NAME "swipl") endif() endif() if(MSVC) add_compile_options(/W3) else() add_compile_options(-Wall) endif() # on ARM, backtrace() requires -funwind-tables. See # https://stackoverflow.com/questions/24700150/on-raspberry-pi-backtrace-returns-0-frames # We must do this at the toplevel to ensure all packages use this as well. if(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm") include(CheckFunctionExists) check_function_exists(backtrace HAVE_BACKTRACE) if(HAVE_BACKTRACE) add_compile_options(-funwind-tables) endif() endif() if(MACOS_UNIVERSAL_BINARY) # Does not work!? Now uses CFLAGS=-arcg x86_64 on M1. See scripts/make-distribution # add_compile_options("SHELL:-arch x86_64" "SHELL:-arch arm64") endif() if(SWIPL_M32) include(cross/linux_i386) endif() if(BUILD_TESTING) enable_testing() endif() # Configuration we need everywhere if(MULTI_THREADED) if(MSVC) find_package(PThreads4W) endif() if(TARGET PThreads4W::PThreads4W) add_library(Threads::Threads ALIAS PThreads4W::PThreads4W) set(CMAKE_USE_PTHREADS_INIT ON) else() set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads) endif() endif() include(TestLargeFiles) OPJ_TEST_LARGE_FILES(HAVE_LARGE_FILES) set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "Core_system") # Add the core Prolog system add_subdirectory(src) install(FILES LICENSE README.md DESTINATION ${SWIPL_INSTALL_PREFIX}) install(FILES customize/edit customize/init.pl customize/README.md DESTINATION ${SWIPL_INSTALL_PREFIX}/customize) if(INSTALL_DOCUMENTATION) include(Documentation) set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Documentation) add_custom_target( doc ALL COMMENT "Build the documentation") add_custom_target( doc.html COMMENT "Build HTML documentation") add_dependencies(doc doc.html) add_custom_command( OUTPUT ${MAN_INDEX} COMMAND ${PROG_SWIPL} -f none --no-packs --home=${SWIPL_BUILD_HOME} -g "use_module(library(prolog_install))" -g cmake_save_man_index -t halt DEPENDS swipl core doc.html VERBATIM) add_custom_target( man_index DEPENDS ${MAN_INDEX}) add_dependencies(doc man_index) install(FILES ${MAN_INDEX} DESTINATION ${SWIPL_INSTALL_DOC}) if(BUILD_PDF_DOCUMENTATION) add_custom_target( doc.pdf COMMENT "Build PDF documentation") add_dependencies(doc doc.pdf) endif() add_subdirectory(man) install(FILES packages/index.html DESTINATION ${SWIPL_INSTALL_DOC}/packages) endif(INSTALL_DOCUMENTATION) # Install a prolog script to run tests on target device # in which ctest is not available if(INSTALL_TESTS) set(INSTALL_TESTS_DIR ${SWIPL_INSTALL_PREFIX}/test) set(PKGS_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/packages) set(INSTALL_TESTS_DB ${CMAKE_BINARY_DIR}/cmake_pkg_tests.db) #Move test db to installation install(FILES ${INSTALL_TESTS_DB} DESTINATION ${INSTALL_TESTS_DIR} COMPONENT Tests) file(REMOVE ${INSTALL_TESTS_DB}) endif(INSTALL_TESTS) # Add the packages if(STATIC_EXTENSIONS) set_property(GLOBAL PROPERTY static_extension_libs) endif() foreach(package ${SWIPL_PACKAGE_LIST}) swipl_package_component(${package} CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) add_subdirectory(packages/${package}) endforeach(package) if(STATIC_EXTENSIONS) get_property(extlibs GLOBAL PROPERTY static_extension_libs) include(StaticPackages) write_static_extensions(${CMAKE_BINARY_DIR}/src/static_packages.h ${extlibs}) endif() # Check for environment variables that may cause the build to fail include(CheckEnv) # Packaging include(Pack)