Compile everything with -fPIE instead of -fPIC

Everything we build is linked into the position-independent executable, so
-fPIE is the right code model: -fPIC only adds symbol interposition (GOT
loads, TLS descriptor sequences) that an executable never uses. Instead of
putting -fPIE back on the three C++ runtime targets, the global flag is now
-fPIE, set where #125094 put it, before the default_libs include. The
objects stay relocatable, so builds with compilers that do not default to
PIE keep working.

Also drop the per-target PIC that would override it: POSITION_INDEPENDENT_CODE
on _cld2, the cuDF fragments and the GPU island targets, -Xcompiler -fPIC in
CMAKE_CUDA_FLAGS (now -Xcompiler -fPIE), -fPIC on xgboost and dmlc-core, and
the MSan "-fPIC -fpie" (now -fPIE).

-fPIC stays where it is needed or mirrors upstream: compiler-rt (builtins,
and the sanitizer and XRay runtimes through SANITIZER_COMMON_FLAGS),
glibc-compatibility with ENABLE_OPENSSL_DYNAMIC, and the shared crypto/ssl
libraries of that option, which CMake compiles as PIC by itself. musl's
rcrt1.c keeps -fPIC on master.

Measured locally (compile_commands.json, effective last PIC/PIE flag per TU):
- amd64 debug, release; aarch64 binary, release; asan, msan, tsan: every
  C/C++ TU is -fPIE except clang_rt_builtins and the compiler-rt sanitizer /
  XRay runtimes; with ENABLE_OPENSSL_DYNAMIC also crypto, ssl and
  glibc-compatibility.
- amd64 debug clickhouse: ELF type DYN, FLAGS_1 NOW PIE; clickhouse local
  queries with threads and exceptions work.
- aarch64 flatc, msan and asan llvm-min-tblgen: DYN + PIE, the sanitizer
  builds run.
- With a clang wrapper defaulting to -fno-pic, llvm-min-tblgen still links
  as PIE.

The GPU island (ENABLE_GPU) is not built by CI and I have no CUDA toolkit,
so the cmake/cuda.cmake and contrib/cudf-cmake changes are not built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Groene AIandClaude Opus 5.5 committed 2026-10-14 19:01:16 +00:00
1 parent b9fbfb17e7
commit 9415dcba9b
7 files changed
+12 -20

No files matched your search

+7 -11
View File
@@ -622,16 +622,19 @@ include(cmake/dbms_glob_sources.cmake)
# For some sophisticated platforms we have different issues with fPIC:
# For example riscv toolchain itself compiled without fPIC
#
# The code is compiled with -fPIE, not -fPIC: it is linked into an executable, where the symbol
# interposition that -fPIC pays for (GOT loads, TLS descriptors) never happens.
#
# This has to be configured before the first targets are created, in particular before
# cmake/linux/default_libs.cmake adds the C++ runtime libraries from contrib: CMake copies the flags
# into each subdirectory when add_subdirectory is called, so targets created earlier would silently
# compile without -fPIC. That only breaks with compilers that do not default to PIE
# compile without -fPIE. That only breaks with compilers that do not default to PIE
# (clang with CLANG_DEFAULT_PIE_ON_LINUX=OFF, as configured by some distributions), because then the
# non-relocatable objects of those libraries cannot be linked into the PIE executable.
if (ARCH_AMD64 OR ARCH_AARCH64)
set(ENABLE_POSITION_INDEPENDENT_BINARY 1)
# -fPIC only makes the code relocatable; whether the executable itself is position independent is
# -fPIE only makes the code relocatable; whether the executable itself is position independent is
# the compiler driver's default unless the linker is asked explicitly, so ask it.
# musl links statically, and -static-pie needs an rcrt1.o that contrib/musl-cmake does not build.
# The FreeBSD and Darwin sysroots carry no PIC startup objects (Scrt1.o).
@@ -642,8 +645,8 @@ endif()
if (ENABLE_POSITION_INDEPENDENT_BINARY)
set (CMAKE_POSITION_INDEPENDENT_CODE OFF)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
endif()
add_library(global-group INTERFACE)
@@ -659,13 +662,6 @@ elseif (OS_WASM)
include(cmake/wasm/default_libs.cmake)
endif ()
if (ENABLE_POSITION_INDEPENDENT_BINARY)
# The C++ runtime libraries are linked only into executables, so they are compiled as PIE (the last flag wins).
foreach (runtime_target cxx cxxabi unwind)
target_compile_options (${runtime_target} PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-fPIE>)
endforeach ()
endif ()
link_libraries(global-group)
target_link_libraries(global-group INTERFACE $<TARGET_PROPERTY:global-libs,INTERFACE_LINK_LIBRARIES>)
+1 -1
View File
@@ -56,7 +56,7 @@ def process_glibc_check():
def process_pie_check():
# Nothing in the build fails when the binary comes out position dependent: -fPIC only makes the
# Nothing in the build fails when the binary comes out position dependent: -fPIE only makes the
# code relocatable, and whether the executable itself is position independent is the linker's
# decision, so it is checked on the packaged binary instead.
header = Shell.get_output(
+1 -2
View File
@@ -130,7 +130,7 @@ if (ENABLE_GPU)
# It has to reach gcc through -Xcompiler. nvcc rejects `-std=gnu++20` for itself
# ("Value 'gnu++20' is not defined for option 'std'"), and CMAKE_CUDA_EXTENSIONS is a
# no-op here - CMake emits -std=c++20 for nvcc either way.
string (APPEND CMAKE_CUDA_FLAGS " --expt-relaxed-constexpr -Xcompiler -fPIC -Xcompiler -std=gnu++20")
string (APPEND CMAKE_CUDA_FLAGS " --expt-relaxed-constexpr -Xcompiler -fPIE -Xcompiler -std=gnu++20")
option (ENABLE_GPU_KERNEL_LINEINFO "Emit CUDA line info, for profiling kernels in Nsight Compute" OFF)
@@ -166,7 +166,6 @@ if (ENABLE_GPU)
COMPILE_OPTIONS ""
COMPILE_DEFINITIONS ""
INCLUDE_DIRECTORIES ""
POSITION_INDEPENDENT_CODE ON
)
get_target_property (_gpu_island_srcs ${target} SOURCES)
+2 -2
View File
@@ -102,8 +102,8 @@ if (SANITIZE)
endif ()
# Linking can fail due to relocation overflows (see #49145), caused by too big object files / libraries.
# Work around this with position-independent builds (-fPIC and -fpie), this is slightly slower than non-PIC/PIE but that's okay.
set (MSAN_FLAGS "-fsanitize=memory -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins=${MSAN_TRACK_ORIGINS_LEVEL} -fPIC -fpie ${MSAN_X86_VZEROUPPER_FLAGS}")
# Work around this with position-independent builds (-fPIE), this is slightly slower than non-PIC/PIE but that's okay.
set (MSAN_FLAGS "-fsanitize=memory -fsanitize-memory-use-after-dtor -fsanitize-memory-track-origins=${MSAN_TRACK_ORIGINS_LEVEL} -fPIE ${MSAN_X86_VZEROUPPER_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS} ${MSAN_FLAGS}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_FLAGS} ${MSAN_FLAGS}")
-1
View File
@@ -27,7 +27,6 @@ set (SRCS
"${LIBRARY_DIR}/internal/cld_generated_score_quad_octa_2.cc"
)
add_library(_cld2 ${SRCS})
set_property(TARGET _cld2 PROPERTY POSITION_INDEPENDENT_CODE ON)
target_compile_options (_cld2 PRIVATE -Wno-reserved-id-macro -Wno-c++11-narrowing)
target_include_directories(_cld2 SYSTEM BEFORE PUBLIC "${LIBRARY_DIR}/public")
add_library(ch_contrib::cld2 ALIAS _cld2)
-1
View File
@@ -125,7 +125,6 @@ function (cudf_add_fragment FRAGMENT INSTANCE UDF_TYPE FILE_INDEX)
CUDA_SEPARABLE_COMPILATION ON
CUDA_FATBIN_COMPILATION ON
INTERPROCEDURAL_OPTIMIZATION ON
POSITION_INDEPENDENT_CODE ON
CUDA_STANDARD 20
CUDA_STANDARD_REQUIRED ON
CUDA_VISIBILITY_PRESET hidden)
+1 -2
View File
@@ -159,7 +159,6 @@ configure_file(
set(DMLC_CORE_COMPILE_OPTIONS
-Wall
-Wno-unknown-pragmas
-fPIC
)
# `-msse2` is only meaningful on x86.
@@ -291,7 +290,7 @@ set(XGBOOST_SOURCES
add_library(_xgboost ${XGBOOST_SOURCES})
target_include_directories(_xgboost SYSTEM PUBLIC ${XGBOOST_INCLUDE_DIR} ${DMLC_CORE_INCLUDE_DIR})
target_compile_options(_xgboost PRIVATE -fPIC -std=c++17 -include exception)
target_compile_options(_xgboost PRIVATE -std=c++17 -include exception)
target_link_libraries(_xgboost PRIVATE
_dmlc_core
Threads::Threads ${CMAKE_THREAD_LIBS_INIT}