diff options
-rw-r--r-- | CMakeLists.txt | 30 | ||||
-rwxr-xr-x | scripts/invoke-with-relative-paths.pl | 95 |
2 files changed, 125 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ba5e60f6146..154273576d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -263,6 +263,36 @@ IF (ENABLE_GCOV AND NOT WIN32 AND NOT APPLE) SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-arcs -ftest-coverage -lgcov") ENDIF() +IF(CMAKE_SYSTEM_NAME MATCHES "Linux") + OPTION(REPRODUCIBLE_BUILD "Take extra pains to make build result independent of build location and time" OFF) +ENDIF() +IF(REPRODUCIBLE_BUILD) + SET(DEBUG_PREFIX_FLAGS + "-fdebug-prefix-map=${CMAKE_SOURCE_DIR}/=./ -fdebug-prefix-map=${CMAKE_CURRENT_BINARY_DIR}=./obj") + + # See if -fdebug-prefix= commands are included in the debug output, + # making the build unreproducible with switches recorded. + # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69821. + EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -g3 -x c -S -fdebug-prefix-map=foo=bar -o - - + INPUT_FILE /dev/null OUTPUT_VARIABLE DEBUG_PREFIX_MAP_RESULT) + IF(DEBUG_PREFIX_MAP_RESULT MATCHES "foo=bar") + SET(DEBUG_PREFIX_FLAGS "${DEBUG_PREFIX_FLAGS} -gno-record-gcc-switches") + ENDIF() + + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${DEBUG_PREFIX_FLAGS}") + SET(CMAKE_C_FLAGS_RELWITHDEBINFO + "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${DEBUG_PREFIX_FLAGS}") + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_PREFIX_FLAGS}") + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${DEBUG_PREFIX_FLAGS}") + + SET(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--build-id=none") + SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--build-id=none") + + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE + "${CMAKE_SOURCE_DIR}/scripts/invoke-with-relative-paths.pl") +ENDIF() + OPTION(ENABLED_LOCAL_INFILE "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) MARK_AS_ADVANCED(ENABLED_LOCAL_INFILE) diff --git a/scripts/invoke-with-relative-paths.pl b/scripts/invoke-with-relative-paths.pl new file mode 100755 index 00000000000..97480330b7f --- /dev/null +++ b/scripts/invoke-with-relative-paths.pl @@ -0,0 +1,95 @@ +#! /usr/bin/perl +# +# Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA +# + +# +# Take the given GCC command line and run it with all absolute paths +# changed to relative paths. This makes sure that no part of the build +# path leaks into the .o files, which it normally would through the +# contents of __FILE__. (Debug information is also affected, but that +# is already fixed through -fdebug-prefix-map=.) +# +# A more elegant solution would be -ffile-prefix-map=, but this is +# not currently supported in GCC; see +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70268. +# + +use strict; +use warnings; +use Cwd; + +my $cwd = getcwd(); + +my @newarg = (); +for my $i (0..$#ARGV) { + my $arg = $ARGV[$i]; + if ($arg =~ /-I(.+)$/) { + $arg = '-I' . relativize($1, $cwd); + } elsif ($arg =~ /^\//) { + $arg = relativize($arg, $cwd); + } + push @newarg, $arg; +} + +exec(@newarg); + +# /a/b/c/foo from /a/b/d = ../c/foo +sub relativize { + my ($dir1, $dir2) = @_; + + if ($dir1 !~ /^\//) { + # Not an absolute path. + return $dir1; + } + + if (! -e $dir1) { +# print STDERR "Unknown file/directory $dir1.\n"; + return $dir1; + } + # Resolve symlinks and such, because getcwd() does. + $dir1 = Cwd::abs_path($dir1); + + if ($dir1 =~ /^\/(lib|tmp|usr)/) { + # Not related to our source code. + return $dir1; + } + + if ($dir1 eq $dir2) { + return "."; + } + + my (@dir1_components) = split /\//, $dir1; + my (@dir2_components) = split /\//, $dir2; + + # Remove common leading components. + while (scalar @dir1_components > 0 && scalar @dir2_components > 0 && + $dir1_components[0] eq $dir2_components[0]) { + shift @dir1_components; + shift @dir2_components; + } + + my $ret = ""; + for my $i (0..$#dir2_components) { + $ret .= '../'; + } + $ret .= join('/', @dir1_components); + + # print STDERR "[$dir1] from [$dir2] => [$ret]\n"; + + return $ret; +} + |