|
| 1 | +#[=============================================================================[ |
| 2 | +This module checks linker support for aligning .text segments on huge page |
| 3 | +boundary. |
| 4 | +
|
| 5 | +Usually, the CheckLinkerFlag module is used to check linker flags, however due |
| 6 | +to the LLD bug present in versions before 18.1 the run check needs to be |
| 7 | +performed. When cross-compiling, the CheckLinkerFlag module is used and the LDD |
| 8 | +bug bypassed for versions prior to 18.1. |
| 9 | +
|
| 10 | +See also: |
| 11 | +- https://github.com/llvm/llvm-project/issues/57618 |
| 12 | +- https://releases.llvm.org/18.1.0/tools/lld/docs/ReleaseNotes.html |
| 13 | +- https://bugs.php.net/79092 |
| 14 | +- https://github.com/php/php-src/pull/5123 |
| 15 | +#]=============================================================================] |
| 16 | + |
| 17 | +include_guard(GLOBAL) |
| 18 | + |
| 19 | +include(CheckLinkerFlag) |
| 20 | +include(CheckSourceRuns) |
| 21 | +include(CMakePushCheckState) |
| 22 | + |
| 23 | +message( |
| 24 | + CHECK_START |
| 25 | + "Checking linker support for aligning segments on huge page boundary" |
| 26 | +) |
| 27 | + |
| 28 | +if( |
| 29 | + NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" |
| 30 | + AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(i[3456]86.*|x86_64)$" |
| 31 | +) |
| 32 | + message(CHECK_FAIL "no") |
| 33 | + return() |
| 34 | +endif() |
| 35 | + |
| 36 | +if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR) |
| 37 | + if( |
| 38 | + CMAKE_C_COMPILER_LINKER_ID STREQUAL "LLD" |
| 39 | + AND CMAKE_C_COMPILER_LINKER_VERSION |
| 40 | + AND CMAKE_C_COMPILER_LINKER_VERSION VERSION_LESS 18.1 |
| 41 | + ) |
| 42 | + set(PHP_HAS_ALIGNMENT_FLAGS_C FALSE) |
| 43 | + endif() |
| 44 | + |
| 45 | + if( |
| 46 | + CMAKE_CXX_COMPILER_LINKER_ID STREQUAL "LLD" |
| 47 | + AND CMAKE_CXX_COMPILER_LINKER_VERSION |
| 48 | + AND CMAKE_CXX_COMPILER_LINKER_VERSION VERSION_LESS 18.1 |
| 49 | + ) |
| 50 | + set(PHP_HAS_ALIGNMENT_FLAGS_CXX FALSE) |
| 51 | + endif() |
| 52 | +endif() |
| 53 | + |
| 54 | +# Checks given linker flags and adds them to the php_config interface target. |
| 55 | +function(_php_check_segments_alignment lang flags result) |
| 56 | + if(NOT DEFINED ${result}) |
| 57 | + cmake_push_check_state(RESET) |
| 58 | + set(CMAKE_REQUIRED_QUIET TRUE) |
| 59 | + |
| 60 | + if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR) |
| 61 | + check_linker_flag(${lang} "${flags}" ${result}) |
| 62 | + else() |
| 63 | + set(CMAKE_REQUIRED_LINK_OPTIONS ${flags}) |
| 64 | + check_source_runs(${lang} [[int main(void) { return 0; }]] ${result}) |
| 65 | + endif() |
| 66 | + cmake_pop_check_state() |
| 67 | + endif() |
| 68 | + |
| 69 | + if(${result}) |
| 70 | + target_link_options( |
| 71 | + php_config |
| 72 | + INTERFACE |
| 73 | + $<$<AND:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>,$<LINK_LANGUAGE:${lang}>>:${flags}> |
| 74 | + ) |
| 75 | + endif() |
| 76 | +endfunction() |
| 77 | + |
| 78 | +set(flags LINKER:-z,common-page-size=2097152 LINKER:-z,max-page-size=2097152) |
| 79 | +_php_check_segments_alignment(C "${flags}" PHP_HAS_ALIGNMENT_FLAGS_C) |
| 80 | + |
| 81 | +if(NOT PHP_HAS_ALIGNMENT_FLAGS_C) |
| 82 | + set(flags LINKER:-z,max-page-size=2097152) |
| 83 | + _php_check_segments_alignment(C "${flags}" PHP_HAS_MAX_PAGE_SIZE_C) |
| 84 | +endif() |
| 85 | + |
| 86 | +get_property(enabledLanguages GLOBAL PROPERTY ENABLED_LANGUAGES) |
| 87 | + |
| 88 | +if(CXX IN_LIST enabledLanguages) |
| 89 | + set(flags LINKER:-z,common-page-size=2097152 LINKER:-z,max-page-size=2097152) |
| 90 | + _php_check_segments_alignment(CXX "${flags}" PHP_HAS_ALIGNMENT_FLAGS_CXX) |
| 91 | + |
| 92 | + if(NOT PHP_HAS_ALIGNMENT_FLAGS_CXX) |
| 93 | + set(flags LINKER:-z,max-page-size=2097152) |
| 94 | + _php_check_segments_alignment(CXX "${flags}" PHP_HAS_MAX_PAGE_SIZE_CXX) |
| 95 | + endif() |
| 96 | +endif() |
| 97 | + |
| 98 | +if( |
| 99 | + PHP_HAS_ALIGNMENT_FLAGS_C |
| 100 | + OR PHP_HAS_ALIGNMENT_FLAGS_CXX |
| 101 | + OR PHP_HAS_MAX_PAGE_SIZE_C |
| 102 | + OR PHP_HAS_MAX_PAGE_SIZE_CXX |
| 103 | +) |
| 104 | + message(CHECK_PASS "done") |
| 105 | +else() |
| 106 | + message(CHECK_FAIL "no") |
| 107 | +endif() |
0 commit comments