diff --git a/CMakeLists.txt b/CMakeLists.txt index 99d70d0c326..78b47764a3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,12 @@ endif (UNIX) # many are core-specific +# whether this build of DynamoRIO is meant for distribution, in which case +# glibc should not have any too-recent imports. See core/CMake_readelf.cmake +# for more information. This is off by default, but gets set by +# make/package.cmake. +option(BUILD_PACKAGE "build DynamoRIO for packaging purposes by performing glibc checks" OFF) + # configurations that also have defines option(DRSTATS_DEMO "build DRstats without the no-longer-supported Run, etc. controls" ON) diff --git a/api/docs/release.dox b/api/docs/release.dox index 427a2221214..68e7b134ce1 100644 --- a/api/docs/release.dox +++ b/api/docs/release.dox @@ -126,7 +126,11 @@ clients. The changes between version \DR_VERSION and 9.0.0 include the following compatibility changes: - - (Nothing so far: this is a placeholder.) + - Introduced a new CMake option called BUILD_PACKAGE to skip glibc + compatibility checks. This is off by default such that building DynamoRIO + from source is straight-forward to do on rolling release Linux + distributions, and enabled by make/package.cmake when building a + distributable version of DynamoRIO. Further non-compatibility-affecting changes include: - Added alias support to droption. diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 281869b4695..4bf1c95a882 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -661,7 +661,7 @@ if (UNIX) ARGS -D lib_fileloc=${CMAKE_CURRENT_BINARY_DIR}/${locvar_name} -D check_textrel=${check_textrel} -D check_deps=${check_deps} - -D check_libc=OFF + -D check_libc=${BUILD_PACKAGE} -D check_interp=ON -D READELF_EXECUTABLE=${READELF_EXECUTABLE} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake_readelf.cmake @@ -931,7 +931,7 @@ if (UNIX) ARGS -D lib_fileloc=${CMAKE_CURRENT_BINARY_DIR}/${locvar_name} -D check_textrel=ON -D check_deps=OFF - -D check_libc=ON + -D check_libc=${BUILD_PACKAGE} -D check_interp=ON -D READELF_EXECUTABLE=${READELF_EXECUTABLE} -P ${CMAKE_CURRENT_SOURCE_DIR}/CMake_readelf.cmake diff --git a/core/CMake_readelf.cmake b/core/CMake_readelf.cmake index 7db2d6fe89e..73976194167 100644 --- a/core/CMake_readelf.cmake +++ b/core/CMake_readelf.cmake @@ -127,23 +127,42 @@ if (check_libc) if (readelf_result OR readelf_error) message(FATAL_ERROR "*** ${READELF_EXECUTABLE} failed: ***\n${readelf_error}") endif (readelf_result OR readelf_error) - # Avoid dependences beyond glibc 2.4 (2.17 on AArch64) for maximum backward + + # Avoid dependences beyond the oldest well-supported version of glibc for maximum backward # portability without going to extremes with a fixed toolchain (xref i#1504): execute_process(COMMAND ${READELF_EXECUTABLE} -h ${${lib_file}} OUTPUT_VARIABLE file_header_result ) - if (file_header_result MATCHES "AArch64") - set (glibc_version_regexp "2\\.(1[8-9]|[2-9][0-9])") - else () - set (glibc_version_regexp "2\\.([5-9]|[1-9][0-9])") - endif () - string(REGEX MATCH " GLOBAL [ A-Z]* UND [^\n]*@GLIBC_${glibc_version_regexp}" - has_recent "${string}") - if (has_recent) - string(REGEX MATCH " GLOBAL DEFAULT UND [^\n]*@GLIBC_${glibc_version_regexp}[^\n]*\n" - symname "${string}") - message(FATAL_ERROR "*** Error: ${${lib_file}} has too-recent import: ${symname}") + + # To determine the minimum version of glibc that we should support for packaging, we should + # check the Linux distributions that are known not to be rolling releases and offer long + # support, and then check the oldest option available that is not yet EOL. As of writing, + # these are: + # * Debian Stretch, which is on glibc 2.24 + # * CentOS 7/RHEL 7, which is on glibc 2.17 + # * Ubuntu 16.04 LTS (Xenial), which is on glibc 2.23 + # + # Therefore, we want to support at least glibc 2.17. + # + # The glibc version is independent of the architecture. For instance, RHEL 7 for AArch64 also + # ships glibc 2.17 as of writing. + set (glibc_version "2.17") + + set (glibc_version_regexp " GLOBAL [ A-Z]* UND [^\n]*@GLIBC_([0-9]+\\.[0-9]+)") + string(REGEX MATCHALL "${glibc_version_regexp}" imports "${string}") + + foreach (import ${imports}) + string(REGEX MATCH "${glibc_version_regexp}" match "${import}") + set(version ${CMAKE_MATCH_1}) + + if (${version} VERSION_GREATER ${glibc_version}) + set(too_recent "${too_recent}\n ${import}") + endif () + endforeach () + + if (too_recent) + message(FATAL_ERROR "*** Error: ${${lib_file}} has too-recent import(s):${too_recent}") endif () endif () diff --git a/make/package.cmake b/make/package.cmake index 54e686c3d9e..60c2debd621 100644 --- a/make/package.cmake +++ b/make/package.cmake @@ -163,6 +163,7 @@ set(base_cache " ${base_cache} BUILD_NUMBER:STRING=${arg_build} UNIQUE_BUILD_NUMBER:STRING=${arg_ubuild} + BUILD_PACKAGE:BOOL=ON ${arg_cacheappend} ") diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 4d7e0fa97c5..2748e1be702 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -198,7 +198,7 @@ foreach (deploytgt drconfig drrun drinject) ARGS -D lib_fileloc=${CMAKE_CURRENT_BINARY_DIR}/${locvar_name} -D check_textrel=ON -D check_deps=OFF - -D check_libc=ON + -D check_libc=${BUILD_PACKAGE} -D READELF_EXECUTABLE=${READELF_EXECUTABLE} -P ${PROJECT_SOURCE_DIR}/core/CMake_readelf.cmake VERBATIM # recommended: p260