# Copyright (C) 2019-2024 Cisco Systems, Inc. and/or its affiliates. All rights reserved. if(WIN32) cmake_minimum_required( VERSION 3.16 ) # For file(GET_RUNTIME_DEPENDENCIES) else() cmake_minimum_required( VERSION 3.14 ) endif() set(CMAKE_C_STANDARD 90) set(CMAKE_C_STANDARD_REQUIRED ON) # CMAKE_CXX_STANDARD not set because we may need to match the compiler used to build LLVM. # There's probably a good chance this issue will go away if using modern LLVM versions. cmake_policy(SET CMP0087 NEW) # support generator expressions in install(CODE) and install(SCRIPT) # Change this on a release: # During active development: set(VERSION_SUFFIX "-devel-${TODAY}") # For beta: set(VERSION_SUFFIX "-beta") # For release candidate: set(VERSION_SUFFIX "-rc") # For release: set(VERSION_SUFFIX "") string(TIMESTAMP TODAY "%Y%m%d") set(VERSION_SUFFIX "") project( ClamAV VERSION "1.4.0" DESCRIPTION "ClamAV open source email, web, and end-point anti-virus toolkit." ) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) include(Version) set(PACKAGE_NAME "${PROJECT_NAME}") set(PACKAGE_VERSION "${PROJECT_VERSION}") set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}${VERSION_SUFFIX}") set(PACKAGE_BUGREPORT "https://github.com/Cisco-Talos/clamav/issues") set(PACKAGE_URL "https://www.clamav.net/") HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH}) # libtool library versioning rules: http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html set(LIBCLAMAV_CURRENT 13) set(LIBCLAMAV_REVISION 0) set(LIBCLAMAV_AGE 1) math(EXPR LIBCLAMAV_SOVERSION "${LIBCLAMAV_CURRENT} - ${LIBCLAMAV_AGE}") set(LIBCLAMAV_VERSION "${LIBCLAMAV_SOVERSION}.${LIBCLAMAV_AGE}.${LIBCLAMAV_REVISION}") HexVersion(LIBCLAMAV_VERSION_NUM ${LIBCLAMAV_CURRENT} ${LIBCLAMAV_REVISION} ${LIBCLAMAV_AGE}) set(LIBFRESHCLAM_CURRENT 3) set(LIBFRESHCLAM_REVISION 2) set(LIBFRESHCLAM_AGE 0) math(EXPR LIBFRESHCLAM_SOVERSION "${LIBFRESHCLAM_CURRENT} - ${LIBFRESHCLAM_AGE}") set(LIBFRESHCLAM_VERSION "${LIBFRESHCLAM_SOVERSION}.${LIBFRESHCLAM_AGE}.${LIBFRESHCLAM_REVISION}") HexVersion(LIBFRESHCLAM_VERSION_NUM ${LIBFRESHCLAM_CURRENT} ${LIBFRESHCLAM_REVISION} ${LIBFRESHCLAM_AGE}) set(GENERATE_WARNING "WARNING: This file was generated by CMake. Do not edit!") # # Define C_LINUX and C_BSD because CMake only defines UNIX, APPLE, WIN32, MSVC # if(CMAKE_SYSTEM_NAME STREQUAL "Linux") set(C_LINUX 1) elseif(APPLE OR CMAKE_SYSTEM_NAME MATCHES "BSD") set(C_BSD 1) endif() # Git optionally used to add commit info into build to differentiate in bug reports. find_package(Git) if(Git_FOUND) # Store git description into variable execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always OUTPUT_VARIABLE REPO_VERSION ERROR_QUIET) if("${REPO_VERSION}" MATCHES "") unset(REPO_VERSION) else() string(STRIP ${REPO_VERSION} REPO_VERSION) endif() endif() # Enable use of pkg-config to find dependencies. find_package(PkgConfig QUIET) # # Load Build Options # # CMake Option default values: set(MAINTAINER_MODE_DEFAULT OFF) set(ENABLE_APP_DEFAULT ON) if(WIN32 OR APPLE) set(ENABLE_MILTER_DEFAULT OFF) else() set(ENABLE_MILTER_DEFAULT ON) endif() if(C_LINUX) set(ENABLE_CLAMONACC_DEFAULT ON) else() set(ENABLE_CLAMONACC_DEFAULT OFF) endif() set(ENABLE_EXAMPLES_DEFAULT OFF) set(ENABLE_TESTS_DEFAULT ON) if(WIN32) set(ENABLE_MAN_PAGES_DEFAULT OFF) else() set(ENABLE_MAN_PAGES_DEFAULT ON) endif() set(ENABLE_DOXYGEN_DEFAULT OFF) set(ENABLE_UNRAR_DEFAULT ON) set(ENABLE_SYSTEMD_DEFAULT ON) # See CMakeOptions.cmake for additional options. include(CMakeOptions.cmake) # Set build type to RelWithDebInfo if not specified. # This must be done before pulling in the Rust module # or else the default build will be Debug for Rust stuffs. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE) # Include "None" as option to disable any additional (optimization) flags, # relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by # default). These strings are presented in cmake-gui. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() # # Find Build Tools # if(MAINTAINER_MODE) # Bison, Flex required to build Yara module for libclamav. find_package(BISON REQUIRED) find_package(FLEX REQUIRED) # TODO: Gperf required to generate JS-normalization code. # find_package(GPERF REQUIRED) endif() find_package(Rust REQUIRED) if(ENABLE_FUZZ) # We'd like the fuzz targets to be statically linked set(ENABLE_STATIC_LIB ON) set(ENABLE_SHARED_LIB OFF) set(ENABLE_LIBCLAMAV_ONLY ON) set(ENABLE_TESTS OFF) set(OPTIMIZE OFF) set(ENABLE_SYSTEMD OFF) set(HAVE_MMAP OFF) if(NOT DEFINED ENV{FUZZING_ENGINE}) # If you're not building in an oss-fuzz docker environment, you can build the fuzz targets by setting: # bash: export CC=`which clang` && export CXX=`which clang++` && export SANITIZER=address/undefined/memory # fish: export CC=(which clang) && export CXX=(which clang++) && export SANITIZER=address/undefined/memory set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=$ENV{SANITIZER},fuzzer-no-link -fsanitize-coverage=edge,indirect-calls") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=$ENV{SANITIZER},fuzzer-no-link -fsanitize-coverage=edge,indirect-calls") endif() endif() if(ENABLE_STATIC_LIB AND NOT ENABLE_SHARED_LIB AND ENABLE_UNRAR) # When building everything static, link in libunrar. set(UNRAR_LINKED 1) endif() if(ENABLE_LIBCLAMAV_ONLY AND (ENABLE_APP OR ENABLE_EXAMPLES)) # Remember when disabled options are disabled for later diagnostics. set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1) else() set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0) endif() if(ENABLE_LIBCLAMAV_ONLY) set(ENABLE_APP OFF) set(ENABLE_EXAMPLES OFF) endif() # # Set RPATH for custom install prefixes # if(APPLE AND NOT DO_NOT_SET_RPATH) set(CMAKE_MACOSX_RPATH 1) endif() include(GNUInstallDirs) if (NOT DEFINED CMAKE_INSTALL_RPATH AND NOT DO_NOT_SET_RPATH) if(CMAKE_INSTALL_FULL_LIBDIR) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_FULL_LIBDIR}") else() set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") endif() endif() if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(USING_CLANG ON) else() set(USING_CLANG OFF) endif() if(C_LINUX) if(CMAKE_COMPILER_IS_GNUCXX OR USING_CLANG) # Set _GNU_SOURCE for O_LARGEFILE, O_CLOEXEC, O_DIRECTORY, O_NOFOLLOW, etc flags on older systems # (pre POSIX.1-2008: glibc 2.11 and earlier). #4042 set(_GNU_SOURCE 1) endif() endif() # # Use the `lib` prefix on Windows, to match previous ClamAV build # if(LLVM_FOUND) list(JOIN LLVM_LIBRARIES "," LLVM_LIBS) list(JOIN LLVM_LIBRARY_DIRS "," LLVM_DIRS) endif() if(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "lib") set(CMAKE_STATIC_LIBRARY_PREFIX "lib") endif() # # Find Test dependencies # if(ENABLE_TESTS) # Used for the libclamav unit test framework find_package(Libcheck REQUIRED) # Used to generate the test files and for the application feature test framework # In distros that support multiple implementations of python it is helpful to specify the impl to use if(DEFINED PYTHON_FIND_VERSION) find_package(Python3 EXACT ${PYTHON_FIND_VERSION} REQUIRED) else() find_package(Python3 REQUIRED) # Not requesting a specific python impl; try using pytest from the PATH execute_process( COMMAND pytest --version RESULT_VARIABLE PYTEST_EXIT_CODE ERROR_QUIET OUTPUT_QUIET ) if(${PYTEST_EXIT_CODE} EQUAL 0) # pytest found in the path. set(PythonTest_COMMAND "pytest;-v") endif() endif() if("${PythonTest_COMMAND}" STREQUAL "") # Not in the path or specified a python impl; try using: python3 -m pytest execute_process( COMMAND ${Python3_EXECUTABLE} -m pytest --version RESULT_VARIABLE PYTEST_MODULE_EXIT_CODE ERROR_QUIET OUTPUT_QUIET ) if(${PYTEST_MODULE_EXIT_CODE} EQUAL 0) # pytest isn't in the path, but the Python 3 we found has it. set(PythonTest_COMMAND "${Python3_EXECUTABLE};-m;pytest;-v") else() # pytest couldn't be found, verify that we can at least use: python3 -m unittest execute_process( COMMAND ${Python3_EXECUTABLE} -m unittest --help RESULT_VARIABLE UNITTEST_MODULE_EXIT_CODE ERROR_QUIET OUTPUT_QUIET ) if(${UNITTEST_MODULE_EXIT_CODE} EQUAL 0) # No pytest :-(, but we'll get by with unittest message("Python 3 package 'pytest' is not installed for ${Python3_EXECUTABLE} and is not available in your PATH.") message("Failed unit tests will be easier to read if you install pytest.") message("Eg: python3 -m pip install --user pytest") set(PythonTest_COMMAND "${Python3_EXECUTABLE};-m;unittest;--verbose") else() # No unittest either! # Some weird Python installations do exist that lack standard modules like unittest. # Let's make sure these folks know the Python 3 install we found won't cut it. message("Python 3 found: ${Python3_EXECUTABLE}, but it is missing the unittest module (weird!).") message(FATAL_ERROR "The tests won't work with this Python installation. You can disable the tests by reconfiguring with: -D ENABLE_TESTS=OFF") endif() endif() endif() # Check for valgrind. If it exists, we'll enable extra tests that use valgrind. if(C_LINUX) find_package(Valgrind) endif() endif() # # Configure CPack # - for installers # - for source tarball # if (WIN32) find_package(PThreadW32) set(HAVE_PTHREAD_H 1) set(_REENTRANT 1) set(CL_THREAD_SAFE 1) else() set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads) if(Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) set(HAVE_PTHREAD_H 1) set(_REENTRANT 1) set(CL_THREAD_SAFE 1) endif() endif() # # Configure CPack # - for installers # - for source tarball # set(CPACK_PACKAGE_NAME ${PACKAGE_STRING}) #set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/logo.png) #set(CPACK_PACKAGE_RELOCATABLE TRUE) set(CPACK_STRIP_FILES TRUE) set(CPACK_PACKAGE_VERSION_MAJOR ${CLAMAV_VERSION_MAJOR}) set(CPACK_PACKAGE_VERSION_MINOR ${CLAMAV_VERSION_MINOR}) set(CPACK_PACKAGE_VERSION_PATCH ${CLAMAV_VERSION_PATCH}) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_DESCRIPTION}) set(CPACK_PACKAGE_CONTACT https://www.clamav.net/) # point to readme and license files set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/COPYING.txt) set(CPACK_PACKAGE_FILE_NAME clamav-${PROJECT_VERSION}${VERSION_SUFFIX}) set(CPACK_SOURCE_GENERATOR "TGZ") set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}) set(CPACK_SOURCE_IGNORE_FILES "\\.git/" ".*~$" "^${CMAKE_BINARY_DIR}") set(CPACK_VERBATIM_VARIABLES YES) if (WIN32) set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) include(InstallRequiredSystemLibraries) set(CPACK_GENERATOR "ZIP;WIX") set(CPACK_PACKAGE_VENDOR "Cisco Systems, Inc.") set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.win.${CMAKE_VS_PLATFORM_NAME}) NumberToHex(${PROJECT_VERSION_MAJOR} HEX_MAJOR) NumberToHex(${PROJECT_VERSION_MINOR} HEX_MINOR) NumberToHex(${PROJECT_VERSION_PATCH} HEX_PATCH) SET(CPACK_WIX_PRODUCT_GUID "D9F136C1-3691-47E3-9079-4FE9C9${HEX_MAJOR}${HEX_MINOR}${HEX_PATCH}") SET(CPACK_WIX_UPGRADE_GUID "D9F136C1-3691-47E3-9079-4FE9C9${HEX_MAJOR}0000") SET(CPACK_WIX_PRODUCT_ICON ${CMAKE_CURRENT_SOURCE_DIR}/win32/res/clam.ico) SET(CPACK_WIX_UI_BANNER ${CMAKE_CURRENT_SOURCE_DIR}/win32/wix_ui_banner.bmp) SET(CPACK_WIX_UI_DIALOG ${CMAKE_CURRENT_SOURCE_DIR}/win32/wix_ui_dialog.bmp) SET(CPACK_WIX_CMAKE_PACKAGE_REGISTRY ClamAV) set(CPACK_PACKAGE_INSTALL_DIRECTORY "ClamAV") install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/NEWS.md ${CMAKE_CURRENT_SOURCE_DIR}/README.md DESTINATION ".") elseif(APPLE) set(CPACK_PACKAGE_NAME ClamAV) set(CPACK_GENERATOR productbuild) set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.macos.universal) set(CPACK_PACKAGE_VENDOR "cisco") # For Apple, creates short name com.cisco.clamav.xxx in pkgutil # productbuild requires components or it won't add anything to the PKG set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries") set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "The ClamAV libraries including the header files for C/C++ development.") set(CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME "Documentation") set(CPACK_COMPONENT_DOCUMENTATION_DESCRIPTION "Manpages and HTML documentation.") set(CPACK_COMPONENT_PROGRAMS_DISPLAY_NAME "Programs") set(CPACK_COMPONENT_PROGRAMS_DESCRIPTION "The ClamAV toolkit.") # dependencies between components set(CPACK_COMPONENT_DOCUMENTATION_DEPENDS libraries) set(CPACK_COMPONENT_PROGRAMS_DEPENDS libraries) set(CPACK_COMPONENT_LIBRARIES_REQUIRED ON) # always install the libs set(CPACK_COMPONENTS_ALL libraries documentation programs) if(CLAMAV_SIGN_FILE) # This tells Xcode's signing phase to pretend that the binary was signed by the linker. # Then install_name_tool is willing to revise the ad-hoc signature. # See: https://gitlab.kitware.com/cmake/cmake/-/issues/21854#note_907691 set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "-o linker-signed") # Stripping the files will invalidate the signatures. set(CPACK_STRIP_FILES FALSE) # Convert NEWS.md to HTML to match Apple productbuild requirements. # Not in the path, try using: python3 -m pytest execute_process( COMMAND ${Python3_EXECUTABLE} -m markdown --version RESULT_VARIABLE MARKDOWN_MODULE_EXIT_CODE ERROR_QUIET OUTPUT_QUIET ) if(${MARKDOWN_MODULE_EXIT_CODE} EQUAL 0) # The markdown module is installed, we can do the conversion. execute_process( COMMAND echo "" OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/prefix.html) execute_process( COMMAND ${Python3_EXECUTABLE} -m markdown ${CMAKE_CURRENT_SOURCE_DIR}/NEWS.md OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/body.html) execute_process( COMMAND echo "" OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/suffix.html) execute_process( COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/prefix.html ${CMAKE_CURRENT_BINARY_DIR}/body.html ${CMAKE_CURRENT_BINARY_DIR}/suffix.html OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/NEWS.html) set(CPACK_RESOURCE_FILE_README ${PROJECT_BINARY_DIR}/NEWS.html) else() message("Failed to detect the Python 3 'markdown' package.") message(FATAL_ERROR "Try running 'pip3 install --user markdown' and then try again.") endif() endif() elseif(C_BSD) # User must specify `-G FreeBSD` when building FreeBSD packages # Disclaimer: doesn't seem to actually exist, despite being in the documentation. set(CPACK_PACKAGE_NAME clamav) set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.freebsd.${CMAKE_SYSTEM_PROCESSOR}) set(CPACK_FREEBSD_PACKAGE_LICENSE "GPLv2") set(CPACK_FREEBSD_PACKAGE_MAINTAINER "https://www.clamav.net/") else() # User must specify `-G DEB` or `-G RPM` when building Linux packages set(CPACK_PACKAGE_NAME clamav) set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION}${VERSION_SUFFIX}) set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME}.linux.${CMAKE_SYSTEM_PROCESSOR}) set(CPACK_RPM_PACKAGE_LICENSE "GPLv2") set(CPACK_RPM_PACKAGE_AUTOREQ " no") set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/sbin" "/usr/local" "/usr/local/bin" "/usr/local/etc" "/usr/local/include" "/usr/local/lib" "/usr/local/sbin" "/usr/local/share" "/usr/local/share/man" "/usr/local/share/man/man1" "/usr/local/share/man/man5" "/usr/local/share/man/man8" ) endif() # Including CPack must be the very last CPack thing we do. include(CPack) # libclamav efficacy dependencies find_package(OpenSSL REQUIRED) find_package(ZLIB REQUIRED) find_package(BZip2 REQUIRED) # Disable CMAKE_FIND_PACKAGE_PREFER_CONFIG, temporarily, because # we don't presently support the using libxml2's Config.cmake set(PACKAGE_PREFER_CONFIG_BAK ${CMAKE_FIND_PACKAGE_PREFER_CONFIG}) set(CMAKE_FIND_PACKAGE_PREFER_CONFIG FALSE) find_package(LibXml2 REQUIRED) # Restore the requested CMAKE_FIND_PACKAGE_PREFER_CONFIG setting set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ${PACKAGE_PREFER_CONFIG_BAK}) find_package(PCRE2 REQUIRED) # libclamav feature dependencies if(NOT WIN32) find_package(Iconv REQUIRED) # Set variable required by libclamav to use iconv set(HAVE_ICONV 1) endif() if(ENABLE_JSON_SHARED) set(JSONC_USE_STATIC OFF) else() set(JSONC_USE_STATIC ON) endif() find_package(JSONC REQUIRED) set(LLVM_MAX_VER "13") set(LLVM_MIN_VER "8") string (TOLOWER ${BYTECODE_RUNTIME} bytecodeRuntime) if(${bytecodeRuntime} STREQUAL "llvm") if(DEFINED LLVM_ROOT_DIR AND DEFINED LLVM_FIND_VERSION) find_package(LLVM EXACT ${LLVM_FIND_VERSION} REQUIRED HINTS ${LLVM_ROOT_DIR}) elseif(DEFINED LLVM_ROOT_DIR) find_package(LLVM REQUIRED HINTS ${LLVM_ROOT_DIR}) elseif(DEFINED LLVM_FIND_VERSION) find_package(LLVM EXACT ${LLVM_FIND_VERSION} REQUIRED) else() set (LLVM_FIND_VERSION ${LLVM_MIN_VER}) find_package(LLVM REQUIRED) endif() if(LLVM_FOUND) if (LLVM_AVAILABLE_LIBS) message(STATUS "LLVM found using LLVMConfig.cmake") set(LLVM_LIBRARIES ${LLVM_AVAILABLE_LIBS}) else() message(STATUS "LLVM found using FindLLVM.cmake") set(LLVM_PACKAGE_VERSION ${LLVM_VERSION_STRING}) if (${LLVM_VERSION_STRING} VERSION_GREATER_EQUAL "9.0.0" AND ${LLVM_VERSION_STRING} VERSION_LESS "10.0.0") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG") endif() endif() math(EXPR TOO_HIGH_VERSION "${LLVM_MAX_VER} + 1" OUTPUT_FORMAT DECIMAL) if(${LLVM_PACKAGE_VERSION} VERSION_LESS ${LLVM_MIN_VER}) message(FATAL_ERROR "LLVM version ${LLVM_PACKAGE_VERSION} is too old") elseif (${LLVM_PACKAGE_VERSION} VERSION_GREATER_EQUAL ${TOO_HIGH_VERSION} ) message(FATAL_ERROR "LLVM version ${LLVM_PACKAGE_VERSION} is too new") else() message(STATUS "LLVM version ${LLVM_PACKAGE_VERSION} found") endif() # Set variable required by libclamav to use llvm instead of interpreter set(LLVM_VERSION ${LLVM_VERSION_MAJOR}${LLVM_VERSION_MINOR}) endif() endif() if(APPLE) find_library(APPLE_CORE_FOUNDATION CoreFoundation) if (NOT APPLE_CORE_FOUNDATION) message(FATAL_ERROR "Apple CoreFoundation framework not found") endif() find_library(APPLE_SECURITY Security) if (NOT APPLE_SECURITY) message(FATAL_ERROR "Apple Security framework not found") endif() endif() # libfreshclam & application dependencies if(NOT ENABLE_LIBCLAMAV_ONLY) find_package(CURL REQUIRED) if(ENABLE_APP) find_package(CURSES REQUIRED) if(NOT WIN32 AND ENABLE_MILTER) find_package(Milter REQUIRED) endif() if(C_LINUX AND ENABLE_SYSTEMD) find_package(SYSTEMD) if(SYSTEMD_FOUND) set(HAVE_SYSTEMD 1) endif() endif() endif() endif() # Do not disable assertions based on CMAKE_BUILD_TYPE. foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo") foreach(_lang C CXX) string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var) string(REGEX REPLACE "(^|)[/-]D *NDEBUG($|)" " " ${_var} "${${_var}}") endforeach() endforeach() # Disable optimizations if OPTIMIZE=OFF if(NOT OPTIMIZE) # Get rid of any previous optimization flag settings... string(REGEX REPLACE "(\-O[011123456789])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REGEX REPLACE "(\-O[011123456789])" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") # ...And substitute our own. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") endif() # Support the latest c++ standard available. include(ExtractValidFlags) foreach(_cxx1x_flag -std=c++14 -std=c++11) extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag}) if(_cxx1x_flag_supported) set(CXX1XCXXFLAGS ${_cxx1x_flag}) break() endif() endforeach() # Always use '-fPIC'/'-fPIE' option if OS is not Haiku. if(NOT HAIKU) set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() # Checks for header files. include(CheckIncludeFile) check_include_file("arpa/inet.h" HAVE_ARPA_INET_H) check_include_file("fcntl.h" HAVE_FCNTL_H) check_include_file("grp.h" HAVE_GRP_H) check_include_file("limits.h" HAVE_LIMITS_H) check_include_file("malloc.h" HAVE_MALLOC_H) check_include_file("netdb.h" HAVE_NETDB_H) check_include_file("netinet/in.h" HAVE_NETINET_IN_H) check_include_file("poll.h" HAVE_POLL_H) check_include_file("pwd.h" HAVE_PWD_H) check_include_file("stdbool.h" HAVE_STDBOOL_H) check_include_file("stdlib.h" HAVE_STDLIB_H) check_include_file("string.h" HAVE_STRING_H) check_include_file("strings.h" HAVE_STRINGS_H) check_include_file("sys/cdefs.h" HAVE_SYS_CDEFS_H) check_include_file("sys/dl.h" HAVE_SYS_DL_H) check_include_file("sys/fileio.h" HAVE_SYS_FILIO_H) check_include_file("sys/mman.h" HAVE_SYS_MMAN_H) check_include_file("sys/param.h" HAVE_SYS_PARAM_H) check_include_file("sys/queue.h" HAVE_SYS_QUEUE_H) check_include_file("sys/select.h" HAVE_SYS_SELECT_H) check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) check_include_file("sys/stat.h" HAVE_SYS_STAT_H) check_include_file("sys/time.h" HAVE_SYS_TIME_H) check_include_file("sys/times.h" HAVE_SYS_TIMES_H) check_include_file("sys/uio.h" HAVE_SYS_UIO_H) check_include_file("syslog.h" USE_SYSLOG) check_include_file("termios.h" HAVE_TERMIOS_H) check_include_file("time.h" HAVE_TIME_H) check_include_file("unistd.h" HAVE_UNISTD_H) check_include_file("sys/fanotify.h" HAVE_SYS_FANOTIFY_H) if(WIN32) set(HAVE_RESOLV_H 1) set(HAVE_DIRENT_H 1) set(HAVE_DLFCN_H 1) else() if(APPLE) set(BIND_8_COMPAT 1) endif() check_include_file("resolv.h" HAVE_RESOLV_H) if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND EXISTS /usr/include/resolv.h) # This hack because check_include_file() can't find "resolv.h" on FreeBSD. set(HAVE_RESOLV_H 1) endif() check_include_file("dirent.h" HAVE_DIRENT_H) check_include_file("dlfcn.h" HAVE_DLFCN_H) endif() # int-types variants check_include_file("inttypes.h" HAVE_INTTYPES_H) check_include_file("sys/inttypes.h" HAVE_SYS_INTTYPES_H) check_include_file("sys/int_types.h" HAVE_SYS_INT_TYPES_H) check_include_file("stdint.h" HAVE_STDINT_H) # this hack required to silence warnings on systems with inttypes.h # because json-c's inttypes header isn't generated for each system. Hooray C! if(HAVE_INTTYPES_H) set(JSON_C_HAVE_INTTYPES_H 1) endif() include(CheckTypeSize) # Checks for typedefs, structures, and compiler characteristics. # AC_TYPE_SIZE_T check_type_size("ssize_t" SIZEOF_SSIZE_T) if(SIZEOF_SSIZE_T STREQUAL "") # ssize_t is a signed type in POSIX storing at least -1. # Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools). set(SSIZE_T_DEF "typedef int ssize_t;") endif() check_type_size("off_t" SIZEOF_OFF_T) if(SIZEOF_OFF_T STREQUAL "") # off_t is a signed type in POSIX no narrower than int. # Set it to "long int" to match the behavior of AC_TYPE_OFF_T (autotools). set(OFF_T_DEF "typedef long int off_t;") endif() check_type_size("int" SIZEOF_INT) check_type_size("short" SIZEOF_SHORT) check_type_size("long" SIZEOF_LONG) check_type_size("long long" SIZEOF_LONG_LONG) # # Variables for clamav-types.h.in # #TODO: Move this to a .cmake file if(HAVE_SYS_INT_TYPES_H) set(INT_TYPES_HEADER "#include ") elseif(HAVE_INTTYPES_H) set(INT_TYPES_HEADER "#include ") elseif(HAVE_STDINT_H) set(INT_TYPES_HEADER "#include ") elseif(WIN32 AND MSVC) # Windows / Visual C++ (not Cygwin), stdint.h should exist. set(INT_TYPES_HEADER "#include ") else() # No int types header available. We'll define the types manually. set(INT8_DEF "typedef signed char int8_t;") set(UINT8_DEF "typedef unsigned char uint8_t;") if(SIZEOF_INT EQUAL 2) set(INT16_DEF "typedef signed int int16_t;") set(UINT16_DEF "typedef unsigned int uint16_t;") elseif(SIZEOF_SHORT EQUAL 2) set(INT16_DEF "typedef signed short int16_t;") set(UINT16_DEF "typedef unsigned short uint16_t;") endif() if(SIZEOF_INT EQUAL 4) set(INT32_DEF "typedef signed int int32_t;") set(UINT32_DEF "typedef unsigned int uint32_t;") elseif(SIZEOF_LONG EQUAL 4) set(INT32_DEF "typedef signed long int32_t;") set(UINT32_DEF "typedef unsigned long uint32_t;") endif() if(SIZEOF_LONG EQUAL 8) set(INT64_DEF "typedef signed long int64_t;") set(UINT64_DEF "typedef unsigned long uint64_t;") elseif(SIZEOF_LONG_LONG EQUAL 8) set(INT64_DEF "typedef signed long long int64_t;") set(UINT64_DEF "typedef unsigned long long uint64_t;") endif() endif() # Always do this if(SIZEOF_INT EQUAL 4) set(DEFINE_SF32_PREFIX "#define _SF32_PREFIX \"\"") elseif(SIZEOF_LONG EQUAL 4) set(DEFINE_SF32_PREFIX "#define _SF32_PREFIX \"l\"") endif() if(SIZEOF_LONG EQUAL 8) set(DEFINE_SF64_PREFIX "#define _SF64_PREFIX \"l\"") elseif(SIZEOF_LONG_LONG EQUAL 8) set(DEFINE_SF64_PREFIX "#define _SF64_PREFIX \"ll\"") endif() # Check for restrict keyword #TODO: Move this to a .cmake file foreach( ac_kw __restrict __restrict__ _Restrict restrict ) check_c_source_compiles( " typedef int * int_ptr; int foo (int_ptr ${ac_kw} ip) { return ip[0]; } int main() { int s[1]; int * ${ac_kw} t = s; t[0] = 0; return foo(t); } " HAVE_RESTRICT ) if( HAVE_RESTRICT ) set( ac_cv_c_restrict ${ac_kw} ) break() endif() endforeach() if( HAVE_RESTRICT ) set( restrict ${ac_cv_c_restrict} ) endif() # Define inline macro as needed. include(TestInline) # Determine if _FILE_OFFSET_BITS 64 needs to be set to handle large files. include(CheckFileOffsetBits) # Determine how to pack structs on this platform. include(CheckStructPacking) # Check for signed right shift implementation. include(CheckSignedRightShift) # Check if systtem fts implementation available include(CheckFTS) # Check if uname(2) follows POSIX standard. include(CheckUnamePosix) # Check support for file descriptor passing include(CheckFDPassing) # Check if big-endian include(TestBigEndian) TEST_BIG_ENDIAN(WORDS_BIGENDIAN) include(CheckStructHasMember) check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF) # Check size of pointer to decide we need 8 bytes alignment adjustment. check_type_size("int *" SIZEOF_INT_P) check_type_size("time_t" SIZEOF_TIME_T) # Checks for library functions. include(CheckSymbolExists) check_symbol_exists(_Exit "stdlib.h" HAVE__EXIT) check_symbol_exists(accept4 "sys/types.h" HAVE_ACCEPT4) check_symbol_exists(snprintf "stdio.h" HAVE_SNPRINTF) check_symbol_exists(stat64 "sys/stat.h" HAVE_STAT64) check_symbol_exists(strcasestr "string.h" HAVE_STRCASESTR) check_symbol_exists(strerror_r "string.h" HAVE_STRERROR_R) check_symbol_exists(strlcat "string.h" HAVE_STRLCAT) check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY) check_symbol_exists(strndup "string.h" HAVE_STRNDUP) check_symbol_exists(strnlen "string.h" HAVE_STRNLEN) check_symbol_exists(strnstr "string.h" HAVE_STRNSTR) check_symbol_exists(sysctlbyname "sysctl.h" HAVE_SYSCTLBYNAME) check_symbol_exists(timegm "time.h" HAVE_TIMEGM) check_symbol_exists(vsnprintf "stdio.h" HAVE_VSNPRINTF) if(WIN32) #set(HAVE_FSEEKO 1) set(HAVE_GETADDRINFO 1) set(HAVE_GETPAGESIZE 1) set(HAVE_MKSTEMP 1) set(HAVE_POLL 1) else() check_symbol_exists(fseeko "stdio.h" HAVE_FSEEKO) check_symbol_exists(getaddrinfo "netdb.h" HAVE_GETADDRINFO) check_symbol_exists(getpagesize "unistd.h" HAVE_GETPAGESIZE) check_symbol_exists(mkstemp "unistd.h" HAVE_MKSTEMP) check_symbol_exists(poll "poll.h" HAVE_POLL) check_symbol_exists(setgroups "unistd.h" HAVE_SETGROUPS) check_symbol_exists(setsid "unistd.h" HAVE_SETSID) endif() include(CheckSymbolExists) # XXX does this correctly detect initgroups (un)availability on cygwin? check_symbol_exists(initgroups grp.h HAVE_INITGROUPS) if(NOT HAVE_INITGROUPS AND HAVE_UNISTD_H) # FreeBSD declares initgroups() in unistd.h check_symbol_exists(initgroups unistd.h HAVE_INITGROUPS2) if(HAVE_INITGROUPS2) set(HAVE_INITGROUPS 1) endif() endif() set(WARNCFLAGS) set(WARNCXXFLAGS) if(CMAKE_C_COMPILER_ID MATCHES "MSVC") if(ENABLE_WERROR) set(WARNCFLAGS /WX) set(WARNCXXFLAGS /WX) endif() else() if(ENABLE_WERROR) extract_valid_c_flags(WARNCFLAGS -Werror) extract_valid_c_flags(WARNCXXFLAGS -Werror) endif() # For C compiler extract_valid_c_flags(WARNCFLAGS -Wall -Wextra -Wformat-security ) if(ENABLE_ALL_THE_WARNINGS) extract_valid_c_flags(WARNCFLAGS -Waddress -Wattributes -Wclobbered -Wconversion -Wdeclaration-after-statement -Wdiv-by-zero -Wempty-body -Wendif-labels -Wfloat-equal -Wformat-nonliteral -Winline -Wmissing-declarations -Wmissing-field-initializers -Wmissing-noreturn -Wmissing-prototypes -Wnested-externs #-Wno-format-nonliteral # May be required to pass format string as "const char*. -Wpointer-arith -Wpragmas -Wredundant-decls -Wshadow -Wunreachable-code -Wunused-parameter -Wvla -Wwrite-strings -Wstrict-prototypes -Wundef -Wcast-align -Wextended-offsetof # May be missing from GCC -Wheader-guard # Only work with Clang for the moment -Wlanguage-extension-token # May be missing from GCC -Wmissing-variable-declarations # May be missing from GCC #-Wpadded # Not used because we cannot change public structs -Wshorten-64-to-32 # May be missing from GCC -Wsign-conversion #-Wswitch-enum # Not used because this basically disallows default case -Wunreachable-code-break # May be missing from GCC -Wunused-macros ) endif() # For C++ compiler extract_valid_cxx_flags(WARNCXXFLAGS -Wall -Wformat-security -Wno-comment # Disabled because LLVM's CFG.h has a warning about a multiline comment because of ascii-art of a graph with a `\` in it. ) endif() # autotools-compatible names # Sphinx expects relative paths in the .rst files. Use the fact that the files # below are all one directory level deep. file(RELATIVE_PATH top_srcdir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}") file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}") set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}") set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}") # libclamav.pc (pkg-config file) set(prefix "${CMAKE_INSTALL_PREFIX}") set(exec_prefix "${CMAKE_INSTALL_PREFIX}") set(bindir "${CMAKE_INSTALL_FULL_BINDIR}") set(sbindir "${CMAKE_INSTALL_FULL_SBINDIR}") set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}") set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}") set(VERSION "${PACKAGE_VERSION}") # Absolute path of database directory if(IS_ABSOLUTE ${DATABASE_DIRECTORY}) set(DATADIR "${DATABASE_DIRECTORY}") else() set(DATADIR "${CMAKE_INSTALL_PREFIX}/${DATABASE_DIRECTORY}") endif() # Absolute path of the applications' config directory if(IS_ABSOLUTE ${APP_CONFIG_DIRECTORY}) set(CONFDIR "${APP_CONFIG_DIRECTORY}") else() set(CONFDIR "${CMAKE_INSTALL_PREFIX}/${APP_CONFIG_DIRECTORY}") endif() if(ENABLE_DEBUG) set(CL_DEBUG 1) endif() if(ENABLE_EXPERIMENTAL) set(CL_EXPERIMENTAL 1) endif() if(ENABLE_STRN_INTERNAL) set(HAVE_STRNI 1) endif() if(ENABLE_FRESHCLAM_DNS_FIX) set(FRESHCLAM_DNS_FIX 1) endif() if(ENABLE_FRESHCLAM_NO_CACHE) set(FRESHCLAM_NO_CACHE 1) endif() set(SCANBUFF 131072) # scan buffer size set(FILEBUFF 8192) # file i/o buffer size if(APPLE) set(C_DARWIN 1) endif() include(CheckFmapFeatures) if(WIN32) set(USE_MPOOL 1) endif() add_definitions(-DHAVE_CONFIG_H) configure_file(clamav-config.h.cmake.in clamav-config.h) configure_file(target.h.cmake.in target.h) configure_file(platform.h.in platform.h) configure_file(clamav-version.h.in clamav-version.h) configure_file(clamav-types.h.in clamav-types.h) if(WIN32) # # Windows-specific config stuff # # Windows resource file set(CLAMAV_RES "") configure_file( win32/res/common.rc.in ${CMAKE_SOURCE_DIR}/win32/res/common.rc @ONLY) else() # # POSIX-specific config stuff # # Don't confuse clamav-config.in with clamav-config.h.in or clamav-config.h.cmake.in configure_file(clamav-config.in ${CMAKE_CURRENT_BINARY_DIR}/clamav-config @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/clamav-config" DESTINATION "${CMAKE_INSTALL_BINDIR}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT libraries) # pkg-config configure_file( libclamav.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libclamav.pc @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libclamav.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" COMPONENT libraries) endif() # include CTest to enable testing before we add any subdirectories which may # add additional tests (like with `add_rust_test()`) if(ENABLE_TESTS) include(CTest) endif() # # ClamAV Build targets! # # Build targets for libraries. if(ENABLE_UNRAR) # Only build libclamunrar if enabled. # We still define the libclamunrar_iface's interface regardless, # so that libclamav will have unrar_iface.h in the include path. add_subdirectory( libclamunrar ) endif() add_subdirectory( libclamunrar_iface ) if(NOT ENABLE_EXTERNAL_MSPACK) add_subdirectory( libclammspack ) set(LIBMSPACK "ClamAV::libmspack") else() find_package(MSPack REQUIRED) set(LIBMSPACK "MSPack::mspack") endif() if(WIN32) add_subdirectory( win32/compat ) endif() add_subdirectory( libclamav ) add_subdirectory( libclamav_rust ) if(NOT ENABLE_LIBCLAMAV_ONLY) add_subdirectory( common ) add_subdirectory( libfreshclam ) if(ENABLE_APP) # Build targets for primary applications. add_subdirectory( clamconf ) add_subdirectory( clamd ) add_subdirectory( clamdscan ) if(C_LINUX AND ENABLE_CLAMONACC) add_subdirectory( clamonacc ) endif() if(ENABLE_MILTER) add_subdirectory( clamav-milter ) endif() add_subdirectory( clamscan ) add_subdirectory( sigtool ) add_subdirectory( clambc ) add_subdirectory( clamsubmit ) add_subdirectory( freshclam ) add_subdirectory( clamdtop ) if(WIN32) add_subdirectory( win32/conf_examples ) else() add_subdirectory( etc ) endif() endif() endif() if(ENABLE_EXAMPLES) add_subdirectory( examples ) endif() add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) if(ENABLE_TESTS) add_subdirectory( unit_tests ) endif() add_subdirectory( docs ) if(ENABLE_FUZZ) add_subdirectory( fuzz ) endif() if(WIN32) # Include the license(s) in the installation install(FILES ${CMAKE_SOURCE_DIR}/COPYING.txt DESTINATION . COMPONENT libraries) install(DIRECTORY ${CMAKE_SOURCE_DIR}/COPYING DESTINATION . COMPONENT libraries) endif() # # The Summary Info. # include(ColourMessage) string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type) message(STATUS "${Y}Configuration Options Summary${e} -- ${c} Package Version: ${e}${PACKAGE_STRING} ${c} libclamav version: ${e}${LIBCLAMAV_CURRENT}:${LIBCLAMAV_REVISION}:${LIBCLAMAV_AGE} ${c} libfreshclam version: ${e}${LIBFRESHCLAM_CURRENT}:${LIBFRESHCLAM_REVISION}:${LIBFRESHCLAM_AGE} ${c} Install prefix: ${e}${CMAKE_INSTALL_PREFIX} ${c} Install database dir: ${e}${DATADIR} ${c} Install config dir: ${e}${CONFDIR} ${c} Host system: ${e}${CMAKE_HOST_SYSTEM} ${c} Target system: ${e}${CMAKE_SYSTEM} ${c} Compiler: ${e} ${b} Build type: ${e}${CMAKE_BUILD_TYPE} ${b} C compiler: ${e}${CMAKE_C_COMPILER} ${b} C++ compiler: ${e}${CMAKE_CXX_COMPILER} ${b} Rust toolchain: ${e}${cargo_EXECUTABLE} (${cargo_VERSION}) ${b} CFLAGS: ${e}${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} ${b} CXXFLAGS: ${e}${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS} ${b} WARNCFLAGS: ${e}${WARNCFLAGS}") if(VCPKG_TOOLCHAIN) message("\ ${c} Using vcpkg: ${e} ${b} Target Triplet: ${e}${VCPKG_TARGET_TRIPLET} ${b} Target Arch: ${e}${VCPKG_TARGET_ARCHITECTURE} ${b} Get runtime DLLs: ${e}${VCPKG_APPLOCAL_DEPS} ${b} Package root path: ${e}${VCPKG_CMAKE_FIND_ROOT_PATH}") endif() message("\ ${c} Build Options: ${e} ${b} Build apps: ${e}${ENABLE_APP} ${b} Shared library: ${e}${ENABLE_SHARED_LIB} ${b} Static library: ${e}${ENABLE_STATIC_LIB} ${b} Enable UnRAR: ${e}${ENABLE_UNRAR} ${b} Examples: ${e}${ENABLE_EXAMPLES} ${b} Tests: ${e}${ENABLE_TESTS} ${b} Build man pages: ${e}${ENABLE_MAN_PAGES} ${b} Build doxygen HTML: ${e}${ENABLE_DOXYGEN} ${b} Maintainer Mode: ${e}${MAINTAINER_MODE}") if(MAINTAINER_MODE) message("\ ${R} Maintainer Mode Tools: ${e} ${y} bison: ${e}${BISON_EXECUTABLE} (${BISON_VERSION}) ${y} flex: ${e}${FLEX_EXECUTABLE} (${FLEX_VERSION})") endif() if(NOT WIN32) message("\ ${c} Build Extras: ${e}") message("\ ${b} Build milter: ${e}${ENABLE_MILTER} (toggle with -DENABLE_MILTER=ON/OFF)") if(C_LINUX) message("\ ${b} Build clamonacc: ${e}${ENABLE_CLAMONACC} (toggle with -DENABLE_CLAMONACC=ON/OFF)") endif() endif() if(LLVM_FOUND) message(STATUS "${C}Engine Options${e} -- ${b} Bytecode Runtime: ${e} ${_} llvm ${e}${LLVM_INCLUDE_DIRS} ${_} ${e}${LLVM_LIBRARY_DIRS} ${_} ${e}${LLVM_LIBRARIES}") else() message(STATUS "${C}Engine Options${e} -- ${b} Bytecode Runtime: ${e} ${_} ${BYTECODE_RUNTIME} ${e}") endif() if(ENABLE_TESTS) message(STATUS "${C}Test Dependencies${e} -- ${b} Unit Test Framework:${e} ${_} libcheck ${e}${LIBCHECK_INCLUDE_DIR} ${_} ${e}${LIBCHECK_LIBRARY} ${b} Feature Test Framework:${e} ${_} python3 ${e}${Python3_EXECUTABLE} ${_} test command ${e}${PythonTest_COMMAND}") endif() message(STATUS "${C}libclamav Dependencies${e} -- ${b} Compression support:${e} ${_} bzip2 ${e}${BZIP2_INCLUDE_DIRS} ${_} ${e}${BZIP2_LIBRARIES} ${_} zlib ${e}${ZLIB_INCLUDE_DIRS} ${_} ${e}${ZLIB_LIBRARIES} ${b} XML support: ${e} ${_} libxml2 ${e}${LIBXML2_INCLUDE_DIRS} ${_} ${e}${LIBXML2_LIBRARIES} ${b} RegEx support: ${e} ${_} libpcre2 ${e}${PCRE2_INCLUDE_DIRS} ${_} ${e}${PCRE2_LIBRARIES} ${b} Crypto support: ${e} ${_} openssl ${e}${OPENSSL_INCLUDE_DIR} ${_} ${e}${OPENSSL_LIBRARIES} ${b} JSON support: ${e} ${_} json-c ${e}${JSONC_INCLUDE_DIRS} ${_} ${e}${JSONC_LIBRARIES} ${b} Threading support: ${e}") if(WIN32) message("\ ${_} pthread-win32 ${e}${PThreadW32_INCLUDE_DIRS} ${_} ${e}${PThreadW32_LIBRARIES}") elseif(Threads_FOUND AND CMAKE_USE_PTHREADS_INIT) message("\ ${_} pthread ${e}") else() message("\ ${o} no ${e}") endif() if(NOT WIN32) message("\ ${b} Locale support: ${e} ${_} iconv ${e}${Iconv_INCLUDE_DIRS} ${_} ${e}${Iconv_LIBRARIES}") endif() if(NOT ENABLE_LIBCLAMAV_ONLY) message(STATUS "${C}libfreshclam Extra Dependencies${e} -- ${b} HTTP support: ${e} ${_} curl ${e}${CURL_INCLUDE_DIRS} ${_} ${e}${CURL_LIBRARIES}") endif() if(HAVE_LIBNCURSES) message(STATUS "${C}Application Extra Dependencies${e} -- ${b} GUI support: ${e} ${_} ncurses ${e}${CURSES_INCLUDE_DIRS} ${_} ${e}${CURSES_LIBRARIES}") elseif(HAVE_LIBPDCURSES) message(STATUS "${C}Application Extra Dependencies${e} -- ${b} GUI support: ${e} ${_} pdcurses ${e}${CURSES_INCLUDE_DIRS} ${_} ${e}${CURSES_LIBRARIES}") endif() if(C_LINUX) if(SYSTEMD_PROGRAM_FOUND) message("\ ${b} systemd: ${e} ${_} unit directory ${e}${SYSTEMD_UNIT_DIR} ${b} systemd ctl support: ${e}") if(SYSTEMD_FOUND) message("\ ${_} libsystemd ${e}${SYSTEMD_INCLUDE_DIRS} ${_} ${e}${SYSTEMD_LIBRARIES}") else() message("\ ${_} libsystemd ${e}not found") endif() else() message("\ ${b} systemd: ${e}not found") endif() endif() if(ENABLE_MILTER) message("\ ${b} Milter Support: ${e} ${_} libmilter ${e}${Milter_INCLUDE_DIRS} ${_} ${e}${Milter_LIBRARIES}") endif() message("") if(NOT JSONC_USE_STATIC) message(STATUS "${g}Warning:${e} libjson-c is known to share symbol names with other JSON libraries which may result in crashes for applications that use libclamav. Consider providing a static json-c library that was compiled with: CFLAGS=\"-fPIC\". Default build settings for json-c 0.15+ should also work. Use the `-DENABLE_JSON_SHARED=OFF` option to prefer detection of the static library, or use -DJSONC_INCLUDE_DIR and -DJSONC_LIBRARY to specify the static JSON library.") endif()