From 76191bed44219b13a7b38653b43a93fc928900a3 Mon Sep 17 00:00:00 2001 From: Ashcon Partovi Date: Thu, 12 Sep 2024 18:08:59 -0700 Subject: [PATCH] Various fixes for CMake (#13928) --- CMakeLists.txt | 18 +- cmake/CompilerFlags.cmake | 315 ++++++++++++++++++------ cmake/{Macros.cmake => Globals.cmake} | 340 ++++++++++++++++++++------ cmake/Options.cmake | 63 ----- cmake/analysis/RunClangTidy.cmake | 2 - cmake/analysis/RunCppCheck.cmake | 2 - cmake/analysis/RunCppLint.cmake | 2 - cmake/analysis/RunIWYU.cmake | 2 - cmake/scripts/GitClone.cmake | 3 +- cmake/targets/BuildBoringSSL.cmake | 2 - cmake/targets/BuildBrotli.cmake | 9 +- cmake/targets/BuildBun.cmake | 76 +++--- cmake/targets/BuildCares.cmake | 2 - cmake/targets/BuildLibArchive.cmake | 4 +- cmake/targets/BuildLibDeflate.cmake | 2 - cmake/targets/BuildLibuv.cmake | 2 - cmake/targets/BuildLolHtml.cmake | 5 +- cmake/targets/BuildLshpack.cmake | 2 - cmake/targets/BuildMimalloc.cmake | 2 - cmake/targets/BuildSQLite.cmake | 2 - cmake/targets/BuildTinyCC.cmake | 2 - cmake/targets/BuildZlib.cmake | 2 - cmake/targets/BuildZstd.cmake | 2 - cmake/tools/SetupBuildkite.cmake | 2 - cmake/tools/SetupBun.cmake | 2 - cmake/tools/SetupCcache.cmake | 2 - cmake/tools/SetupEsbuild.cmake | 2 - cmake/tools/SetupLLVM.cmake | 2 - cmake/tools/SetupMacSDK.cmake | 2 - cmake/tools/SetupRust.cmake | 2 - cmake/tools/SetupWebKit.cmake | 60 +---- cmake/tools/SetupZig.cmake | 50 ++-- package.json | 4 +- scripts/build.mjs | 32 ++- 34 files changed, 598 insertions(+), 423 deletions(-) rename cmake/{Macros.cmake => Globals.cmake} (78%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 875cf2e633..17be34f43a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 3.24) message(STATUS "Configuring Bun") -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake @@ -11,16 +10,7 @@ list(APPEND CMAKE_MODULE_PATH ) include(Policies) -include(Macros) - -# --- Globals --- - -setx(CWD ${CMAKE_SOURCE_DIR}) -setx(BUILD_PATH ${CMAKE_BINARY_DIR}) -optionx(CACHE_PATH STRING "The path to the cache directory" DEFAULT ${BUILD_PATH}/cache) -optionx(CACHE_STRATEGY "read-write|read-only|write-only|none" "The strategy to use for caching" DEFAULT "read-write") -optionx(TMP_PATH STRING "The path to the temporary directory" DEFAULT ${BUILD_PATH}/tmp) -optionx(FRESH BOOL "Set when --fresh is used" DEFAULT OFF) +include(Globals) # --- Compilers --- @@ -36,6 +26,7 @@ parse_package_json(VERSION_VARIABLE DEFAULT_VERSION) optionx(VERSION STRING "The version of Bun" DEFAULT ${DEFAULT_VERSION}) project(Bun VERSION ${VERSION}) include(Options) +include(CompilerFlags) # --- Tools --- @@ -43,11 +34,8 @@ include(SetupBuildkite) include(SetupBun) include(SetupEsbuild) include(SetupZig) +include(SetupRust) # --- Targets --- include(BuildBun) - -# --- Flags --- - -include(CompilerFlags) diff --git a/cmake/CompilerFlags.cmake b/cmake/CompilerFlags.cmake index 5b4d8aaf40..14e634f692 100644 --- a/cmake/CompilerFlags.cmake +++ b/cmake/CompilerFlags.cmake @@ -1,57 +1,97 @@ -include(Macros) - # clang: https://clang.llvm.org/docs/CommandGuide/clang.html # clang-cl: https://clang.llvm.org/docs/UsersManual.html#id11 +# --- Macros --- + +macro(setb variable) + if(${variable}) + set(${variable} ON) + else() + set(${variable} OFF) + endif() +endmacro() + +set(targets WIN32 APPLE UNIX LINUX) +foreach(target ${targets}) + setb(${target}) +endforeach() + +# --- CPU target --- + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64") + if(APPLE) + register_compiler_flags(-mcpu=apple-m1) + else() + register_compiler_flags(-march=armv8-a+crc -mtune=ampere1) + endif() +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64") + if(ENABLE_BASELINE) + register_compiler_flags(-march=nehalem) + else() + register_compiler_flags(-march=haswell) + endif() +else() + unsupported(CMAKE_SYSTEM_PROCESSOR) +endif() + # --- MSVC runtime --- if(WIN32) - if(DEBUG) - add_compile_options(/MTd) # Use static debug run-time - else() - add_compile_options(/MT) # Use static run-time - endif() + register_compiler_flags( + DESCRIPTION "Use static MSVC runtime" + /MTd ${DEBUG} + /MT ${RELEASE} + /U_DLL + ) endif() # --- Optimization level --- if(DEBUG) - if(WIN32) - add_compile_options(/O0) - else() - add_compile_options(-O0) - endif() + register_compiler_flags( + DESCRIPTION "Disable optimization" + /O0 ${WIN32} + -O0 ${UNIX} + ) elseif(ENABLE_SMOL) - if(WIN32) - add_compile_options(/Os) - else() - add_compile_options(-Os) - endif() + register_compiler_flags( + DESCRIPTION "Optimize for size" + /Os ${WIN32} + -Os ${UNIX} + ) else() - if(WIN32) - # TODO: change to /0t (same as -O3) to match macOS and Linux? - add_compile_options(/O2) - else() - add_compile_options(-O3) - endif() + register_compiler_flags( + DESCRIPTION "Optimize for speed" + /O2 ${WIN32} # TODO: change to /0t (same as -O3) to match macOS and Linux? + -O3 ${UNIX} + ) endif() -# --- Debug symbols --- +# --- Debug level --- if(WIN32) - add_compile_options( - /Z7 # Produce a .pdb file + register_compiler_flags( + DESCRIPTION "Enable debug symbols (.pdb)" + /Z7 ) -else() - add_compile_options( - -ggdb # Produce a format that is compatable with GDB - -gdwarf-4 # Produce DWARF v4 debug info +elseif(APPLE) + register_compiler_flags( + DESCRIPTION "Enable debug symbols (.dSYM)" + -gdwarf-4 + ) +endif() + +if(UNIX) + register_compiler_flags( + DESCRIPTION "Enable debug symbols" + -g3 ${DEBUG} + -g1 ${RELEASE} + ) + + register_compiler_flags( + DESCRIPTION "Optimize debug symbols for LLDB" + -glldb ) - if(DEBUG) - add_compile_options(-g3) - else() - add_compile_options(-g1) - endif() endif() # TODO: consider other debug options @@ -59,44 +99,184 @@ endif() # -fstandalone-debug # Emit debug info for non-system libraries # -fno-eliminate-unused-debug-types # Don't eliminate unused debug symbols -# --- RTTI --- +# --- C/C++ flags --- -if(WIN32) - add_compile_options(/GR-) -else() - add_compile_options(-fno-rtti) +register_compiler_flags( + DESCRIPTION "Disable C/C++ exceptions" + -fno-exceptions ${UNIX} + /EHsc ${WIN32} # (s- disables C++, c- disables C) +) + +register_compiler_flags( + DESCRIPTION "Disable C++ static destructors" + LANGUAGES CXX + -Xclang ${WIN32} + -fno-c++-static-destructors +) + +register_compiler_flags( + DESCRIPTION "Disable runtime type information (RTTI)" + /GR- ${WIN32} + -fno-rtti ${UNIX} +) + +register_compiler_flags( + DESCRIPTION "Keep frame pointers" + /Oy- ${WIN32} + -fno-omit-frame-pointer ${UNIX} + -mno-omit-leaf-frame-pointer ${UNIX} +) + +if(UNIX) + register_compiler_flags( + DESCRIPTION "Set C/C++ visibility to hidden" + -fvisibility=hidden + -fvisibility-inlines-hidden + ) + + register_compiler_flags( + DESCRIPTION "Disable unwind tables" + -fno-unwind-tables + -fno-asynchronous-unwind-tables + ) endif() -# --- CPU target (-march, -mtune, -mcpu) --- +register_compiler_flags( + DESCRIPTION "Place each function in its own section" + -ffunction-sections ${UNIX} + /Gy ${WIN32} +) -# Using -march=native can break older systems, instead use a specific CPU -if(CPU STREQUAL "native") - if(ARCH STREQUAL "aarch64") - if(APPLE) - add_compile_options(-mcpu=apple-m1) - else() - add_compile_options(-march=armv8-a+crc -mtune=ampere1) - endif() +register_compiler_flags( + DESCRIPTION "Place each data item in its own section" + -fdata-sections ${UNIX} + /Gw ${WIN32} +) + +if(UNIX) + register_compiler_flags( + DESCRIPTION "Emit an address-significance table" + -faddrsig + ) +endif() + +if(WIN32) + register_compiler_flags( + DESCRIPTION "Enable string pooling" + /GF + ) + + register_compiler_flags( + DESCRIPTION "Assume thread-local variables are defined in the executable" + /GA + ) +endif() + +# --- Linker flags --- + +if(LINUX) + register_linker_flags( + DESCRIPTION "Disable relocation read-only (RELRO)" + -Wl,-z,norelro + ) +endif() + +# --- Assertions --- + +# Note: This is a helpful guide about assertions: +# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++ + +if(ENABLE_ASSERTIONS) + register_compiler_flags( + DESCRIPTION "Do not eliminate null-pointer checks" + -fno-delete-null-pointer-checks + ) + + register_compiler_definitions( + DESCRIPTION "Enable libc++ assertions" + _LIBCPP_ENABLE_ASSERTIONS=1 + _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE ${RELEASE} + _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG ${DEBUG} + ) + + register_compiler_definitions( + DESCRIPTION "Enable fortified sources" + _FORTIFY_SOURCE=3 + ) + + if(LINUX) + register_compiler_definitions( + DESCRIPTION "Enable glibc++ assertions" + _GLIBCXX_ASSERTIONS=1 + ) endif() -elseif(CPU) - add_compile_options(-march=${CPU} -mtune=${CPU}) else() - message(FATAL_ERROR "No CPU specified, please set -DCPU=") + register_compiler_definitions( + DESCRIPTION "Disable debug assertions" + NDEBUG=1 + ) + + register_compiler_definitions( + DESCRIPTION "Disable libc++ assertions" + _LIBCPP_ENABLE_ASSERTIONS=0 + _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE + ) + + if(LINUX) + register_compiler_definitions( + DESCRIPTION "Disable glibc++ assertions" + _GLIBCXX_ASSERTIONS=0 + ) + endif() endif() # --- Diagnostics --- -if(NOT WIN32) - add_compile_options(-fdiagnostics-color=always) +if(UNIX) + register_compiler_flags( + DESCRIPTION "Enable color diagnostics" + -fdiagnostics-color=always + ) endif() -add_compile_options(-ferror-limit=${ERROR_LIMIT}) +register_compiler_flags( + DESCRIPTION "Set C/C++ error limit" + -ferror-limit=${ERROR_LIMIT} +) + +# --- LTO --- + +if(ENABLE_LTO) + register_compiler_flags( + DESCRIPTION "Enable link-time optimization (LTO)" + -flto=full ${UNIX} + -flto ${WIN32} + ) + + if(UNIX) + register_compiler_flags( + DESCRIPTION "Enable virtual tables" + LANGUAGES CXX + -fforce-emit-vtables + -fwhole-program-vtables + ) + + register_linker_flags( + DESCRIPTION "Enable link-time optimization (LTO)" + -flto=full + -fwhole-program-vtables + -fforce-emit-vtables + ) + endif() +endif() # --- Remapping --- -if(NOT WIN32) - add_compile_options( +if(UNIX) + register_compiler_flags( + DESCRIPTION "Remap source files" -ffile-prefix-map=${CWD}=. + -ffile-prefix-map=${VENDOR_PATH}=vendor -ffile-prefix-map=${BUILD_PATH}=build -ffile-prefix-map=${CACHE_PATH}=cache ) @@ -107,7 +287,7 @@ endif() # Valgrind cannot handle SSE4.2 instructions # This is needed for picohttpparser if(ENABLE_VALGRIND AND ARCH STREQUAL "x64") - add_compile_definitions("__SSE4_2__=0") + register_compiler_definitions(__SSE4_2__=0) endif() # --- Other --- @@ -118,28 +298,9 @@ if(WIN32 AND NOT CMAKE_CL_SHOWINCLUDES_PREFIX) set(CMAKE_CL_SHOWINCLUDES_PREFIX "Note: including file:") endif() -if(ENABLE_ASSERTIONS) - if(APPLE) - # add_compile_definitions("_LIBCXX_ENABLE_ASSERTIONS=1") - # add_compile_definitions("_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG") - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - add_compile_definitions("_GLIBCXX_ASSERTIONS=1") - endif() - - add_compile_definitions("ASSERT_ENABLED=1") -else() - if(APPLE) - # add_compile_definitions("_LIBCXX_ENABLE_ASSERTIONS=0") - # add_compile_definitions("_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE") - endif() - - add_compile_definitions("NDEBUG=1") -endif() - # WebKit uses -std=gnu++20 on non-macOS non-Windows. # If we do not set this, it will crash at startup on the first memory allocation. if(NOT WIN32 AND NOT APPLE) set(CMAKE_CXX_EXTENSIONS ON) set(CMAKE_POSITION_INDEPENDENT_CODE OFF) endif() - diff --git a/cmake/Macros.cmake b/cmake/Globals.cmake similarity index 78% rename from cmake/Macros.cmake rename to cmake/Globals.cmake index c5e37718ec..1dcb5e57fa 100644 --- a/cmake/Macros.cmake +++ b/cmake/Globals.cmake @@ -1,5 +1,142 @@ include(CMakeParseArguments) +# --- Global macros --- + +# setx() +# Description: +# Sets a variable, similar to `set()`, but also prints the value. +# Arguments: +# variable string - The variable to set +# value string - The value to set the variable to +macro(setx) + set(${ARGV}) + message(STATUS "Set ${ARGV0}: ${${ARGV0}}") +endmacro() + +# optionx() +# Description: +# Defines an option, similar to `option()`, but allows for bool, string, and regex types. +# Arguments: +# variable string - The variable to set +# type string - The type of the variable +# description string - The description of the variable +# DEFAULT string - The default value of the variable +# PREVIEW string - The preview value of the variable +# REGEX string - The regex to match the value +# REQUIRED bool - Whether the variable is required +macro(optionx variable type description) + set(options REQUIRED) + set(oneValueArgs DEFAULT PREVIEW REGEX) + set(multiValueArgs) + cmake_parse_arguments(${variable} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT ${type} MATCHES "^(BOOL|STRING|FILEPATH|PATH|INTERNAL)$") + set(${variable}_REGEX ${type}) + set(${variable}_TYPE STRING) + else() + set(${variable}_TYPE ${type}) + endif() + + set(${variable} ${${variable}_DEFAULT} CACHE ${${variable}_TYPE} ${description}) + set(${variable}_SOURCE "argument") + set(${variable}_PREVIEW -D${variable}) + + if(DEFINED ENV{${variable}}) + set(${variable} $ENV{${variable}} CACHE ${${variable}_TYPE} ${description} FORCE) + set(${variable}_SOURCE "environment variable") + set(${variable}_PREVIEW ${variable}) + endif() + + if(NOT ${variable} AND ${${variable}_REQUIRED}) + message(FATAL_ERROR "Required ${${variable}_SOURCE} is missing: please set, ${${variable}_PREVIEW}=<${${variable}_REGEX}>") + endif() + + if(${type} STREQUAL "BOOL") + if("${${variable}}" MATCHES "^(TRUE|true|ON|on|YES|yes|1)$") + set(${variable} ON) + elseif("${${variable}}" MATCHES "^(FALSE|false|OFF|off|NO|no|0)$") + set(${variable} OFF) + else() + message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\", please use ${${variable}_PREVIEW}=") + endif() + endif() + + if(DEFINED ${variable}_REGEX AND NOT "^(${${variable}_REGEX})$" MATCHES "${${variable}}") + message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\", please use ${${variable}_PREVIEW}=<${${variable}_REGEX}>") + endif() + + message(STATUS "Set ${variable}: ${${variable}}") +endmacro() + +# unsupported() +# Description: +# Prints a message that the feature is not supported. +# Arguments: +# variable string - The variable that is not supported +macro(unsupported variable) + message(FATAL_ERROR "Unsupported ${variable}: \"${${variable}}\"") +endmacro() + +# --- CMake variables --- + +setx(CMAKE_VERSION ${CMAKE_VERSION}) +setx(CMAKE_COMMAND ${CMAKE_COMMAND}) +setx(CMAKE_HOST_SYSTEM_NAME ${CMAKE_HOST_SYSTEM_NAME}) + +# In script mode, using -P, this variable is not set +if(NOT DEFINED CMAKE_HOST_SYSTEM_PROCESSOR) + cmake_host_system_information(RESULT CMAKE_HOST_SYSTEM_PROCESSOR QUERY OS_PLATFORM) +endif() +setx(CMAKE_HOST_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR}) + +if(CMAKE_HOST_APPLE) + set(HOST_OS "darwin") +elseif(CMAKE_HOST_WIN32) + set(HOST_OS "windows") +elseif(CMAKE_HOST_LINUX) + set(HOST_OS "linux") +else() + unsupported(CMAKE_HOST_SYSTEM_NAME) +endif() + +if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64") + set(HOST_OS "aarch64") +elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64") + set(HOST_OS "x64") +else() + unsupported(CMAKE_HOST_SYSTEM_PROCESSOR) +endif() + +setx(CMAKE_EXPORT_COMPILE_COMMANDS ON) +setx(CMAKE_COLOR_DIAGNOSTICS ON) + +cmake_host_system_information(RESULT CORE_COUNT QUERY NUMBER_OF_LOGICAL_CORES) +optionx(CMAKE_BUILD_PARALLEL_LEVEL STRING "The number of parallel build jobs" DEFAULT ${CORE_COUNT}) + +# --- Global variables --- + +setx(CWD ${CMAKE_SOURCE_DIR}) +setx(BUILD_PATH ${CMAKE_BINARY_DIR}) + +optionx(CACHE_PATH FILEPATH "The path to the cache directory" DEFAULT ${BUILD_PATH}/cache) +optionx(CACHE_STRATEGY "read-write|read-only|write-only|none" "The strategy to use for caching" DEFAULT "read-write") + +optionx(CI BOOL "If CI is enabled" DEFAULT OFF) + +if(CI) + set(DEFAULT_VENDOR_PATH ${CACHE_PATH}/vendor) +else() + set(DEFAULT_VENDOR_PATH ${CWD}/vendor) +endif() + +optionx(VENDOR_PATH FILEPATH "The path to the vendor directory" DEFAULT ${DEFAULT_VENDOR_PATH}) +optionx(TMP_PATH FILEPATH "The path to the temporary directory" DEFAULT ${BUILD_PATH}/tmp) + +optionx(FRESH BOOL "Set when --fresh is used" DEFAULT OFF) +optionx(CLEAN BOOL "Set when --clean is used" DEFAULT OFF) + +# --- Helper functions --- + function(parse_semver value variable) string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${value}") @@ -13,17 +150,6 @@ function(parse_semver value variable) set(${variable}_VERSION_PATCH "${CMAKE_MATCH_3}" PARENT_SCOPE) endfunction() -# setx() -# Description: -# Sets a variable, similar to `set()`, but also prints the value. -# Arguments: -# variable string - The variable to set -# value string - The value to set the variable to -macro(setx) - set(${ARGV}) - message(STATUS "Set ${ARGV0}: ${${ARGV0}}") -endmacro() - # setenv() # Description: # Sets an environment variable during the build step, and writes it to a .env file. @@ -61,65 +187,6 @@ function(setenv variable value) message(STATUS "Set ENV ${variable}: ${value}") endfunction() -# optionx() -# Description: -# Defines an option, similar to `option()`, but allows for bool, string, and regex types. -# Arguments: -# variable string - The variable to set -# type string - The type of the variable -# description string - The description of the variable -# DEFAULT string - The default value of the variable -# PREVIEW string - The preview value of the variable -# REGEX string - The regex to match the value -# REQUIRED bool - Whether the variable is required -macro(optionx variable type description) - set(options REQUIRED) - set(oneValueArgs DEFAULT PREVIEW REGEX) - set(multiValueArgs) - cmake_parse_arguments(${variable} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT ${type} MATCHES "^(BOOL|STRING|FILEPATH|PATH|INTERNAL)$") - set(${variable}_REGEX ${type}) - set(${variable}_TYPE STRING) - else() - set(${variable}_TYPE ${type}) - endif() - - set(${variable} ${${variable}_DEFAULT} CACHE ${${variable}_TYPE} ${description}) - set(${variable}_SOURCE "argument") - set(${variable}_PREVIEW -D${variable}) - - if(DEFINED ENV{${variable}}) - # if(DEFINED ${variable} AND NOT ${variable} STREQUAL $ENV{${variable}}) - # message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\" conflicts with environment variable ${variable}=\"$ENV{${variable}}\"") - # endif() - - set(${variable} $ENV{${variable}} CACHE ${${variable}_TYPE} ${description} FORCE) - set(${variable}_SOURCE "environment variable") - set(${variable}_PREVIEW ${variable}) - endif() - - if(NOT ${variable} AND ${${variable}_REQUIRED}) - message(FATAL_ERROR "Required ${${variable}_SOURCE} is missing: please set, ${${variable}_PREVIEW}=<${${variable}_REGEX}>") - endif() - - if(${type} STREQUAL "BOOL") - if("${${variable}}" MATCHES "^(TRUE|true|ON|on|YES|yes|1)$") - set(${variable} ON) - elseif("${${variable}}" MATCHES "^(FALSE|false|OFF|off|NO|no|0)$") - set(${variable} OFF) - else() - message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\", please use ${${variable}_PREVIEW}=") - endif() - endif() - - if(DEFINED ${variable}_REGEX AND NOT "^(${${variable}_REGEX})$" MATCHES "${${variable}}") - message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\", please use ${${variable}_PREVIEW}=<${${variable}_REGEX}>") - endif() - - message(STATUS "Set ${variable}: ${${variable}}") -endmacro() - # check_command() # Description: # Checks if a command is available, used by `find_command()` as a validator. @@ -142,7 +209,7 @@ function(check_command FOUND CMD) OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(NOT RESULT EQUAL 0) + if(NOT RESULT EQUAL 0 OR NOT OUTPUT) message(DEBUG "${CHECK_COMMAND}, exited with code ${RESULT}") return() endif() @@ -212,7 +279,11 @@ function(find_command) message(FATAL_ERROR "Command not found: \"${CMD_COMMAND}\"") endif() - setx(${CMD_VARIABLE} ${${CMD_VARIABLE}}) + if(${CMD_VARIABLE} MATCHES "NOTFOUND") + unset(${CMD_VARIABLE} PARENT_SCOPE) + else() + setx(${CMD_VARIABLE} ${${CMD_VARIABLE}} PARENT_SCOPE) + endif() endfunction() # register_command() @@ -272,7 +343,7 @@ function(register_command) endforeach() foreach(source ${CMD_SOURCES}) - if(NOT source MATCHES "^(${CWD}|${BUILD_PATH})") + if(NOT source MATCHES "^(${CWD}|${BUILD_PATH}|${CACHE_PATH}|${VENDOR_PATH})") message(FATAL_ERROR "register_command: SOURCES contains \"${source}\", if it's a path, make it absolute, otherwise add it to TARGETS instead") endif() list(APPEND CMD_EFFECTIVE_DEPENDS ${source}) @@ -285,14 +356,14 @@ function(register_command) set(CMD_EFFECTIVE_OUTPUTS) foreach(output ${CMD_OUTPUTS}) - if(NOT output MATCHES "^(${CWD}|${BUILD_PATH})") + if(NOT output MATCHES "^(${CWD}|${BUILD_PATH}|${CACHE_PATH}|${VENDOR_PATH})") message(FATAL_ERROR "register_command: OUTPUTS contains \"${output}\", if it's a path, make it absolute") endif() list(APPEND CMD_EFFECTIVE_OUTPUTS ${output}) endforeach() foreach(artifact ${CMD_ARTIFACTS}) - if(NOT artifact MATCHES "^(${CWD}|${BUILD_PATH})") + if(NOT artifact MATCHES "^(${CWD}|${BUILD_PATH}|${CACHE_PATH}|${VENDOR_PATH})") message(FATAL_ERROR "register_command: ARTIFACTS contains \"${artifact}\", if it's a path, make it absolute") endif() list(APPEND CMD_EFFECTIVE_OUTPUTS ${artifact}) @@ -501,7 +572,7 @@ function(register_repository) endif() if(NOT GIT_PATH) - set(GIT_PATH ${CWD}/vendor/${GIT_NAME}) + set(GIT_PATH ${VENDOR_PATH}/${GIT_NAME}) endif() if(GIT_COMMIT) @@ -562,7 +633,7 @@ function(register_cmake_command) endif() if(NOT MAKE_CWD) - set(MAKE_CWD ${CWD}/vendor/${MAKE_TARGET}) + set(MAKE_CWD ${VENDOR_PATH}/${MAKE_TARGET}) endif() if(NOT MAKE_BUILD_PATH) @@ -621,7 +692,7 @@ function(register_cmake_command) set(effectiveFlags ${setFlags} ${appendFlags}) foreach(flag ${effectiveFlags}) - list(APPEND MAKE_EFFECTIVE_ARGS -DCMAKE_${flag}=${MAKE_${flag}}) + list(APPEND MAKE_EFFECTIVE_ARGS "-DCMAKE_${flag}=${MAKE_${flag}}") endforeach() if(DEFINED FRESH) @@ -706,3 +777,116 @@ function(register_cmake_command) target_sources(${bun} PRIVATE ${MAKE_ARTIFACTS}) endif() endfunction() + +# register_compiler_flag() +# Description: +# Registers a compiler flag, similar to `add_compile_options()`, but has more validation and features. +# Arguments: +# flags string[] - The flags to register +# DESCRIPTION string - The description of the flag +# LANGUAGES string[] - The languages to register the flag (default: C, CXX) +# TARGETS string[] - The targets to register the flag (default: all) +function(register_compiler_flags) + set(args DESCRIPTION) + set(multiArgs LANGUAGES TARGETS) + cmake_parse_arguments(COMPILER "" "${args}" "${multiArgs}" ${ARGN}) + + if(NOT COMPILER_LANGUAGES) + set(COMPILER_LANGUAGES C CXX) + endif() + + set(COMPILER_FLAGS) + foreach(flag ${COMPILER_UNPARSED_ARGUMENTS}) + if(flag STREQUAL "ON") + continue() + elseif(flag STREQUAL "OFF") + list(POP_BACK COMPILER_FLAGS) + elseif(flag MATCHES "^(-|/)") + list(APPEND COMPILER_FLAGS ${flag}) + else() + message(FATAL_ERROR "register_compiler_flags: Invalid flag: \"${flag}\"") + endif() + endforeach() + + foreach(target ${COMPILER_TARGETS}) + if(NOT TARGET ${target}) + message(FATAL_ERROR "register_compiler_flags: \"${target}\" is not a target") + endif() + endforeach() + + foreach(lang ${COMPILER_LANGUAGES}) + list(JOIN COMPILER_FLAGS " " COMPILER_FLAGS_STRING) + + if(NOT COMPILER_TARGETS) + set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${COMPILER_FLAGS_STRING}" PARENT_SCOPE) + endif() + + foreach(target ${COMPILER_TARGETS}) + set(${target}_CMAKE_${lang}_FLAGS "${${target}_CMAKE_${lang}_FLAGS} ${COMPILER_FLAGS_STRING}" PARENT_SCOPE) + endforeach() + endforeach() + + foreach(lang ${COMPILER_LANGUAGES}) + foreach(flag ${COMPILER_FLAGS}) + if(NOT COMPILER_TARGETS) + add_compile_options($<$:${flag}>) + endif() + + foreach(target ${COMPILER_TARGETS}) + get_target_property(type ${target} TYPE) + if(type MATCHES "EXECUTABLE|LIBRARY") + target_compile_options(${target} PRIVATE $<$:${flag}>) + endif() + endforeach() + endforeach() + endforeach() +endfunction() + +function(register_compiler_definitions) + +endfunction() + +# register_linker_flags() +# Description: +# Registers a linker flag, similar to `add_link_options()`. +# Arguments: +# flags string[] - The flags to register +# DESCRIPTION string - The description of the flag +function(register_linker_flags) + set(args DESCRIPTION) + cmake_parse_arguments(LINKER "" "${args}" "" ${ARGN}) + + foreach(flag ${LINKER_UNPARSED_ARGUMENTS}) + if(flag STREQUAL "ON") + continue() + elseif(flag STREQUAL "OFF") + list(POP_FRONT LINKER_FLAGS) + elseif(flag MATCHES "^(-|/)") + list(APPEND LINKER_FLAGS ${flag}) + else() + message(FATAL_ERROR "register_linker_flags: Invalid flag: \"${flag}\"") + endif() + endforeach() + + add_link_options(${LINKER_FLAGS}) +endfunction() + +function(print_compiler_flags) + get_property(targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) + set(languages C CXX) + foreach(target ${targets}) + get_target_property(type ${target} TYPE) + message(STATUS "Target: ${target}") + foreach(lang ${languages}) + if(${target}_CMAKE_${lang}_FLAGS) + message(STATUS " ${lang} Flags: ${${target}_CMAKE_${lang}_FLAGS}") + endif() + endforeach() + endforeach() + foreach(lang ${languages}) + message(STATUS "Language: ${lang}") + if(CMAKE_${lang}_FLAGS) + message(STATUS " Flags: ${CMAKE_${lang}_FLAGS}") + endif() + endforeach() +endfunction() diff --git a/cmake/Options.cmake b/cmake/Options.cmake index f342bc4e54..44ea99042d 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -1,5 +1,3 @@ -include(Macros) - if(NOT CMAKE_SYSTEM_NAME OR NOT CMAKE_SYSTEM_PROCESSOR) message(FATAL_ERROR "CMake included this file before project() was called") endif() @@ -7,7 +5,6 @@ endif() optionx(BUN_LINK_ONLY BOOL "If only the linking step should be built" DEFAULT OFF) optionx(BUN_CPP_ONLY BOOL "If only the C++ part of Bun should be built" DEFAULT OFF) -optionx(CI BOOL "If CI is enabled" DEFAULT OFF) optionx(BUILDKITE BOOL "If Buildkite is enabled" DEFAULT OFF) optionx(GITHUB_ACTIONS BOOL "If GitHub Actions is enabled" DEFAULT OFF) @@ -34,10 +31,6 @@ if(CMAKE_BUILD_TYPE MATCHES "MinSizeRel") setx(ENABLE_SMOL ON) endif() -cmake_host_system_information(RESULT CORE_COUNT QUERY NUMBER_OF_LOGICAL_CORES) - -optionx(CMAKE_BUILD_PARALLEL_LEVEL STRING "The number of parallel build jobs" DEFAULT ${CORE_COUNT}) - if(APPLE) setx(OS "darwin") elseif(WIN32) @@ -60,16 +53,6 @@ if(ARCH STREQUAL "x64") optionx(ENABLE_BASELINE BOOL "If baseline features should be used for older CPUs (e.g. disables AVX, AVX2)" DEFAULT OFF) endif() -if(ARCH STREQUAL "aarch64") - set(DEFAULT_CPU "native") -elseif(ENABLE_BASELINE) - set(DEFAULT_CPU "nehalem") -else() - set(DEFAULT_CPU "haswell") -endif() - -optionx(CPU STRING "The CPU to use for the compiler" DEFAULT ${DEFAULT_CPU}) - optionx(ENABLE_LOGS BOOL "If debug logs should be enabled" DEFAULT ${DEBUG}) optionx(ENABLE_ASSERTIONS BOOL "If debug assertions should be enabled" DEFAULT ${DEBUG}) @@ -170,51 +153,5 @@ optionx(USE_WEBKIT_ICU BOOL "Use the ICU libraries from WebKit" DEFAULT ${DEFAUL optionx(ERROR_LIMIT STRING "Maximum number of errors to show when compiling C++ code" DEFAULT "100") -# Set the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS for building dependencies. -# This is a mess, since it doesn't use the CMake add_compile_options or target_compile_options commands. -# In the future, make some macros so we can set this automatically. -# e.g. -# add_c_flags(-mtune=native) - applies to all dependencies -# add_c_flags({target} -fno-rtti) - applies to a specific target - -if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|arm|ARM64") - if(APPLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=apple-m1") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=apple-m1") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crc -mtune=ampere1") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a+crc -mtune=ampere1") - endif() -else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mtune=${CPU}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mtune=${CPU}") -endif() - list(APPEND CMAKE_ARGS -DCMAKE_EXPORT_COMPILE_COMMANDS=ON) -if(WIN32) - list(APPEND CMAKE_ARGS -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Z7 /MT /Ob2 /DNDEBUG /U_DLL") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Z7 /MT /Ob2 /DNDEBUG /U_DLL -Xclang -fno-c++-static-destructors") - if(ENABLE_LTO) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=lld -flto -Xclang -emit-llvm-bc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld -flto -Xclang -emit-llvm-bc") - endif() -else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-c++-static-destructors") - if(ENABLE_LTO) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto=full") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=full -fwhole-program-vtables -fforce-emit-vtables") - set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -flto=full -fwhole-program-vtables -fforce-emit-vtables") - endif() - if(LINUX) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -faddrsig") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections -faddrsig") - set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -Wl,-z,norelro") - endif() - if(APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCXX_ENABLE_ASSERTIONS=0 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE") - endif() -endif() - diff --git a/cmake/analysis/RunClangTidy.cmake b/cmake/analysis/RunClangTidy.cmake index 09c1111766..bac6cc5e75 100644 --- a/cmake/analysis/RunClangTidy.cmake +++ b/cmake/analysis/RunClangTidy.cmake @@ -1,7 +1,5 @@ # https://clang.llvm.org/extra/clang-tidy/ -include(Macros) - find_command( VARIABLE CLANG_TIDY_PROGRAM diff --git a/cmake/analysis/RunCppCheck.cmake b/cmake/analysis/RunCppCheck.cmake index f8131f98c2..a384a44863 100644 --- a/cmake/analysis/RunCppCheck.cmake +++ b/cmake/analysis/RunCppCheck.cmake @@ -1,7 +1,5 @@ # https://cppcheck.sourceforge.io/ -include(Macros) - find_command( VARIABLE CPPCHECK_EXECUTABLE diff --git a/cmake/analysis/RunCppLint.cmake b/cmake/analysis/RunCppLint.cmake index 7d9d6b1e00..5b9264ecf5 100644 --- a/cmake/analysis/RunCppLint.cmake +++ b/cmake/analysis/RunCppLint.cmake @@ -1,5 +1,3 @@ -include(Macros) - find_command( VARIABLE CPPLINT_PROGRAM diff --git a/cmake/analysis/RunIWYU.cmake b/cmake/analysis/RunIWYU.cmake index 832902576b..340e44f780 100644 --- a/cmake/analysis/RunIWYU.cmake +++ b/cmake/analysis/RunIWYU.cmake @@ -1,8 +1,6 @@ # IWYU = "Include What You Use" # https://include-what-you-use.org/ -include(Macros) - setx(IWYU_SOURCE_PATH ${CACHE_PATH}/iwyu-${LLVM_VERSION_MAJOR}) setx(IWYU_BUILD_PATH ${IWYU_SOURCE_PATH}/build) setx(IWYU_PROGRAM ${IWYU_BUILD_PATH}/bin/include-what-you-use) diff --git a/cmake/scripts/GitClone.cmake b/cmake/scripts/GitClone.cmake index a46bf068f0..6dcfffc4b2 100644 --- a/cmake/scripts/GitClone.cmake +++ b/cmake/scripts/GitClone.cmake @@ -1,4 +1,4 @@ -include(cmake/Macros.cmake) +include(cmake/Globals.cmake) if(NOT GIT_PATH OR NOT GIT_REPOSITORY OR NOT GIT_REF) message(FATAL_ERROR "git_clone: GIT_PATH, GIT_REPOSITORY, and GIT_REF are required") @@ -33,6 +33,7 @@ foreach(i RANGE 10) ${GIT_DOWNLOAD_TMP_PATH} TIMEOUT 120 STATUS GIT_DOWNLOAD_STATUS + SHOW_PROGRESS ) if(GIT_DOWNLOAD_STATUS MATCHES "^0") file(RENAME ${GIT_DOWNLOAD_TMP_PATH} ${GIT_DOWNLOAD_PATH}) diff --git a/cmake/targets/BuildBoringSSL.cmake b/cmake/targets/BuildBoringSSL.cmake index e3aea90a4b..28575eb35f 100644 --- a/cmake/targets/BuildBoringSSL.cmake +++ b/cmake/targets/BuildBoringSSL.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME boringssl diff --git a/cmake/targets/BuildBrotli.cmake b/cmake/targets/BuildBrotli.cmake index 9a2302ead3..f9bc8d9601 100644 --- a/cmake/targets/BuildBrotli.cmake +++ b/cmake/targets/BuildBrotli.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME brotli @@ -9,6 +7,12 @@ register_repository( v1.1.0 ) +# Tests fail with "BrotliDecompressionError" when LTO is enabled +# only on Linux x64 (non-baseline). It's a mystery. +if(LINUX AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64" AND NOT ENABLE_BASELINE) + set(BROTLI_CMAKE_ARGS "-DCMAKE_C_FLAGS=-fno-lto") +endif() + register_cmake_command( TARGET brotli @@ -21,6 +25,7 @@ register_cmake_command( -DBROTLI_BUILD_TOOLS=OFF -DBROTLI_EMSCRIPTEN=OFF -DBROTLI_DISABLE_TESTS=ON + ${BROTLI_CMAKE_ARGS} INCLUDES c/include ) diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index d012066e84..5f7d2c1577 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -1,5 +1,3 @@ -include(Macros) - if(DEBUG) set(bun bun-debug) elseif(ENABLE_SMOL) @@ -496,8 +494,8 @@ list(APPEND BUN_ZIG_SOURCES ${BUN_JAVASCRIPT_OUTPUTS} ) -if (CMAKE_BUILD_TYPE STREQUAL "Debug") - # in a debug build, these are not embedded, but rather referenced at runtime. +# In debug builds, these are not embedded, but rather referenced at runtime. +if (DEBUG) list(APPEND BUN_ZIG_SOURCES ${CODEGEN_PATH}/kit_empty_file) else() list(APPEND BUN_ZIG_SOURCES ${BUN_KIT_RUNTIME_OUTPUTS}) @@ -505,9 +503,27 @@ endif() set(BUN_ZIG_OUTPUT ${BUILD_PATH}/bun-zig.o) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64") + if(APPLE) + set(ZIG_CPU "apple_m1") + else() + set(ZIG_CPU "native") + endif() +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|X86_64|x64|X64|amd64|AMD64") + if(ENABLE_BASELINE) + set(ZIG_CPU "nehalem") + else() + set(ZIG_CPU "haswell") + endif() +else() + unsupported(CMAKE_SYSTEM_PROCESSOR) +endif() + register_command( TARGET bun-zig + GROUP + console COMMENT "Building src/*.zig for ${ZIG_TARGET}" COMMAND @@ -518,7 +534,7 @@ register_command( -Dobj_format=${ZIG_OBJECT_FORMAT} -Dtarget=${ZIG_TARGET} -Doptimize=${ZIG_OPTIMIZE} - -Dcpu=${CPU} + -Dcpu=${ZIG_CPU} -Denable_logs=$,true,false> -Dversion=${VERSION} -Dsha=${REVISION} @@ -572,7 +588,7 @@ register_repository( picohttpparser.c ) -list(APPEND BUN_C_SOURCES ${CWD}/vendor/picohttpparser/picohttpparser.c) +list(APPEND BUN_C_SOURCES ${VENDOR_PATH}/picohttpparser/picohttpparser.c) if(WIN32) list(APPEND BUN_C_SOURCES ${CWD}/src/bun.js/bindings/windows/musl-memmem.c) @@ -662,13 +678,17 @@ target_include_directories(${bun} PRIVATE ${CWD}/src/js/builtins ${CWD}/src/napi ${CWD}/src/deps - ${CWD}/vendor - ${CWD}/vendor/picohttpparser ${CODEGEN_PATH} + ${VENDOR_PATH} + ${VENDOR_PATH}/picohttpparser ) # --- C/C++ Definitions --- +if(ENABLE_ASSERTIONS) + target_compile_definitions(${bun} PRIVATE ASSERT_ENABLED=1) +endif() + if(DEBUG) target_compile_definitions(${bun} PRIVATE BUN_DEBUG=1) endif() @@ -714,31 +734,10 @@ endif() # --- Compiler options --- -if(WIN32) - target_compile_options(${bun} PUBLIC - /EHsc - -Xclang -fno-c++-static-destructors - ) - if(RELEASE) - target_compile_options(${bun} PUBLIC - /Gy - /Gw - /GF - /GA - ) - endif() -else() +if(NOT WIN32) target_compile_options(${bun} PUBLIC -fconstexpr-steps=2542484 -fconstexpr-depth=54 - -fno-exceptions - -fno-asynchronous-unwind-tables - -fno-unwind-tables - -fno-c++-static-destructors - -fvisibility=hidden - -fvisibility-inlines-hidden - -fno-omit-frame-pointer - -mno-omit-leaf-frame-pointer -fno-pic -fno-pie -faddrsig @@ -798,7 +797,6 @@ if(WIN32) ) if(RELEASE) target_link_options(${bun} PUBLIC - -flto=full /LTCG /OPT:REF /OPT:NOICF @@ -858,22 +856,6 @@ else() ) endif() -# --- LTO options --- - -if(ENABLE_LTO) - if(WIN32) - target_link_options(${bun} PUBLIC -flto) - target_compile_options(${bun} PUBLIC -flto -Xclang -emit-llvm-bc) - else() - target_compile_options(${bun} PUBLIC - -flto=full - -emit-llvm - -fwhole-program-vtables - -fforce-emit-vtables - ) - endif() -endif() - # --- Symbols list --- if(WIN32) diff --git a/cmake/targets/BuildCares.cmake b/cmake/targets/BuildCares.cmake index ccc6f3b2f7..9a3f0b9ef0 100644 --- a/cmake/targets/BuildCares.cmake +++ b/cmake/targets/BuildCares.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME cares diff --git a/cmake/targets/BuildLibArchive.cmake b/cmake/targets/BuildLibArchive.cmake index 7c2393921f..e0cffd020b 100644 --- a/cmake/targets/BuildLibArchive.cmake +++ b/cmake/targets/BuildLibArchive.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME libarchive @@ -40,7 +38,7 @@ register_cmake_command( # spawn a processes to compress instead of using the library. -DENABLE_ZLIB=OFF -DHAVE_ZLIB_H=ON - -DCMAKE_C_FLAGS="-I${CWD}/vendor/zlib" + -DCMAKE_C_FLAGS="-I${VENDOR_PATH}/zlib" LIB_PATH libarchive LIBRARIES diff --git a/cmake/targets/BuildLibDeflate.cmake b/cmake/targets/BuildLibDeflate.cmake index 568f1062d4..3faf5963a7 100644 --- a/cmake/targets/BuildLibDeflate.cmake +++ b/cmake/targets/BuildLibDeflate.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME libdeflate diff --git a/cmake/targets/BuildLibuv.cmake b/cmake/targets/BuildLibuv.cmake index 97cb58c632..feba612c44 100644 --- a/cmake/targets/BuildLibuv.cmake +++ b/cmake/targets/BuildLibuv.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME libuv diff --git a/cmake/targets/BuildLolHtml.cmake b/cmake/targets/BuildLolHtml.cmake index 8cfd51cc2c..9a02362723 100644 --- a/cmake/targets/BuildLolHtml.cmake +++ b/cmake/targets/BuildLolHtml.cmake @@ -1,6 +1,3 @@ -include(Macros) -include(SetupRust) - register_repository( NAME lolhtml @@ -10,7 +7,7 @@ register_repository( 8d4c273ded322193d017042d1f48df2766b0f88b ) -set(LOLHTML_CWD ${CWD}/vendor/lolhtml/c-api) +set(LOLHTML_CWD ${VENDOR_PATH}/lolhtml/c-api) set(LOLHTML_BUILD_PATH ${BUILD_PATH}/lolhtml) if(DEBUG) diff --git a/cmake/targets/BuildLshpack.cmake b/cmake/targets/BuildLshpack.cmake index 53406b27c9..c1cbb12ff5 100644 --- a/cmake/targets/BuildLshpack.cmake +++ b/cmake/targets/BuildLshpack.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME lshpack diff --git a/cmake/targets/BuildMimalloc.cmake b/cmake/targets/BuildMimalloc.cmake index 70e953a3b1..48d3fe5224 100644 --- a/cmake/targets/BuildMimalloc.cmake +++ b/cmake/targets/BuildMimalloc.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME mimalloc diff --git a/cmake/targets/BuildSQLite.cmake b/cmake/targets/BuildSQLite.cmake index 4dc898544d..ce4cd8da24 100644 --- a/cmake/targets/BuildSQLite.cmake +++ b/cmake/targets/BuildSQLite.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_cmake_command( TARGET sqlite diff --git a/cmake/targets/BuildTinyCC.cmake b/cmake/targets/BuildTinyCC.cmake index 60257d2356..c6b4bbaee9 100644 --- a/cmake/targets/BuildTinyCC.cmake +++ b/cmake/targets/BuildTinyCC.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME tinycc diff --git a/cmake/targets/BuildZlib.cmake b/cmake/targets/BuildZlib.cmake index 6e29286025..cc98acde74 100644 --- a/cmake/targets/BuildZlib.cmake +++ b/cmake/targets/BuildZlib.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME zlib diff --git a/cmake/targets/BuildZstd.cmake b/cmake/targets/BuildZstd.cmake index b4ccc83f20..f58c3793fa 100644 --- a/cmake/targets/BuildZstd.cmake +++ b/cmake/targets/BuildZstd.cmake @@ -1,5 +1,3 @@ -include(Macros) - register_repository( NAME zstd diff --git a/cmake/tools/SetupBuildkite.cmake b/cmake/tools/SetupBuildkite.cmake index 5911ce728b..946ed25131 100644 --- a/cmake/tools/SetupBuildkite.cmake +++ b/cmake/tools/SetupBuildkite.cmake @@ -1,5 +1,3 @@ -include(Macros) - optionx(BUILDKITE_CACHE BOOL "If the build can use Buildkite caches, even if not running in Buildkite" DEFAULT ${BUILDKITE}) if(NOT BUILDKITE_CACHE OR NOT BUN_LINK_ONLY) diff --git a/cmake/tools/SetupBun.cmake b/cmake/tools/SetupBun.cmake index ac2fa1f3e2..5377eb1cff 100644 --- a/cmake/tools/SetupBun.cmake +++ b/cmake/tools/SetupBun.cmake @@ -1,5 +1,3 @@ -include(Macros) - find_command( VARIABLE BUN_EXECUTABLE diff --git a/cmake/tools/SetupCcache.cmake b/cmake/tools/SetupCcache.cmake index b3d12039b7..7e14cc8a41 100644 --- a/cmake/tools/SetupCcache.cmake +++ b/cmake/tools/SetupCcache.cmake @@ -1,5 +1,3 @@ -include(Macros) - optionx(ENABLE_CCACHE BOOL "If ccache should be enabled" DEFAULT ON) if(NOT ENABLE_CCACHE OR CACHE_STRATEGY STREQUAL "none") diff --git a/cmake/tools/SetupEsbuild.cmake b/cmake/tools/SetupEsbuild.cmake index f5364de45b..90989b711c 100644 --- a/cmake/tools/SetupEsbuild.cmake +++ b/cmake/tools/SetupEsbuild.cmake @@ -1,5 +1,3 @@ -include(Macros) - if(CMAKE_HOST_WIN32) setx(ESBUILD_EXECUTABLE ${CWD}/node_modules/.bin/esbuild.exe) else() diff --git a/cmake/tools/SetupLLVM.cmake b/cmake/tools/SetupLLVM.cmake index 43c08cdb4e..a029ce9fce 100644 --- a/cmake/tools/SetupLLVM.cmake +++ b/cmake/tools/SetupLLVM.cmake @@ -1,5 +1,3 @@ -include(Macros) - if(CMAKE_HOST_WIN32 OR CMAKE_HOST_APPLE) set(DEFAULT_LLVM_VERSION "18.1.8") else() diff --git a/cmake/tools/SetupMacSDK.cmake b/cmake/tools/SetupMacSDK.cmake index ae9d6823cd..83d0e8e5d3 100644 --- a/cmake/tools/SetupMacSDK.cmake +++ b/cmake/tools/SetupMacSDK.cmake @@ -1,5 +1,3 @@ -include(Macros) - set(MIN_OSX_DEPLOYMENT_TARGET "13.0") if(DEFINED ENV{CI}) diff --git a/cmake/tools/SetupRust.cmake b/cmake/tools/SetupRust.cmake index 45e9558aa1..a83b28bc5f 100644 --- a/cmake/tools/SetupRust.cmake +++ b/cmake/tools/SetupRust.cmake @@ -1,5 +1,3 @@ -include(Macros) - find_command( VARIABLE CARGO_EXECUTABLE diff --git a/cmake/tools/SetupWebKit.cmake b/cmake/tools/SetupWebKit.cmake index ea2d9aef67..38bbac3b85 100644 --- a/cmake/tools/SetupWebKit.cmake +++ b/cmake/tools/SetupWebKit.cmake @@ -1,5 +1,3 @@ -include(Macros) - optionx(WEBKIT_VERSION STRING "The version of WebKit to use" DEFAULT "147ed53838e21525677492c27099567a6cd19c6b") optionx(WEBKIT_PREBUILT BOOL "If a pre-built version of WebKit should be used" DEFAULT ON) @@ -69,8 +67,8 @@ set(WEBKIT_NAME bun-webkit-${WEBKIT_OS}-${WEBKIT_ARCH}${WEBKIT_SUFFIX}) set(WEBKIT_FILENAME ${WEBKIT_NAME}.tar.gz) setx(WEBKIT_DOWNLOAD_URL https://github.com/oven-sh/WebKit/releases/download/autobuild-${WEBKIT_VERSION}/${WEBKIT_FILENAME}) -file(DOWNLOAD ${WEBKIT_DOWNLOAD_URL} ${CACHE_PATH}/${WEBKIT_FILENAME}) -file(ARCHIVE_EXTRACT INPUT ${CACHE_PATH}/${WEBKIT_FILENAME} DESTINATION ${CACHE_PATH}) +file(DOWNLOAD ${WEBKIT_DOWNLOAD_URL} ${CACHE_PATH}/${WEBKIT_FILENAME} SHOW_PROGRESS) +file(ARCHIVE_EXTRACT INPUT ${CACHE_PATH}/${WEBKIT_FILENAME} DESTINATION ${CACHE_PATH} TOUCH) file(REMOVE ${CACHE_PATH}/${WEBKIT_FILENAME}) file(REMOVE_RECURSE ${WEBKIT_PATH}) file(RENAME ${CACHE_PATH}/bun-webkit ${WEBKIT_PATH}) @@ -78,57 +76,3 @@ file(RENAME ${CACHE_PATH}/bun-webkit ${WEBKIT_PATH}) if(APPLE) file(REMOVE_RECURSE ${WEBKIT_INCLUDE_PATH}/unicode) endif() - -# --- WebKit --- -# WebKit is either prebuilt and distributed via NPM, or you can pass WEBKIT_PATH to use a local build. -# We cannot include their CMake build files (TODO: explain why, for now ask @paperdave why) -# -# On Unix, this will pull from NPM the single package that is needed and use that -# if(WIN32) -# set(STATIC_LIB_EXT "lib") -# set(libJavaScriptCore "JavaScriptCore") -# set(libWTF "WTF") -# else() -# set(STATIC_LIB_EXT "a") -# set(libJavaScriptCore "libJavaScriptCore") -# set(libWTF "libWTF") -# endif() - -# if(WEBKIT_PREBUILT) - -# elseif(WEBKIT_PATH STREQUAL "omit") - -# else() -# # Expected to be WebKit/WebKitBuild/${CMAKE_BUILD_TYPE} -# if(EXISTS "${WEBKIT_PATH}/cmakeconfig.h") -# # You may need to run: -# # make jsc-compile-debug jsc-copy-headers -# include_directories( -# "${WEBKIT_PATH}/" -# "${WEBKIT_PATH}/JavaScriptCore/Headers/JavaScriptCore" -# "${WEBKIT_PATH}/JavaScriptCore/PrivateHeaders" -# "${WEBKIT_PATH}/bmalloc/Headers" -# "${WEBKIT_PATH}/WTF/Headers" -# ) -# set(WEBKIT_LIB_DIR "${WEBKIT_PATH}/lib") - -# if(ENABLE_ASSERTIONS) -# add_compile_definitions("BUN_DEBUG=1") -# endif() - -# message(STATUS "Using WebKit from ${WEBKIT_PATH}") -# else() -# if(NOT EXISTS "${WEBKIT_PATH}/lib/${libWTF}.${STATIC_LIB_EXT}" OR NOT EXISTS "${WEBKIT_PATH}/lib/${libJavaScriptCore}.${STATIC_LIB_EXT}") -# if(WEBKIT_PATH MATCHES "src/bun.js/WebKit$") -# message(FATAL_ERROR "WebKit directory ${WEBKIT_PATH} does not contain all the required files for Bun. Did you forget to init submodules?") -# endif() - -# message(FATAL_ERROR "WebKit directory ${WEBKIT_PATH} does not contain all the required files for Bun. Expected a path to the oven-sh/WebKit repository, or a path to a folder containing `include` and `lib`.") -# endif() - -# set(WEBKIT_LIB_DIR "${WEBKIT_PATH}/lib") - -# message(STATUS "Using specified WebKit directory: ${WEBKIT_PATH}") -# message(STATUS "WebKit assertions: OFF") -# endif() -# endif() \ No newline at end of file diff --git a/cmake/tools/SetupZig.cmake b/cmake/tools/SetupZig.cmake index 90dd7e71de..005fec3597 100644 --- a/cmake/tools/SetupZig.cmake +++ b/cmake/tools/SetupZig.cmake @@ -1,11 +1,9 @@ -include(Macros) - if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") set(DEFAULT_ZIG_ARCH "aarch64") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|x64|AMD64") set(DEFAULT_ZIG_ARCH "x86_64") else() - message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}") + unsupported(CMAKE_SYSTEM_PROCESSOR) endif() if(APPLE) @@ -15,7 +13,7 @@ elseif(WIN32) elseif(LINUX) set(DEFAULT_ZIG_TARGET ${DEFAULT_ZIG_ARCH}-linux-gnu) else() - message(FATAL_ERROR "Unsupported operating system: ${CMAKE_SYSTEM_NAME}") + unsupported(CMAKE_SYSTEM_NAME) endif() optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET}) @@ -28,6 +26,8 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") set(DEFAULT_ZIG_OPTIMIZE "ReleaseSmall") elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") set(DEFAULT_ZIG_OPTIMIZE "Debug") +else() + unsupported(CMAKE_BUILD_TYPE) endif() # Since Bun 1.1, Windows has been built using ReleaseSafe. @@ -46,8 +46,9 @@ optionx(ZIG_OBJECT_FORMAT "obj|bc" "Output file format for Zig object files" DEF optionx(ZIG_VERSION STRING "The version of zig to use" DEFAULT "0.13.0") optionx(ZIG_LOCAL_CACHE_DIR FILEPATH "The path to local the zig cache directory" DEFAULT ${CACHE_PATH}/zig/local) optionx(ZIG_GLOBAL_CACHE_DIR FILEPATH "The path to the global zig cache directory" DEFAULT ${CACHE_PATH}/zig/global) -optionx(ZIG_BIN_CACHE_DIR FILEPATH "The path to the zig binary cache directory" DEFAULT ${CACHE_PATH}/zig/bin) -optionx(ZIG_REPOSITORY_PATH FILEPATH "The path to the Zig repository" DEFAULT ${CWD}/vendor/zig) + +setx(ZIG_REPOSITORY_PATH ${VENDOR_PATH}/zig) +setx(ZIG_PATH ${CACHE_PATH}/zig/bin) register_repository( NAME @@ -76,14 +77,14 @@ find_command( zig zig.exe PATHS - ${ZIG_BIN_CACHE_DIR} + ${ZIG_PATH} VERSION ${ZIG_VERSION} REQUIRED OFF ) -if(NOT CMAKE_ZIG_COMPILER MATCHES "NOTFOUND") +if(CMAKE_ZIG_COMPILER) return() endif() @@ -92,7 +93,7 @@ if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") elseif(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "amd64|x86_64|x64|AMD64") set(ZIG_HOST_ARCH "x86_64") else() - message(FATAL_ERROR "Unsupported architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}") + unsupported(CMAKE_HOST_SYSTEM_PROCESSOR) endif() if(CMAKE_HOST_APPLE) @@ -102,7 +103,7 @@ elseif(CMAKE_HOST_WIN32) elseif(CMAKE_HOST_UNIX) set(ZIG_HOST_OS "linux") else() - message(FATAL_ERROR "Unsupported operating system: ${CMAKE_HOST_SYSTEM_NAME}") + unsupported(CMAKE_HOST_SYSTEM_NAME) endif() set(ZIG_NAME zig-${ZIG_HOST_OS}-${ZIG_HOST_ARCH}-${ZIG_VERSION}) @@ -116,14 +117,27 @@ else() endif() setx(ZIG_DOWNLOAD_URL https://ziglang.org/download/${ZIG_VERSION}/${ZIG_FILENAME}) -file(DOWNLOAD ${ZIG_DOWNLOAD_URL} ${ZIG_BIN_CACHE_DIR}/${ZIG_FILENAME}) -file(ARCHIVE_EXTRACT INPUT ${ZIG_BIN_CACHE_DIR}/${ZIG_FILENAME} DESTINATION ${ZIG_BIN_CACHE_DIR}) -file(REMOVE ${ZIG_BIN_CACHE_DIR}/${ZIG_FILENAME}) -file(COPY ${ZIG_BIN_CACHE_DIR}/${ZIG_NAME}/${ZIG_EXE} DESTINATION ${ZIG_BIN_CACHE_DIR}) -file(REMOVE_RECURSE ${ZIG_BIN_CACHE_DIR}/${ZIG_NAME}) -file(CHMOD ${ZIG_BIN_CACHE_DIR}/${ZIG_EXE} PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) -setx(CMAKE_ZIG_COMPILER ${ZIG_BIN_CACHE_DIR}/${ZIG_EXE}) +file(DOWNLOAD ${ZIG_DOWNLOAD_URL} ${TMP_PATH}/${ZIG_FILENAME} SHOW_PROGRESS) +file(ARCHIVE_EXTRACT INPUT ${TMP_PATH}/${ZIG_FILENAME} DESTINATION ${TMP_PATH} TOUCH) +file(REMOVE ${TMP_PATH}/${ZIG_FILENAME}) +file(COPY ${TMP_PATH}/${ZIG_NAME}/${ZIG_EXE} DESTINATION ${ZIG_PATH}) +file(CHMOD ${ZIG_PATH}/${ZIG_EXE} PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) +setx(CMAKE_ZIG_COMPILER ${ZIG_PATH}/${ZIG_EXE}) if(NOT WIN32) - file(CREATE_LINK ${ZIG_BIN_CACHE_DIR}/${ZIG_EXE} ${ZIG_BIN_CACHE_DIR}/zig.exe SYMBOLIC) + file(CREATE_LINK ${ZIG_PATH}/${ZIG_EXE} ${ZIG_PATH}/zig.exe SYMBOLIC) endif() + +# Some zig commands need the executable to be in the same directory as the zig repository +register_command( + COMMENT + "Creating symlink for zig" + COMMAND + ${CMAKE_COMMAND} -E copy ${ZIG_PATH}/${ZIG_EXE} ${ZIG_REPOSITORY_PATH}/${ZIG_EXE} + && ${CMAKE_COMMAND} -E create_symlink ${ZIG_REPOSITORY_PATH}/${ZIG_EXE} ${ZIG_REPOSITORY_PATH}/zig.exe + OUTPUTS + ${ZIG_REPOSITORY_PATH}/${ZIG_EXE} + ${ZIG_REPOSITORY_PATH}/zig.exe + TARGETS + clone-zig +) diff --git a/package.json b/package.json index c0ae4ff476..99e7ee6e16 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "build:debug": "bun run build", "build:valgrind": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Debug -DENABLE_BASELINE=ON -ENABLE_VALGRIND=ON -B build/debug-valgrind", "build:release": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -B build/release", - "build:ci": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=ON -DCI=true -B build/release-ci --verbose", + "build:ci": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=ON -DCI=true -B build/release-ci --verbose --fresh", "build:assert": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_ASSERTIONS=ON -DENABLE_LOGS=ON -B build/release-assert", "build:logs": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DENABLE_LOGS=ON -B build/release-logs", "build:safe": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DZIG_OPTIMIZE=ReleaseSafe -B build/release-safe", @@ -49,7 +49,7 @@ "test": "node scripts/runner.node.mjs ./build/bun-debug", "test:release": "node scripts/runner.node.mjs ./build-release/bun", "banned": "bun packages/bun-internal-test/src/linter.ts", - "zig": "build/debug/cache/zig/bin/zig.exe", + "zig": "vendor/zig/zig.exe", "zig:fmt": "bun run zig fmt src/*.zig src/*/*.zig src/*/*/*.zig src/*/*/*/*.zig", "zig:check": "bun run zig build check --summary new", "zig:check-all": "bun run zig build check-all --summary new", diff --git a/scripts/build.mjs b/scripts/build.mjs index 0bac459510..82f3bc7b4e 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -30,7 +30,7 @@ const buildFlags = [ async function build(args) { const startTime = Date.now(); - + if (process.platform === "win32" && !process.env["VSINSTALLDIR"]) { const shellPath = join(import.meta.dirname, "vs-shell.ps1"); const scriptPath = import.meta.filename; @@ -138,7 +138,7 @@ async function build(args) { ); } - printDuration('total', Date.now() - startTime); + printDuration("total", Date.now() - startTime); } function cmakePath(path) { @@ -209,8 +209,9 @@ async function spawn(command, args, options, label) { label ??= basename(command); + const pipe = process.env.CI === "true"; const subprocess = nodeSpawn(command, effectiveArgs, { - stdio: "pipe", + stdio: pipe ? "pipe" : "inherit", ...options, }); @@ -219,24 +220,29 @@ async function spawn(command, args, options, label) { timestamp = Date.now(); }); - const stdout = new Promise(resolve => { - subprocess.stdout.on("end", resolve); - subprocess.stdout.on("data", data => process.stdout.write(data)); - }); + let done; + if (pipe) { + const stdout = new Promise(resolve => { + subprocess.stdout.on("end", resolve); + subprocess.stdout.on("data", data => process.stdout.write(data)); + }); - const stderr = new Promise(resolve => { - subprocess.stderr.on("end", resolve); - subprocess.stderr.on("data", data => process.stderr.write(data)); - }); + const stderr = new Promise(resolve => { + subprocess.stderr.on("end", resolve); + subprocess.stderr.on("data", data => process.stderr.write(data)); + }); - const done = Promise.all([stdout, stderr]); + done = Promise.all([stdout, stderr]); + } const { error, exitCode, signalCode } = await new Promise(resolve => { subprocess.on("error", error => resolve({ error })); subprocess.on("exit", (exitCode, signalCode) => resolve({ exitCode, signalCode })); }); - await done; + if (done) { + await done; + } printDuration(label, Date.now() - timestamp);