mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2026-10-28 16:18:23 +08:00
Adds `OS_WASM`/`ARCH_WASM` to the build system and the platform arms that go with them, so `emcmake cmake` configures this tree and the lower layers of it compile to `wasm64`. It is experimental and not in CI, like the Android and E2K targets; nothing here changes any platform that builds today. The build system: arch and target detection, `cmake/wasm/default_libs.cmake` (the Emscripten sysroot already supplies libc, libc++, libc++abi, compiler-rt and a pthread implementation, so unlike the other platforms this one does not use `-nodefaultlibs`), `emcc` handling in `cmake/tools.cmake` (it knows its own target and drives `wasm-ld` itself), the set of libraries a sandbox cannot have, `ucontext` fibers for Boost.Context and the Linux resolver configuration for c-ares. `wasm64` rather than `wasm32`: this tree assumes a 64-bit `size_t` and 64-bit pointers pervasively, from `1e12uz` literals in `Core/Defines.h` to sizeof-equality static_asserts in ProfileEvents. The platform arms: thread ids and names, `waitForPid`, `malloc_usable_size`, and stack traces - WebAssembly cannot walk its own call stack from user code and there is no libunwind for it. Signals get one capability macro, `OS_HAS_SIGNAL_HANDLERS` in `base/defines.h`, rather than a condition per call site; the timer-based query profiler follows it, since a per-thread timer has no way to deliver an expiry without signals. Two fixes that are not WebAssembly-specific but block this configuration: * The `USE_LIBFIU=0` branch of `FailPoint.cpp` is stale. It defines `enablePauseFailPoint`, `wait` and `enableFromGlobalConfig`, none of which the class declares any more, and omits `notifyPauseAndWaitForResume`, which it does. `-DENABLE_LIBFIU=OFF` does not build on any platform today. * `atomicRename.cpp` defines `RENAME_NOREPLACE`/`RENAME_EXCHANGE` unconditionally in its non-Linux branch, which collides with a libc that declares them without being able to honour them. No warnings are disabled: `-Weverything -Werror` is untouched, and the one diagnostic that came from a libc macro rather than from this code - musl spells `stderr` as `#define stderr (stderr)` - is suppressed at the single use, the way `cmake/warnings.cmake` prescribes. Verified with Emscripten 6.0.5. The whole tree configures. `base/base/libcommon.a` and `src/libclickhouse_common_io.a` build - 402 objects, confirmed as WebAssembly binaries - with the standard warning set and `-Werror`. On Linux the full `clickhouse` binary builds and behaves identically: stack traces, the query profiler and thread naming all unchanged. Two things still stand between this and a whole WebAssembly binary, both deliberately left out. `-Wunique-object-duplication` fires 214 times across 16 headers because Emscripten defaults to `-fvisibility=hidden`, which no other target here uses; clearing it means giving those statics default visibility, which is its own change and not this one. And the rest of the tree beyond `clickhouse_common_io` has not been attempted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
142 lines
5.2 KiB
CMake
142 lines
5.2 KiB
CMake
# Compiler
|
|
|
|
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
|
message (FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER_ID} is not supported. Please switch to Clang")
|
|
endif ()
|
|
|
|
# Print details to output
|
|
if (OS_WASM)
|
|
# `emcc` knows its own target and sysroot, and rejects being passed an empty one.
|
|
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version
|
|
OUTPUT_VARIABLE COMPILER_SELF_IDENTIFICATION
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
else ()
|
|
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version --target=${CMAKE_CXX_COMPILER_TARGET} --sysroot=${CMAKE_SYSROOT}
|
|
OUTPUT_VARIABLE COMPILER_SELF_IDENTIFICATION
|
|
COMMAND_ERROR_IS_FATAL ANY
|
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
)
|
|
endif ()
|
|
message (STATUS "Using compiler:\n${COMPILER_SELF_IDENTIFICATION}")
|
|
|
|
# Require minimum compiler versions
|
|
set (CLANG_MINIMUM_VERSION 21)
|
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${CLANG_MINIMUM_VERSION})
|
|
message (FATAL_ERROR "Compilation with Clang version ${CMAKE_CXX_COMPILER_VERSION} is unsupported, the minimum required version is ${CLANG_MINIMUM_VERSION}.")
|
|
endif ()
|
|
|
|
string (REGEX MATCHALL "[0-9]+" COMPILER_VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
|
|
list (GET COMPILER_VERSION_LIST 0 COMPILER_VERSION_MAJOR)
|
|
|
|
# Linker
|
|
option (LINKER_NAME "Linker name or full path")
|
|
|
|
if (LINKER_NAME MATCHES "gold")
|
|
message (FATAL_ERROR "Linking with gold is unsupported. Please use lld.")
|
|
endif ()
|
|
|
|
macro(ch_find_program var)
|
|
if (USING_DUMMY_LAUNCHERS)
|
|
set(${var} "${CMAKE_SOURCE_DIR}/cmake/dummy_compiler_linker.sh")
|
|
else()
|
|
unset(${var})
|
|
find_program(${var} ${ARGN})
|
|
endif()
|
|
endmacro()
|
|
|
|
if (NOT LINKER_NAME)
|
|
if (OS_LINUX AND NOT ARCH_S390X)
|
|
ch_find_program (LLD_PATH NAMES "ld.lld-${COMPILER_VERSION_MAJOR}" "ld.lld")
|
|
elseif (OS_DARWIN)
|
|
ch_find_program (LLD_PATH NAMES "ld64.lld-${COMPILER_VERSION_MAJOR}" "ld64.lld" "ld")
|
|
# Duplicate libraries passed to the linker is not a problem.
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_warn_duplicate_libraries")
|
|
endif ()
|
|
if (LLD_PATH)
|
|
if (OS_LINUX OR OS_DARWIN)
|
|
# Clang driver simply allows full linker path.
|
|
set (LINKER_NAME ${LLD_PATH})
|
|
endif ()
|
|
endif()
|
|
endif()
|
|
|
|
if (LINKER_NAME)
|
|
ch_find_program (LLD_PATH NAMES ${LINKER_NAME})
|
|
if (NOT LLD_PATH)
|
|
message (FATAL_ERROR "Using linker ${LINKER_NAME} but can't find its path.")
|
|
endif ()
|
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --ld-path=${LLD_PATH}")
|
|
endif ()
|
|
|
|
if (LINKER_NAME)
|
|
message(STATUS "Using linker: ${LINKER_NAME}")
|
|
elseif (OS_WASM)
|
|
# `emcc` drives `wasm-ld` itself and takes no `--ld-path`.
|
|
message(STATUS "Using linker: <wasm-ld, through emcc>")
|
|
elseif (NOT ARCH_S390X AND NOT OS_FREEBSD AND NOT OS_SUNOS)
|
|
message (FATAL_ERROR "The only supported linker is LLVM's LLD, but we cannot find it.")
|
|
else ()
|
|
message(STATUS "Using linker: <default>")
|
|
endif ()
|
|
|
|
# Archiver
|
|
ch_find_program (LLVM_AR_PATH NAMES "llvm-ar-${COMPILER_VERSION_MAJOR}" "llvm-ar")
|
|
if (LLVM_AR_PATH)
|
|
set (CMAKE_AR "${LLVM_AR_PATH}")
|
|
endif ()
|
|
message(STATUS "Using archiver: ${CMAKE_AR}")
|
|
|
|
# Ranlib
|
|
ch_find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib-${COMPILER_VERSION_MAJOR}" "llvm-ranlib")
|
|
if (LLVM_RANLIB_PATH)
|
|
set (CMAKE_RANLIB "${LLVM_RANLIB_PATH}")
|
|
endif ()
|
|
message(STATUS "Using ranlib: ${CMAKE_RANLIB}")
|
|
|
|
# Install Name Tool
|
|
ch_find_program (LLVM_INSTALL_NAME_TOOL_PATH NAMES "llvm-install-name-tool-${COMPILER_VERSION_MAJOR}" "llvm-install-name-tool")
|
|
if (LLVM_INSTALL_NAME_TOOL_PATH)
|
|
set (CMAKE_INSTALL_NAME_TOOL "${LLVM_INSTALL_NAME_TOOL_PATH}")
|
|
endif ()
|
|
message(STATUS "Using install-name-tool: ${CMAKE_INSTALL_NAME_TOOL}")
|
|
|
|
# Objcopy
|
|
ch_find_program (OBJCOPY_PATH NAMES "llvm-objcopy-${COMPILER_VERSION_MAJOR}" "llvm-objcopy" "objcopy")
|
|
if (OBJCOPY_PATH)
|
|
message (STATUS "Using objcopy: ${OBJCOPY_PATH}")
|
|
else ()
|
|
message (FATAL_ERROR "Cannot find objcopy.")
|
|
endif ()
|
|
|
|
# nm (used by helper scripts that inspect symbol tables, e.g. cmake/localize_rust_c_symbols.sh)
|
|
ch_find_program (NM_PATH NAMES "llvm-nm-${COMPILER_VERSION_MAJOR}" "llvm-nm" "nm")
|
|
if (NM_PATH)
|
|
message (STATUS "Using nm: ${NM_PATH}")
|
|
else ()
|
|
message (FATAL_ERROR "Cannot find nm.")
|
|
endif ()
|
|
|
|
# Strip
|
|
ch_find_program (STRIP_PATH NAMES "llvm-strip-${COMPILER_VERSION_MAJOR}" "llvm-strip" "strip")
|
|
if (STRIP_PATH)
|
|
message (STATUS "Using strip: ${STRIP_PATH}")
|
|
else ()
|
|
message (FATAL_ERROR "Cannot find strip.")
|
|
endif ()
|
|
|
|
if (OS_DARWIN AND NOT CMAKE_TOOLCHAIN_FILE)
|
|
# utils/list-licenses/list-licenses.sh (which generates system table system.licenses) needs the GNU versions of find and grep. These are
|
|
# not available out-of-the-box on Mac. As a special case, Darwin builds in CI are cross-compiled from x86 Linux where the GNU userland is
|
|
# available.
|
|
find_program(GFIND_PATH NAMES "gfind")
|
|
if (NOT GFIND_PATH)
|
|
message (FATAL_ERROR "GNU find not found. You can install it with 'brew install findutils'.")
|
|
endif()
|
|
find_program(GGREP_PATH NAMES "ggrep")
|
|
if (NOT GGREP_PATH)
|
|
message (FATAL_ERROR "GNU grep not found. You can install it with 'brew install grep'.")
|
|
endif()
|
|
endif ()
|