rpm/CMakeLists.txt

511 lines
14 KiB
CMake

cmake_minimum_required(VERSION 3.18)
project(rpm
VERSION 4.19.90
DESCRIPTION "The RPM Package Manager"
HOMEPAGE_URL "http://rpm.org"
LANGUAGES C
)
# user configurable stuff
option(ENABLE_NLS "Enable native language support" ON)
option(ENABLE_OPENMP "Enable OpenMP threading support" ON)
option(ENABLE_PYTHON "Enable Python bindings" ON)
option(ENABLE_PLUGINS "Enable plugin support" ON)
option(ENABLE_WERROR "Stop build on warnings" OFF)
option(ENABLE_SQLITE "Enable sqlite rpmdb support" ON)
option(ENABLE_NDB "Enable ndb rpmdb support" ON)
option(ENABLE_BDB_RO "Enable read-only Berkeley DB rpmdb support (EXPERIMENTAL)" OFF)
option(ENABLE_TESTSUITE "Enable test-suite" ON)
option(WITH_INTERNAL_OPENPGP "Use internal OpenPGP parse (DEPRECATED)" OFF)
option(WITH_OPENSSL "Use openssl (instead of libgcrypt) for internal crypto" OFF)
option(WITH_CAP "Build with capability support" ON)
option(WITH_ACL "Build with ACL support" ON)
option(WITH_ARCHIVE "Build with libarchive support" ON)
option(WITH_SELINUX "Build with SELinux support" ON)
option(WITH_DBUS "Build with DBUS support" ON)
option(WITH_AUDIT "Build with audit support" ON)
option(WITH_FSVERITY "Build with fsverity support" OFF)
option(WITH_IMAEVM "Build with IMA support" OFF)
option(WITH_FAPOLICYD "Build with fapolicyd support" ON)
set(RPM_CONFIGDIR "${CMAKE_INSTALL_PREFIX}/lib/rpm" CACHE PATH "rpm home")
set(RPM_VENDOR "vendor" CACHE STRING "rpm vendor string")
# Emulate libtool versioning. Before a public release:
# - increment micro version whenever there are code changes
# - increment minor version whenever there are added interfaces
# - increment major version whenever there are removed interfaces
# - incrementing a more significant version segment resets changes to
# any less significant segments
set(RPM_SOVERSION 10)
set(RPM_LIBVERSION ${RPM_SOVERSION}.0.0)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(CMAKE_SHARED_MODULE_PREFIX "")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(GNUInstallDirs)
add_compile_definitions(_GNU_SOURCE)
add_definitions(-D_FILE_OFFSET_BITS=64)
function(findutil UTIL TRY)
list(GET TRY 0 util)
find_program(${UTIL}
NAMES ${TRY}
PATHS ENV MYPATH
PATHS /usr/local/bin /usr/bin /bin
PATHS /usr/local/sbin /usr/sbin /sbin
NO_DEFAULT_PATH
)
if (NOT ${UTIL})
list(GET TRY 0 util)
message(DEBUG "${util} not found, assuming /usr/bin/${util}")
set(${UTIL} /usr/bin/${util} PARENT_SCOPE)
endif()
endfunction()
function(makemacros)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
set(bindir "\${exec_prefix}/${CMAKE_INSTALL_BINDIR}")
set(sbindir "\${exec_prefix}/${CMAKE_INSTALL_SBINDIR}")
set(libexecdir "\${exec_prefix}/${CMAKE_INSTALL_LIBEXECDIR}")
set(datarootdir "\${prefix}/${CMAKE_INSTALL_DATAROOTDIR}")
set(datadir "\${datarootdir}")
set(sysconfdir "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
set(sharedstatedir "${CMAKE_INSTALL_FULL_SHAREDSTATEDIR}")
set(localstatedir "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}")
set(libdir "\${prefix}/=LIB=")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
set(oldincludedir "${CMAKE_INSTALL_FULL_OLDINCLUDEDIR}")
set(infodir "\${prefix}/${CMAKE_INSTALL_INFODIR}")
set(mandir "\${prefix}/${CMAKE_INSTALL_MANDIR}")
set(rundir /run)
set(root_prefix /usr)
findutil(__7ZIP 7zip)
findutil(__BZIP2 bzip2)
findutil(__CAT cat)
findutil(__CHMOD chmod)
findutil(__CHOWN chown)
findutil(__CP cp)
findutil(__CURL curl)
findutil(__FILE file)
findutil(__GPG gpg)
findutil(__GREP grep)
findutil(__GZIP gzip)
findutil(__ID id)
findutil(__CC cc)
findutil(__LN ln)
findutil(__INSTALL install)
findutil(__LRZIP lrzip)
findutil(__LZIP lzip)
findutil(__XZ xz)
findutil(__MAKE make)
findutil(__MKDIR mkdir)
findutil(__MV mv)
findutil(__PATCH patch)
findutil(__RM rm)
findutil(__SED sed)
findutil(__TAR tar)
findutil(__UNZIP unzip)
findutil(__ZSTD zstd)
findutil(__GEM gem)
findutil(__GIT git)
findutil(__HG hg)
findutil(__BZR bzr)
findutil(__QUILT quilt)
findutil(__LD ld)
findutil(__OBJDUMP objdump)
findutil(__STRIP strip)
findutil(__SYSTEMD_SYSUSERS systemd-sysusers)
findutil(__AWK awk)
findutil(__AR ar)
findutil(__AS as)
findutil(__CPP cpp)
findutil(__CXX c++)
list(GET db_backends 0 DB_BACKEND)
set(host_cpu ${CMAKE_HOST_SYSTEM_PROCESSOR})
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} host_os)
set(host_vendor ${RPM_VENDOR})
set(host ${host_cpu}-${host_vendor}-${host_os})
set(RPMCANONVENDOR ${host_vendor})
set(RPMCANONOS ${host_os})
set(RPMCANONGNU -gnu)
configure_file(platform.in platform @ONLY)
configure_file(rpmrc.in rpmrc @ONLY)
configure_file(macros.in macros @ONLY)
configure_file(rpmpopt.in rpmpopt-${PROJECT_VERSION} @ONLY)
configure_file(rpm.pc.in rpm.pc @ONLY)
install(CODE "execute_process(COMMAND
${CMAKE_COMMAND} -E env pkglibdir=${RPM_CONFIGDIR}
${CMAKE_SOURCE_DIR}/installplatform
rpmrc platform macros
${RPMCANONVENDOR} ${RPMCANONOS} ${RPMCANONGNU})"
)
endfunction()
include(CheckLibraryExists)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckCCompilerFlag)
set(OPTFUNCS
stpcpy stpncpy putenv mempcpy fdatasync lutimes mergesort
getauxval setprogname __progname syncfs sched_getaffinity unshare
secure_getenv __secure_getenv mremap
)
set(REQFUNCS
mkstemp getcwd basename dirname realpath setenv unsetenv regcomp
utimes getline localtime_r statvfs getaddrinfo
openat mkdirat fstatat linkat symlinkat mkfifoat mknodat unlinkat
renameat utimensat fchmodat fchownat stpcpy stpncpy
)
find_package(PkgConfig REQUIRED)
find_package(Lua 5.2 REQUIRED)
find_package(ZLIB REQUIRED)
find_package(BZip2)
find_package(Iconv)
pkg_check_modules(POPT REQUIRED IMPORTED_TARGET popt)
pkg_check_modules(READLINE IMPORTED_TARGET readline)
pkg_check_modules(ZSTD IMPORTED_TARGET libzstd>=1.3.8)
pkg_check_modules(LIBELF IMPORTED_TARGET libelf)
pkg_check_modules(LIBDW IMPORTED_TARGET libdw)
pkg_check_modules(LIBLZMA IMPORTED_TARGET liblzma>=5.2.0)
# Lua module does not ship an IMPORTED target, define our own
add_library(LUA::LUA INTERFACE IMPORTED)
set_target_properties(LUA::LUA PROPERTIES
INTERFACE_LINK_LIBRARIES "${LUA_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}")
# file >= 5.39 ships a pkg-config, may move to that later
add_library(MAGIC::MAGIC UNKNOWN IMPORTED)
find_library(MAGIC_LIBRARY NAMES magic REQUIRED)
find_path(MAGIC_INCLUDE_DIR NAMES magic.h REQUIRED)
set_target_properties(MAGIC::MAGIC PROPERTIES
IMPORTED_LOCATION "${MAGIC_LIBRARY}")
target_include_directories(MAGIC::MAGIC INTERFACE "${MAGIC_INCLUDE_DIR}")
if (ENABLE_OPENMP)
find_package(OpenMP 4.5 REQUIRED)
endif()
if (ENABLE_NLS)
find_package(Intl REQUIRED)
endif()
if (ENABLE_SQLITE)
pkg_check_modules(SQLITE REQUIRED IMPORTED_TARGET sqlite3>=3.22)
list(APPEND db_backends sqlite)
endif()
if (ENABLE_NDB)
list(APPEND db_backends ndb)
endif()
if (ENABLE_BDB_RO)
list(APPEND db_backends bdb_ro)
endif()
list(APPEND db_backends dummy)
if (ENABLE_PYTHON)
find_package(Python3 3.2 COMPONENTS Interpreter Development REQUIRED)
endif()
if (WITH_CAP)
pkg_check_modules(LIBCAP REQUIRED IMPORTED_TARGET libcap)
endif()
if (WITH_ACL)
pkg_check_modules(LIBACL REQUIRED IMPORTED_TARGET libacl)
endif()
if (WITH_AUDIT)
pkg_check_modules(AUDIT REQUIRED IMPORTED_TARGET audit)
endif()
if (WITH_SELINUX)
pkg_check_modules(SELINUX REQUIRED IMPORTED_TARGET libselinux)
endif()
if (WITH_ARCHIVE)
pkg_check_modules(LIBARCHIVE REQUIRED IMPORTED_TARGET libarchive)
endif()
if (WITH_FSVERITY)
pkg_check_modules(FSVERITY REQUIRED IMPORTED_TARGET libfsverity)
endif()
if (WITH_IMAEVM)
list(APPEND REQFUNCS lsetxattr)
add_library(IMA::IMA UNKNOWN IMPORTED)
find_path(IMA_INCLUDE_DIR NAMES imaevm.h REQUIRED)
find_library(IMA_LIBRARY NAMES imaevm REQUIRED)
set_target_properties(IMA::IMA PROPERTIES
IMPORTED_LOCATION "${IMA_LIBRARY}")
target_include_directories(IMA::IMA INTERFACE "${IMA_INCLUDE_DIR}")
endif()
find_program(__FIND_DEBUGINFO find-debuginfo)
function(chkdef func req)
string(TOUPPER ${func} FUNC)
set(HAVENAME HAVE_${FUNC})
check_function_exists(${func} ${HAVENAME})
if (${req} AND NOT ${HAVENAME})
message(FATAL_ERROR "required function ${func} not found")
endif()
endfunction()
foreach(f ${OPTFUNCS})
chkdef(${f} FALSE)
endforeach()
foreach(f ${REQFUNCS})
chkdef(${f} TRUE)
endforeach()
function(chkhdr inc req)
string(MAKE_C_IDENTIFIER ${inc} ID)
string(TOUPPER ${ID} INC)
set(HAVENAME HAVE_${INC})
check_include_file(${inc} ${HAVENAME})
if (${req} AND NOT ${HAVENAME})
message(FATAL_ERROR "required include ${inc} not found")
endif()
endfunction()
set(OPTINCS
unistd.h limits.h getopt.h
sys/utsname.h sys/systemcfg.h sys/param.h sys/auxv.h
)
foreach(f ${OPTINCS})
chkhdr(${f} FALSE)
endforeach()
function(id0name var file)
execute_process(COMMAND awk -F: "$3==0 {print $1;exit}" ${file}
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE name)
if ("${name}" STREQUAL "")
set(name root)
endif()
set(${var} ${name} PARENT_SCOPE)
endfunction()
id0name(UID_0_USER /etc/passwd)
id0name(GID_0_GROUP /etc/group)
# map module/package findings to config.h
if (BZIP2_FOUND)
set(HAVE_BZLIB_H 1)
endif()
if (LIBLZMA_FOUND)
set(HAVE_LZMA_H 1)
endif()
if (Iconv_FOUND)
set(HAVE_ICONV 1)
endif()
if (ZSTD_FOUND)
set(HAVE_ZSTD 1)
endif()
if (READLINE_FOUND)
set(HAVE_READLINE 1)
endif()
if (LIBELF_FOUND)
set(HAVE_LIBELF 1)
endif()
if (LIBDW_FOUND)
set(HAVE_LIBDW 1)
endif()
check_symbol_exists(major "sys/sysmacros.h" MAJOR_IN_SYSMACROS)
if (NOT MAJOR_IN_SYSMACROS)
check_symbol_exists(major "sys/mkdev.h" MAJOR_IN_MKDEV)
endif()
configure_file(config.h.in config.h)
add_compile_definitions(HAVE_CONFIG_H)
add_compile_options(-Wall -Wpointer-arith -Wmissing-prototypes -Wstrict-prototypes -Wempty-body)
if (ENABLE_WERROR)
add_compile_options(-Werror)
endif()
# try to ensure some compiler sanity
foreach (flag -fno-strict-overflow -fno-delete-null-pointer-checks)
check_c_compiler_flag(${flag} found)
if (found)
add_compile_options(${flag})
endif()
unset(found)
endforeach()
include_directories(${CMAKE_BINARY_DIR})
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include)
add_subdirectory(docs)
add_subdirectory(include/rpm)
add_subdirectory(misc)
add_subdirectory(rpmio)
add_subdirectory(lib)
add_subdirectory(build)
add_subdirectory(sign)
if (EXISTS ${CMAKE_SOURCE_DIR}/po/rpm.pot)
add_subdirectory(po)
endif()
if (ENABLE_PYTHON)
add_subdirectory(python)
endif()
if (ENABLE_PLUGINS)
add_subdirectory(plugins)
endif()
add_subdirectory(fileattrs)
add_subdirectory(scripts)
add_library(cliutils OBJECT cliutils.c cliutils.h)
add_executable(rpm rpm.c cliutils)
add_executable(rpmdb rpmdb.c cliutils)
add_executable(rpmkeys rpmkeys.c cliutils)
add_executable(rpm2cpio rpm2cpio.c cliutils)
add_executable(rpmsign rpmsign.c cliutils)
add_executable(rpmbuild rpmbuild.c cliutils)
add_executable(rpmspec rpmspec.c cliutils)
add_executable(rpmdeps tools/rpmdeps.c)
add_executable(rpmgraph tools/rpmgraph.c)
add_executable(rpmlua tools/rpmlua.c)
add_executable(rpmsort tools/rpmsort.c)
add_executable(rpmuncompress tools/rpmuncompress.c)
add_executable(elfdeps tools/elfdeps.c)
target_link_libraries(rpmsign PRIVATE librpmsign)
target_link_libraries(rpmlua PRIVATE LUA::LUA)
target_link_libraries(elfdeps PRIVATE PkgConfig::LIBELF)
target_link_libraries(rpmbuild PRIVATE librpmbuild)
target_link_libraries(rpmspec PRIVATE librpmbuild)
target_link_libraries(rpmdeps PRIVATE librpmbuild)
if (READLINE_FOUND)
target_link_libraries(rpmspec PRIVATE PkgConfig::READLINE)
target_link_libraries(rpmlua PRIVATE PkgConfig::READLINE)
endif()
if (WITH_ARCHIVE)
add_executable(rpm2archive rpm2archive.c)
target_link_libraries(rpm2archive PRIVATE PkgConfig::LIBARCHIVE)
install(TARGETS rpm2archive)
endif()
# Everything links to these
get_property(executables DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
foreach(exe ${executables})
target_link_libraries(${exe} PRIVATE librpmio librpm PkgConfig::POPT)
endforeach()
foreach(cmd rpmverify rpmquery)
add_custom_target(${cmd} ALL COMMAND
${CMAKE_COMMAND} -E create_symlink rpm ${cmd}
BYPRODUCTS ${cmd})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${cmd} TYPE BIN)
endforeach()
install(TARGETS
rpm rpmdb rpmkeys rpm2cpio rpmsign rpmbuild rpmspec
rpmlua rpmgraph rpmsort
)
install(TARGETS elfdeps rpmdeps rpmuncompress DESTINATION ${RPM_CONFIGDIR})
makemacros()
foreach(f macros rpmrc rpmpopt-${PROJECT_VERSION})
install(FILES ${CMAKE_BINARY_DIR}/${f} DESTINATION ${RPM_CONFIGDIR})
endforeach()
if (ENABLE_TESTSUITE)
add_subdirectory(tests)
endif()
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/rpm.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
install(DIRECTORY DESTINATION ${RPM_CONFIGDIR}/lua)
install(DIRECTORY DESTINATION ${RPM_CONFIGDIR}/macros.d)
install(FILES CONTRIBUTING.md COPYING CREDITS INSTALL README TYPE DOC)
add_custom_target(ChangeLog
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND git log --no-merges
--output=${CMAKE_BINARY_DIR}/ChangeLog
)
add_custom_command(OUTPUT po/rpm.pot
COMMAND git submodule update --init)
function(add_tarball targetname namever treeish)
set(distfmt tar)
set(tarname ${namever}.${distfmt})
set(distname ${tarname}.bz2)
set(docname ${namever}-doc.${distfmt})
add_custom_target(${docname}
DEPENDS man apidoc
COMMAND tar
-C ${CMAKE_BINARY_DIR}
--transform 's:^:${namever}/:'
-cf ${docname} docs/man/*.[1-8] docs/html/
)
add_custom_target(${distname}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
BYPRODUCTS ${distname} ${docname}
VERBATIM
DEPENDS ChangeLog ${docname} po/rpm.pot
COMMAND git archive
--format=${distfmt}
--output=${CMAKE_BINARY_DIR}/${tarname}
--prefix=${namever}/
--add-file=${CMAKE_BINARY_DIR}/ChangeLog
${treeish}
COMMAND git submodule foreach --quiet
"git archive --prefix=${namever}/$sm_path/ \
--output=${CMAKE_BINARY_DIR}/$sha1.tar HEAD \
&& tar --concatenate \
--file=${CMAKE_BINARY_DIR}/${tarname} \
${CMAKE_BINARY_DIR}/$sha1.tar \
&& rm -f ${CMAKE_BINARY_DIR}/$sha1.tar"
COMMAND tar --concatenate
--file=${CMAKE_BINARY_DIR}/${tarname}
${CMAKE_BINARY_DIR}/${docname}
COMMAND bzip2 -f ${CMAKE_BINARY_DIR}/${tarname}
)
add_custom_target(${targetname} DEPENDS ${distname})
endfunction()
add_tarball(dist ${PROJECT_NAME}-${PROJECT_VERSION} HEAD)
if (EXISTS ${CMAKE_SOURCE_DIR}/.git)
execute_process(COMMAND git rev-list --count HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE gitcount
OUTPUT_STRIP_TRAILING_WHITESPACE)
add_tarball(snapshot
${PROJECT_NAME}-${PROJECT_VERSION}-git${gitcount} HEAD)
endif()