<commit_before>cmake_minimum_required(VERSION 2.6)

project("openscap")
set(OPENSCAP_VERSION_MAJOR "1")
set(OPENSCAP_VERSION_MINOR "3")
set(OPENSCAP_VERSION_PATCH "0")
set(OPENSCAP_VERSION "${OPENSCAP_VERSION_MAJOR}.${OPENSCAP_VERSION_MINOR}.${OPENSCAP_VERSION_PATCH}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")

message(STATUS "OpenSCAP ${OPENSCAP_VERSION}")
message(STATUS "(see ${CMAKE_SOURCE_DIR}/README.md for build instructions)")
message(STATUS " ")

# Strictly speaking in-source will work but will be very messy, let's
# discourage our users from using them
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
	message(FATAL_ERROR "In-source builds are not supported! Please use out of source builds:\n"
		"$ cd openscap\n"
		"$ rm CMakeCache.txt\n"
		"$ cd build\n"
		"$ cmake ../\n"
		"$ make -j4"
		)
endif()

# In Microsoft Visual Studio, store built binaries to a single directory.
# We need to build all the binaries in a single directory on Windows, because
# vcpkg tool fails to fetch dependent DLLs (libxml, libcurl, etc.) if
# oscap.exe is build to a different directory than openscap.dll.
# See the discussion in https://github.com/Microsoft/vcpkg/issues/1002
if(MSVC)
	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
	set(CMAKE_PDB_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()

# ---------- INCLUDES CMAKE MODULES

include(GNUInstallDirs)
include(FindPkgConfig)
include(CheckLibraryExists)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckCSourceCompiles)
include(CMakeDependentOption)

# ---------- DEPENDENCIES

find_package(ACL)
if(ACL_FOUND)
	check_library_exists(${ACL_LIBRARY} acl_extended_file "" HAVE_ACL_EXTENDED_FILE)
	check_include_file(acl/libacl.h HAVE_ACL_LIBACL_H)
	check_include_file(sys/acl.h HAVE_SYS_ACL_H)
endif()

find_package(AptPkg)

find_package(Blkid)
if(BLKID_FOUND)
	check_library_exists(blkid blkid_get_tag_value "" HAVE_BLKID_GET_TAG_VALUE)
endif()

find_package(Cap)
if(CAP_FOUND)
	check_library_exists(cap cap_get_pid "" HAVE_CAP_GET_PID)
endif()

find_package(CURL)
find_package(DBus)
find_package(Doxygen)
find_package(GConf)
find_package(Ldap)
find_package(OpenDbx)
find_package(PCRE REQUIRED)
find_package(PerlLibs)
find_package(Popt)

find_package(Procps)
if(PROCPS_FOUND)
	check_library_exists(procps dev_to_tty "" HAVE_DEV_TO_TTY)
	check_include_file(proc/devname.h HAVE_PROC_DEVNAME_H)
endif()

# According to CMake documentation:
# https://cmake.org/cmake/help/latest/module/FindPythonInterp.html
# If calling both find_package(PythonInterp) and find_package(PythonLibs),
# call find_package(PythonInterp) first to get the currently active Python
# version by default with a consistent version of PYTHON_LIBRARIES.
find_package(PythonInterp 3)
find_package(PythonLibs 3)

find_package(RPM)
if(RPM_FOUND)
	check_library_exists(rpm rpmReadConfigFiles "" HAVE_RPMREADCONFIGFILES)
	check_library_exists(rpm headerFormat "" HAVE_HEADERFORMAT)
	check_library_exists(rpmio rpmFreeCrypto "" HAVE_RPMFREECRYPTO)
	check_library_exists(rpm rpmFreeFilesystems "" HAVE_RPMFREEFILESYSTEMS)
	set(HAVE_RPMVERCMP 1)
endif()

find_package(SELinux)
find_package(SWIG)
find_package(LibXml2 REQUIRED)
find_package(LibXslt REQUIRED)
find_package(BZip2)

# PThread
set(CMAKE_THREAD_PREFER_PTHREAD)
set(THREADS_PREFER_PTHREAD_FLAG)
set(THREADS_USE_PTHREADS_WIN32 true)
find_package(Threads REQUIRED)
check_library_exists(pthread pthread_timedjoin_np "" HAVE_PTHREAD_TIMEDJOIN_NP)
check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP)
check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP)

# WITH_CRYPTO
set(WITH_CRYPTO "gcrypt" CACHE STRING "gcrypt|nss3")
if(NOT (${WITH_CRYPTO} EQUAL "nss3"))
	# gcrypt
	find_package(GCrypt)
else()
	# nss3
	find_package(NSS)
endif()
if(GCRYPT_FOUND OR NSS_FOUND)
	set(CRYPTO_FOUND TRUE)
endif()

check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
check_function_exists(posix_memalign HAVE_POSIX_MEMALIGN)
check_function_exists(memalign HAVE_MEMALIGN)
check_function_exists(fts_open HAVE_FTS_OPEN)
check_function_exists(strsep HAVE_STRSEP)
check_function_exists(strptime HAVE_STRPTIME)

check_include_file(syslog.h HAVE_SYSLOG_H)
check_include_file(stdio_ext.h HAVE_STDIO_EXT_H)
check_include_file(shadow.h HAVE_SHADOW_H)
check_include_file(sys/systeminfo.h HAVE_SYS_SYSTEMINFO_H)
check_include_file(getopt.h HAVE_GETOPT_H)
check_include_file(sys/uio.h HAVE_UIO_H)

# HAVE_ATOMIC_BUILTINS
check_c_source_compiles("#include <stdint.h>\nint main() {uint16_t foovar=0; uint16_t old=1; uint16_t new=2;__sync_bool_compare_and_swap(&foovar,old,new); return __sync_fetch_and_add(&foovar, 1); __sync_fetch_and_add(&foovar, 1);}" HAVE_ATOMIC_BUILTINS)
if(NOT HAVE_ATOMIC_BUILTINS)
	message(WARNING "!!! Compiler does not support atomic builtins. Atomic operation will be emulated using mutex-based locking. !!!")
endif()

mark_as_advanced(ENV_PRESENT VALGRIND_PRESENT)
find_program(ENV_PRESENT env)
find_program(VALGRIND_PRESENT valgrind)

# ---------- CORE FEATURE SWITCHES

option(ENABLE_CCE "enables support for Common Configuration Enumeration" FALSE)
option(ENABLE_SCE "enables Script Check Engine - an alternative checking engine that let's you use executables instead of OVAL for checks" FALSE)

# ---------- OVAL FEATURE SWITCHES

option(ENABLE_PROBES "build OVAL probes - each probe implements an OVAL test" TRUE)
set(SEAP_MSGID_BITS 32 CACHE STRING "Size of SEAP_msgid_t in bits [32|64]")
cmake_dependent_option(ENABLE_PROBES_INDEPENDENT "build OVAL probes for independent (cross platform) OVAL tests" ON "ENABLE_PROBES" OFF)
# On some platforms (Windows..) UNIX ends up being empty instead of "false"
set(IS_UNIX FALSE)
if (UNIX)
    set(IS_UNIX TRUE)
endif()
cmake_dependent_option(ENABLE_PROBES_UNIX "build OVAL probes for the UNIX OVAL tests" ${IS_UNIX} "ENABLE_PROBES" OFF)
string(COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "Linux" IS_LINUX)
cmake_dependent_option(ENABLE_PROBES_LINUX "build OVAL probes for the Linux OVAL tests" ${IS_LINUX} "ENABLE_PROBES" OFF)
string(COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "Solaris" IS_SOLARIS)
cmake_dependent_option(ENABLE_PROBES_SOLARIS "build OVAL probes for the Solaris OVAL tests" ${IS_SOLARIS} "ENABLE_PROBES" OFF)
set(IS_WIN32 FALSE)
if (WIN32)
    set(IS_WIN32 TRUE)
endif()
cmake_dependent_option(ENABLE_PROBES_WINDOWS "build OVAL probes for the Windows OVAL tests" ${IS_WIN32} "ENABLE_PROBES" OFF)

# INDEPENDENT PROBES
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE "Independent environmentvariable probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE58 "Independent environmentvariable58 probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_FAMILY "Independent family probe" ON "ENABLE_PROBES_INDEPENDENT" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_FILEHASH "Independent filehash probe" ON "ENABLE_PROBES_INDEPENDENT; CRYPTO_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_FILEHASH58 "Independent filehash58 probe" ON "ENABLE_PROBES_INDEPENDENT; CRYPTO_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_SQL "Independent sql probe" ON "ENABLE_PROBES_INDEPENDENT; OPENDBX_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_SQL57 "Independent sql57 probe" ON "ENABLE_PROBES_INDEPENDENT; OPENDBX_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_SYSTEM_INFO "Independent system info probe" ON "ENABLE_PROBES_INDEPENDENT" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_TEXTFILECONTENT "Independent textfilecontent probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_TEXTFILECONTENT54 "Independent textfilecontent54 probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_VARIABLE "Independent variable probe" ON "ENABLE_PROBES_INDEPENDENT" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_XMLFILECONTENT "Independent xmlfilecontent probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)

# UNIX PROBES
cmake_dependent_option(OPENSCAP_PROBE_UNIX_DNSCACHE "Unix dnscache probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_FILE "Unix file probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_FILEEXTENDEDATTRIBUTE "Unix fileextendedattribute probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_GCONF "Unix gconf probe" ON "ENABLE_PROBES_UNIX; GCONF_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_INTERFACE "Unix interface probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_PASSWORD "Unix password probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_PROCESS "Unix process probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_PROCESS58 "Unix process58 probe" ON "ENABLE_PROBES_UNIX; CAP_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_ROUTINGTABLE "Unix routingtable probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_RUNLEVEL "Unix runlevel probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_SHADOW "Unix shadow probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_SYMLINK "Unix symlink probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_SYSCTL "Unix sysctl probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_UNAME "Unix uname probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_XINETD "Unix xinetd probe" ON "ENABLE_PROBES_UNIX" OFF)

# LINUX PROBES
cmake_dependent_option(OPENSCAP_PROBE_LINUX_DPKGINFO "Linux dpkginfo probe" ON "ENABLE_PROBES_LINUX; APTPKG_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_IFLISTENERS "Linux iflisteners probe" ON "ENABLE_PROBES_LINUX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_INETLISTENINGSERVERS "Linux inetlisteningservers probe" ON "ENABLE_PROBES_LINUX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_PARTITION "Linux partition probe" ON "ENABLE_PROBES_LINUX; BLKID_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMINFO "Linux rpminfo probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMVERIFY "Linux rpmverify probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMVERIFYFILE "Linux rpmverifyfile probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMVERIFYPACKAGE "Linux rpmverifypackage probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SELINUXBOOLEAN "Linux selinuxboolean probe" ON "ENABLE_PROBES_LINUX; SELINUX_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SELINUXSECURITYCONTEXT "Linux selinuxsecuritycontext probe" ON "ENABLE_PROBES_LINUX; SELINUX_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SYSTEMDUNITDEPENDENCY "Linux systemdunitdependency probe" ON "ENABLE_PROBES_LINUX; DBUS_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SYSTEMDUNITPROPERTY "Linux systemdunitproperty probe" ON "ENABLE_PROBES_LINUX; DBUS_FOUND" OFF)

# SOLARIS PROBES
cmake_dependent_option(OPENSCAP_PROBE_SOLARIS_ISAINFO "Solaris isainfo probe" ON "ENABLE_PROBES_SOLARIS" OFF)

# WINDOWS PROBES
cmake_dependent_option(OPENSCAP_PROBE_WINDOWS_ACCESSTOKEN "Windows accesstoken probe" ON "ENABLE_PROBES_WINDOWS" OFF)
cmake_dependent_option(OPENSCAP_PROBE_WINDOWS_REGISTRY "Windows registry probe" ON "ENABLE_PROBES_WINDOWS" OFF)
cmake_dependent_option(OPENSCAP_PROBE_WINDOWS_WMI57 "Windows wmi57 probe" ON "ENABLE_PROBES_WINDOWS" OFF)


# ---------- EXECUTABLES / UTILITIES SWITCHES

option(ENABLE_OSCAP_UTIL "build the oscap utility, oscap is the core utility for evaluation and processing of SCAP data" TRUE)

set(OSCAP_DOCKER_PYTHON ${PYTHON_EXECUTABLE} CACHE STRING "path to the Python interpreter for oscap-docker")
cmake_dependent_option(ENABLE_OSCAP_UTIL_DOCKER "enables the oscap-docker utility, this let's you scan containers and container images" ON "NOT WIN32" OFF)
if(ENABLE_OSCAP_UTIL_DOCKER AND NOT BZIP2_FOUND)
	set(ENABLE_OSCAP_UTIL_DOCKER FALSE)
	message(SEND_ERROR "oscap-docker requires bzip2! Either disable oscap-docker or install bzip2")
endif()

cmake_dependent_option(ENABLE_OSCAP_UTIL_AS_RPM "enable the scap-as-rpm utility, this let's you package SCAP data as RPMs" ON "NOT WIN32" OFF)
cmake_dependent_option(ENABLE_OSCAP_UTIL_SSH "enables the oscap-ssh utility, this let's you scan remote machines over ssh" ON "NOT WIN32" OFF)
cmake_dependent_option(ENABLE_OSCAP_UTIL_VM "enables the oscap-vm utility, this let's you scan VMs and VM storage images" ON "NOT WIN32" OFF)
cmake_dependent_option(ENABLE_OSCAP_UTIL_CHROOT "enables the oscap-chroot utility, this let's you scan entire chroots using offline scanning" ON "NOT WIN32" OFF)

# ---------- TEST-SUITE SWITCHES

# Tests will be turned off on Windows, because the test suite uses bash
# and other Linux-specific tools.
if(WIN32)
	# TODO: I hate that the doc string is duplicated but cmake doesn't support evaluating expressions :-/
	option(ENABLE_TESTS "enables the test suite, use `ctest` to run it" FALSE)
else()
	option(ENABLE_TESTS "enables the test suite, use `ctest` to run it" TRUE)
endif()

option(ENABLE_VALGRIND "enables Valgrind memory testing in the test-suite" FALSE)

# ---------- LANGUAGE BINDINGS
cmake_dependent_option(ENABLE_PYTHON3 "if enabled, the python3 swig bindings will be built" ON "PYTHONINTERP_FOUND;SWIG_FOUND;PYTHONLIBS_FOUND" OFF)

# TODO: Shouldn't we only enable this if perl was found?
option(ENABLE_PERL "if enabled, the perl swig bindings will be built" FALSE)

# ---------- NO IDEA WHAT THIS IS FOR
set(WANT_BASE64 TRUE CACHE BOOL "wants builtin Base64")
set(WANT_XBASE64 FALSE CACHE BOOL "wants builtin XBase64")

# ---------- OTHERS
cmake_dependent_option(ENABLE_DOXYGEN_DOCS "if enabled, doxygen API reference documentation will be built" ON "DOXYGEN_FOUND" OFF)

# ---------- STATUS MESSAGES

message(STATUS " ")
message(STATUS "CMake:")
message(STATUS "generator: ${CMAKE_GENERATOR}")
message(STATUS "source directory: ${CMAKE_SOURCE_DIR}")
message(STATUS "build directory: ${CMAKE_BINARY_DIR}")
message(STATUS " ")
<commit_msg>Enable perl bindings if dependencies were found<commit_after>cmake_minimum_required(VERSION 2.6)

project("openscap")
set(OPENSCAP_VERSION_MAJOR "1")
set(OPENSCAP_VERSION_MINOR "3")
set(OPENSCAP_VERSION_PATCH "0")
set(OPENSCAP_VERSION "${OPENSCAP_VERSION_MAJOR}.${OPENSCAP_VERSION_MINOR}.${OPENSCAP_VERSION_PATCH}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")

message(STATUS "OpenSCAP ${OPENSCAP_VERSION}")
message(STATUS "(see ${CMAKE_SOURCE_DIR}/README.md for build instructions)")
message(STATUS " ")

# Strictly speaking in-source will work but will be very messy, let's
# discourage our users from using them
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
	message(FATAL_ERROR "In-source builds are not supported! Please use out of source builds:\n"
		"$ cd openscap\n"
		"$ rm CMakeCache.txt\n"
		"$ cd build\n"
		"$ cmake ../\n"
		"$ make -j4"
		)
endif()

# In Microsoft Visual Studio, store built binaries to a single directory.
# We need to build all the binaries in a single directory on Windows, because
# vcpkg tool fails to fetch dependent DLLs (libxml, libcurl, etc.) if
# oscap.exe is build to a different directory than openscap.dll.
# See the discussion in https://github.com/Microsoft/vcpkg/issues/1002
if(MSVC)
	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
	set(CMAKE_PDB_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()

# ---------- INCLUDES CMAKE MODULES

include(GNUInstallDirs)
include(FindPkgConfig)
include(CheckLibraryExists)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckCSourceCompiles)
include(CMakeDependentOption)

# ---------- DEPENDENCIES

find_package(ACL)
if(ACL_FOUND)
	check_library_exists(${ACL_LIBRARY} acl_extended_file "" HAVE_ACL_EXTENDED_FILE)
	check_include_file(acl/libacl.h HAVE_ACL_LIBACL_H)
	check_include_file(sys/acl.h HAVE_SYS_ACL_H)
endif()

find_package(AptPkg)

find_package(Blkid)
if(BLKID_FOUND)
	check_library_exists(blkid blkid_get_tag_value "" HAVE_BLKID_GET_TAG_VALUE)
endif()

find_package(Cap)
if(CAP_FOUND)
	check_library_exists(cap cap_get_pid "" HAVE_CAP_GET_PID)
endif()

find_package(CURL)
find_package(DBus)
find_package(Doxygen)
find_package(GConf)
find_package(Ldap)
find_package(OpenDbx)
find_package(PCRE REQUIRED)
find_package(PerlLibs)
find_package(Popt)

find_package(Procps)
if(PROCPS_FOUND)
	check_library_exists(procps dev_to_tty "" HAVE_DEV_TO_TTY)
	check_include_file(proc/devname.h HAVE_PROC_DEVNAME_H)
endif()

# According to CMake documentation:
# https://cmake.org/cmake/help/latest/module/FindPythonInterp.html
# If calling both find_package(PythonInterp) and find_package(PythonLibs),
# call find_package(PythonInterp) first to get the currently active Python
# version by default with a consistent version of PYTHON_LIBRARIES.
find_package(PythonInterp 3)
find_package(PythonLibs 3)

find_package(RPM)
if(RPM_FOUND)
	check_library_exists(rpm rpmReadConfigFiles "" HAVE_RPMREADCONFIGFILES)
	check_library_exists(rpm headerFormat "" HAVE_HEADERFORMAT)
	check_library_exists(rpmio rpmFreeCrypto "" HAVE_RPMFREECRYPTO)
	check_library_exists(rpm rpmFreeFilesystems "" HAVE_RPMFREEFILESYSTEMS)
	set(HAVE_RPMVERCMP 1)
endif()

find_package(SELinux)
find_package(SWIG)
find_package(LibXml2 REQUIRED)
find_package(LibXslt REQUIRED)
find_package(BZip2)

# PThread
set(CMAKE_THREAD_PREFER_PTHREAD)
set(THREADS_PREFER_PTHREAD_FLAG)
set(THREADS_USE_PTHREADS_WIN32 true)
find_package(Threads REQUIRED)
check_library_exists(pthread pthread_timedjoin_np "" HAVE_PTHREAD_TIMEDJOIN_NP)
check_library_exists(pthread pthread_setname_np "" HAVE_PTHREAD_SETNAME_NP)
check_library_exists(pthread pthread_getname_np "" HAVE_PTHREAD_GETNAME_NP)

# WITH_CRYPTO
set(WITH_CRYPTO "gcrypt" CACHE STRING "gcrypt|nss3")
if(NOT (${WITH_CRYPTO} EQUAL "nss3"))
	# gcrypt
	find_package(GCrypt)
else()
	# nss3
	find_package(NSS)
endif()
if(GCRYPT_FOUND OR NSS_FOUND)
	set(CRYPTO_FOUND TRUE)
endif()

check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
check_function_exists(posix_memalign HAVE_POSIX_MEMALIGN)
check_function_exists(memalign HAVE_MEMALIGN)
check_function_exists(fts_open HAVE_FTS_OPEN)
check_function_exists(strsep HAVE_STRSEP)
check_function_exists(strptime HAVE_STRPTIME)

check_include_file(syslog.h HAVE_SYSLOG_H)
check_include_file(stdio_ext.h HAVE_STDIO_EXT_H)
check_include_file(shadow.h HAVE_SHADOW_H)
check_include_file(sys/systeminfo.h HAVE_SYS_SYSTEMINFO_H)
check_include_file(getopt.h HAVE_GETOPT_H)
check_include_file(sys/uio.h HAVE_UIO_H)

# HAVE_ATOMIC_BUILTINS
check_c_source_compiles("#include <stdint.h>\nint main() {uint16_t foovar=0; uint16_t old=1; uint16_t new=2;__sync_bool_compare_and_swap(&foovar,old,new); return __sync_fetch_and_add(&foovar, 1); __sync_fetch_and_add(&foovar, 1);}" HAVE_ATOMIC_BUILTINS)
if(NOT HAVE_ATOMIC_BUILTINS)
	message(WARNING "!!! Compiler does not support atomic builtins. Atomic operation will be emulated using mutex-based locking. !!!")
endif()

mark_as_advanced(ENV_PRESENT VALGRIND_PRESENT)
find_program(ENV_PRESENT env)
find_program(VALGRIND_PRESENT valgrind)

# ---------- CORE FEATURE SWITCHES

option(ENABLE_CCE "enables support for Common Configuration Enumeration" FALSE)
option(ENABLE_SCE "enables Script Check Engine - an alternative checking engine that let's you use executables instead of OVAL for checks" FALSE)

# ---------- OVAL FEATURE SWITCHES

option(ENABLE_PROBES "build OVAL probes - each probe implements an OVAL test" TRUE)
set(SEAP_MSGID_BITS 32 CACHE STRING "Size of SEAP_msgid_t in bits [32|64]")
cmake_dependent_option(ENABLE_PROBES_INDEPENDENT "build OVAL probes for independent (cross platform) OVAL tests" ON "ENABLE_PROBES" OFF)
# On some platforms (Windows..) UNIX ends up being empty instead of "false"
set(IS_UNIX FALSE)
if (UNIX)
    set(IS_UNIX TRUE)
endif()
cmake_dependent_option(ENABLE_PROBES_UNIX "build OVAL probes for the UNIX OVAL tests" ${IS_UNIX} "ENABLE_PROBES" OFF)
string(COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "Linux" IS_LINUX)
cmake_dependent_option(ENABLE_PROBES_LINUX "build OVAL probes for the Linux OVAL tests" ${IS_LINUX} "ENABLE_PROBES" OFF)
string(COMPARE EQUAL ${CMAKE_SYSTEM_NAME} "Solaris" IS_SOLARIS)
cmake_dependent_option(ENABLE_PROBES_SOLARIS "build OVAL probes for the Solaris OVAL tests" ${IS_SOLARIS} "ENABLE_PROBES" OFF)
set(IS_WIN32 FALSE)
if (WIN32)
    set(IS_WIN32 TRUE)
endif()
cmake_dependent_option(ENABLE_PROBES_WINDOWS "build OVAL probes for the Windows OVAL tests" ${IS_WIN32} "ENABLE_PROBES" OFF)

# INDEPENDENT PROBES
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE "Independent environmentvariable probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_ENVIRONMENTVARIABLE58 "Independent environmentvariable58 probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_FAMILY "Independent family probe" ON "ENABLE_PROBES_INDEPENDENT" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_FILEHASH "Independent filehash probe" ON "ENABLE_PROBES_INDEPENDENT; CRYPTO_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_FILEHASH58 "Independent filehash58 probe" ON "ENABLE_PROBES_INDEPENDENT; CRYPTO_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_SQL "Independent sql probe" ON "ENABLE_PROBES_INDEPENDENT; OPENDBX_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_SQL57 "Independent sql57 probe" ON "ENABLE_PROBES_INDEPENDENT; OPENDBX_FOUND; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_SYSTEM_INFO "Independent system info probe" ON "ENABLE_PROBES_INDEPENDENT" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_TEXTFILECONTENT "Independent textfilecontent probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_TEXTFILECONTENT54 "Independent textfilecontent54 probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_VARIABLE "Independent variable probe" ON "ENABLE_PROBES_INDEPENDENT" OFF)
cmake_dependent_option(OPENSCAP_PROBE_INDEPENDENT_XMLFILECONTENT "Independent xmlfilecontent probe" ON "ENABLE_PROBES_INDEPENDENT; NOT WIN32" OFF)

# UNIX PROBES
cmake_dependent_option(OPENSCAP_PROBE_UNIX_DNSCACHE "Unix dnscache probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_FILE "Unix file probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_FILEEXTENDEDATTRIBUTE "Unix fileextendedattribute probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_GCONF "Unix gconf probe" ON "ENABLE_PROBES_UNIX; GCONF_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_INTERFACE "Unix interface probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_PASSWORD "Unix password probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_PROCESS "Unix process probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_PROCESS58 "Unix process58 probe" ON "ENABLE_PROBES_UNIX; CAP_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_ROUTINGTABLE "Unix routingtable probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_RUNLEVEL "Unix runlevel probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_SHADOW "Unix shadow probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_SYMLINK "Unix symlink probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_SYSCTL "Unix sysctl probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_UNAME "Unix uname probe" ON "ENABLE_PROBES_UNIX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_UNIX_XINETD "Unix xinetd probe" ON "ENABLE_PROBES_UNIX" OFF)

# LINUX PROBES
cmake_dependent_option(OPENSCAP_PROBE_LINUX_DPKGINFO "Linux dpkginfo probe" ON "ENABLE_PROBES_LINUX; APTPKG_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_IFLISTENERS "Linux iflisteners probe" ON "ENABLE_PROBES_LINUX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_INETLISTENINGSERVERS "Linux inetlisteningservers probe" ON "ENABLE_PROBES_LINUX" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_PARTITION "Linux partition probe" ON "ENABLE_PROBES_LINUX; BLKID_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMINFO "Linux rpminfo probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMVERIFY "Linux rpmverify probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMVERIFYFILE "Linux rpmverifyfile probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_RPMVERIFYPACKAGE "Linux rpmverifypackage probe" ON "ENABLE_PROBES_LINUX; RPM_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SELINUXBOOLEAN "Linux selinuxboolean probe" ON "ENABLE_PROBES_LINUX; SELINUX_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SELINUXSECURITYCONTEXT "Linux selinuxsecuritycontext probe" ON "ENABLE_PROBES_LINUX; SELINUX_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SYSTEMDUNITDEPENDENCY "Linux systemdunitdependency probe" ON "ENABLE_PROBES_LINUX; DBUS_FOUND" OFF)
cmake_dependent_option(OPENSCAP_PROBE_LINUX_SYSTEMDUNITPROPERTY "Linux systemdunitproperty probe" ON "ENABLE_PROBES_LINUX; DBUS_FOUND" OFF)

# SOLARIS PROBES
cmake_dependent_option(OPENSCAP_PROBE_SOLARIS_ISAINFO "Solaris isainfo probe" ON "ENABLE_PROBES_SOLARIS" OFF)

# WINDOWS PROBES
cmake_dependent_option(OPENSCAP_PROBE_WINDOWS_ACCESSTOKEN "Windows accesstoken probe" ON "ENABLE_PROBES_WINDOWS" OFF)
cmake_dependent_option(OPENSCAP_PROBE_WINDOWS_REGISTRY "Windows registry probe" ON "ENABLE_PROBES_WINDOWS" OFF)
cmake_dependent_option(OPENSCAP_PROBE_WINDOWS_WMI57 "Windows wmi57 probe" ON "ENABLE_PROBES_WINDOWS" OFF)


# ---------- EXECUTABLES / UTILITIES SWITCHES

option(ENABLE_OSCAP_UTIL "build the oscap utility, oscap is the core utility for evaluation and processing of SCAP data" TRUE)

set(OSCAP_DOCKER_PYTHON ${PYTHON_EXECUTABLE} CACHE STRING "path to the Python interpreter for oscap-docker")
cmake_dependent_option(ENABLE_OSCAP_UTIL_DOCKER "enables the oscap-docker utility, this let's you scan containers and container images" ON "NOT WIN32" OFF)
if(ENABLE_OSCAP_UTIL_DOCKER AND NOT BZIP2_FOUND)
	set(ENABLE_OSCAP_UTIL_DOCKER FALSE)
	message(SEND_ERROR "oscap-docker requires bzip2! Either disable oscap-docker or install bzip2")
endif()

cmake_dependent_option(ENABLE_OSCAP_UTIL_AS_RPM "enable the scap-as-rpm utility, this let's you package SCAP data as RPMs" ON "NOT WIN32" OFF)
cmake_dependent_option(ENABLE_OSCAP_UTIL_SSH "enables the oscap-ssh utility, this let's you scan remote machines over ssh" ON "NOT WIN32" OFF)
cmake_dependent_option(ENABLE_OSCAP_UTIL_VM "enables the oscap-vm utility, this let's you scan VMs and VM storage images" ON "NOT WIN32" OFF)
cmake_dependent_option(ENABLE_OSCAP_UTIL_CHROOT "enables the oscap-chroot utility, this let's you scan entire chroots using offline scanning" ON "NOT WIN32" OFF)

# ---------- TEST-SUITE SWITCHES

# Tests will be turned off on Windows, because the test suite uses bash
# and other Linux-specific tools.
if(WIN32)
	# TODO: I hate that the doc string is duplicated but cmake doesn't support evaluating expressions :-/
	option(ENABLE_TESTS "enables the test suite, use `ctest` to run it" FALSE)
else()
	option(ENABLE_TESTS "enables the test suite, use `ctest` to run it" TRUE)
endif()

option(ENABLE_VALGRIND "enables Valgrind memory testing in the test-suite" FALSE)

# ---------- LANGUAGE BINDINGS
cmake_dependent_option(ENABLE_PYTHON3 "if enabled, the python3 swig bindings will be built" ON "PYTHONINTERP_FOUND;SWIG_FOUND;PYTHONLIBS_FOUND" OFF)
cmake_dependent_option(ENABLE_PERL "if enabled, the perl swig bindings will be built" ON "PERLLIBS_FOUND;SWIG_FOUND" OFF)

# ---------- NO IDEA WHAT THIS IS FOR
set(WANT_BASE64 TRUE CACHE BOOL "wants builtin Base64")
set(WANT_XBASE64 FALSE CACHE BOOL "wants builtin XBase64")

# ---------- OTHERS
cmake_dependent_option(ENABLE_DOXYGEN_DOCS "if enabled, doxygen API reference documentation will be built" ON "DOXYGEN_FOUND" OFF)

# ---------- STATUS MESSAGES

message(STATUS " ")
message(STATUS "CMake:")
message(STATUS "generator: ${CMAKE_GENERATOR}")
message(STATUS "source directory: ${CMAKE_SOURCE_DIR}")
message(STATUS "build directory: ${CMAKE_BINARY_DIR}")
message(STATUS " ")

{'fraction_non_alphanumeric': 0.07878580003429943, 'fraction_numerical': 0.007683073229291717, 'mean_word_length': 8.866666666666667, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6835514', 'n_tokens_mistral': 11103, 'n_tokens_neox': 10636, 'n_words': 2256}