From 8c76d45a9530397db1c80deb3009bd04a70fd891 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 30 Sep 2026 15:57:17 -0400 Subject: [PATCH 1/3] Add automatic configuration if EDG_HOST_BASE is not specified --- CMakeLists.txt | 22 ++++++- cmake/host-defaults.cmake | 90 ++++++++++++++++++++++++++ cmake/macro-conf.cmake | 49 ++++++++++++-- cmake/wrapper.cmake | 8 +++ lib_src/cmake/lib_build_platform.cmake | 2 +- 5 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 cmake/host-defaults.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f5935d0fe..709320a6e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,10 +89,23 @@ set(EDG_EAGER_REBUILD_LIB FALSE CACHE BOOL # Support for 32-bit build set(32BIT_BUILD FALSE CACHE BOOL "Build cpfe as a 32-bit executable") +# Detect the defaults (macro configuration, EDG_BASE, etc.) for this host and +# compiler, used when a configuration doesn't specify them. +include(${CMAKE_SOURCE_DIR}/cmake/host-defaults.cmake) +detect_host_defaults() + # Include and initialize supporting logic for EDG cmake macro configurations. include(${CMAKE_SOURCE_DIR}/cmake/macro-conf.cmake) init_macro_configuration_support() +# Resolve EDG_BASE, preferring the environment over the host default. The +# result is exported by environment.sh for use by eccp. +if(NOT "$ENV{EDG_BASE}" STREQUAL "") + set(EDG_RESOLVED_BASE "$ENV{EDG_BASE}") +else() + set(EDG_RESOLVED_BASE "${EDG_HOST_BASE}") +endif() + add_subdirectory(util) add_subdirectory(src) @@ -100,8 +113,13 @@ if($CACHE{EDG_BUILD_LIB}) if(NOT WIN32) add_subdirectory(lib_src) # Check edg_eccp_config/EDG_BASE setup - message(STATUS "Checking for edg_eccp_config in \"$ENV{EDG_BASE}\".") - if(NOT DEFINED ENV{EDG_BASE} OR NOT EXISTS $ENV{EDG_BASE}/edg_eccp_config) + message(STATUS + "Checking for edg_eccp_config in \"${EDG_RESOLVED_BASE}\".") + if(EDG_RESOLVED_BASE STREQUAL "") + message(FATAL_ERROR + "There is no default EDG_BASE for this host and compiler; " + "please set EDG_BASE to a folder with an \"edg_eccp_config\".") + elseif(NOT EXISTS "${EDG_RESOLVED_BASE}/edg_eccp_config") message(FATAL_ERROR "Please set EDG_BASE to a folder with an \"edg_eccp_config\".") endif() diff --git a/cmake/host-defaults.cmake b/cmake/host-defaults.cmake new file mode 100644 index 0000000000..d74ac3c842 --- /dev/null +++ b/cmake/host-defaults.cmake @@ -0,0 +1,90 @@ +# Part of the EDG Compiler Project, under the Apache License v2.0 with LLVM +# Exceptions. +# See https://edgcpp.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +# Defaults derived from the host platform and compiler, so that a configure +# which doesn't use a preset (e.g., an IDE's default CMake profile) makes the +# same selections as the matching preset in CMakePresets.json. + +function(detect_host_defaults) + # This function sets up the variables: + # - EDG_HOST_MACRO_CONF: the debug macro configuration for this host and + # compiler (the release configuration, if any, adds a "-release" + # suffix), or "" if none is known. + # - EDG_HOST_BASE: the default EDG_BASE directory, or "" if none is known. + # - EDG_HOST_CPP_RT_LIBS: the default EDG_CPP_RT_LIBS list. + set(macro_conf "") + set(base "") + set(cpp_rt_libs "") + string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" processor) + + if(APPLE) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if(processor MATCHES "^(arm64|aarch64)$") + set(macro_conf "macos-arm-clang") + set(base "cmake-native/macos-arm/clang") + set(cpp_rt_libs "macos_arm64") + elseif(processor STREQUAL "x86_64") + set(macro_conf "macos-x86-clang") + set(base "cmake-native/macos-x86_64/clang") + set(cpp_rt_libs "macos_x86_64") + endif() + endif() + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # The Linux configurations all target an x86_64 (or, for 32-bit builds, + # i686) host. + if(processor MATCHES "^(x86_64|amd64)$") + if($CACHE{32BIT_BUILD}) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(macro_conf "linux-i686-gcc") + set(base "docker/dev-env/gcc-i686") + set(cpp_rt_libs "linux_i686 win32") + endif() + else() + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(macro_conf "linux-gcc") + set(base "docker/dev-env/gcc") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(macro_conf "linux-clang") + set(base "docker/dev-env/clang") + endif() + if(NOT macro_conf STREQUAL "") + string(CONCAT cpp_rt_libs + "linux_riscv64 linux_riscv32 linux_aarch64 linux_armv7 " + "linux_i686 linux_x86_64 win32 win64") + endif() + endif() + endif() + elseif(WIN32 AND MSVC) + if(processor MATCHES "^(x86_64|amd64)$") + set(macro_conf "windows-msvc") + endif() + endif() + + if(NOT base STREQUAL "") + set(base "${CMAKE_SOURCE_DIR}/bases/${base}") + endif() + + # Export shared state. + set(EDG_HOST_MACRO_CONF "${macro_conf}" PARENT_SCOPE) + set(EDG_HOST_BASE "${base}" PARENT_SCOPE) + set(EDG_HOST_CPP_RT_LIBS "${cpp_rt_libs}" PARENT_SCOPE) +endfunction() + +function(host_macro_configuration result_var build_type) + # Set result_var to the host's macro configuration for build_type, or to "" + # if there isn't one. + set(result "") + if(NOT EDG_HOST_MACRO_CONF STREQUAL "") + set(result "${EDG_HOST_MACRO_CONF}") + string(TOUPPER "${build_type}" build_type) + if(build_type MATCHES "^(RELEASE|RELWITHDEBINFO|MINSIZEREL)$") + string(APPEND result "-release") + endif() + if(NOT IS_DIRECTORY "${CMAKE_SOURCE_DIR}/cmake/macro-conf/${result}") + set(result "") + endif() + endif() + set(${result_var} "${result}" PARENT_SCOPE) +endfunction() diff --git a/cmake/macro-conf.cmake b/cmake/macro-conf.cmake index 0bd41af94e..fc11283de0 100644 --- a/cmake/macro-conf.cmake +++ b/cmake/macro-conf.cmake @@ -26,6 +26,43 @@ function(init_macro_configuration_support) set(EDG_MACRO_CONF ${default} CACHE STRING "The debug macro configuration to use") + + # An empty macro configuration selects the one matching the host platform, + # compiler, and build type. The selections are exported as + # EDG_EFFECTIVE_MACRO_CONF (single-configuration generators) or + # EDG_EFFECTIVE_DEBUG_MACRO_CONF and EDG_EFFECTIVE_RELEASE_MACRO_CONF + # (multi-configuration generators). + if(CMAKE_CONFIGURATION_TYPES) + resolve_macro_configuration(debug_conf "$CACHE{EDG_DEBUG_MACRO_CONF}" + "Debug") + resolve_macro_configuration(release_conf + "$CACHE{EDG_RELEASE_MACRO_CONF}" "Release") + set(EDG_EFFECTIVE_DEBUG_MACRO_CONF "${debug_conf}" PARENT_SCOPE) + set(EDG_EFFECTIVE_RELEASE_MACRO_CONF "${release_conf}" PARENT_SCOPE) + else() + resolve_macro_configuration(conf "$CACHE{EDG_MACRO_CONF}" + "${CMAKE_BUILD_TYPE}") + set(EDG_EFFECTIVE_MACRO_CONF "${conf}" PARENT_SCOPE) + endif() +endfunction() + +function(resolve_macro_configuration result_var macro_conf build_type) + # Set result_var to macro_conf, or, if that's empty, to the host's macro + # configuration for build_type. + set(result "${macro_conf}") + if(result STREQUAL "") + host_macro_configuration(result "${build_type}") + if(result STREQUAL "") + message(WARNING + "No macro configuration matches this host, compiler, and " + "build type \"${build_type}\"; set EDG_MACRO_CONF or use a " + "preset from CMakePresets.json.") + else() + message(STATUS "Auto-selected macro configuration \"${result}\" for " + "build type \"${build_type}\".") + endif() + endif() + set(${result_var} "${result}" PARENT_SCOPE) endfunction() function(process_macro_configuration_setup target macro_conf) @@ -124,17 +161,17 @@ function(macro_configuration_to_compile_definitions target) if(CMAKE_CONFIGURATION_TYPES) # Capture the definitions for a debug configuration. configure_definitions_as_values("${target}" - "$CACHE{EDG_DEBUG_MACRO_CONF}") + "${EDG_EFFECTIVE_DEBUG_MACRO_CONF}") set(debug_args "${configured_cmakedef_definitions}") # Capture the definitions for a release configuration. configure_definitions_as_values("${target}" - "$CACHE{EDG_RELEASE_MACRO_CONF}") + "${EDG_EFFECTIVE_RELEASE_MACRO_CONF}") set(release_args "${configured_cmakedef_definitions}") # Conditionally add either the debug or release configuration defines. add_compile_definitions( "$,${debug_args},${release_args}>") else() - configure_definitions_as_values("${target}" "$CACHE{EDG_MACRO_CONF}") + configure_definitions_as_values("${target}" "${EDG_EFFECTIVE_MACRO_CONF}") add_compile_definitions(${configured_cmakedef_definitions}) endif() endfunction() @@ -145,12 +182,12 @@ function(macro_configuration_to_defines target) if(CMAKE_CONFIGURATION_TYPES) # Write out a defines.h for the debug configuration. configure_definitions_as_defines("${target}" - "$CACHE{EDG_DEBUG_MACRO_CONF}") + "${EDG_EFFECTIVE_DEBUG_MACRO_CONF}") FILE(WRITE "${PROJECT_HEADER_OUTPUT_DIRECTORY}/cmake_debug_defines.h" "${configured_cmakedef_definitions}") # Write out a defines.h for the release configuration. configure_definitions_as_defines("${target}" - "$CACHE{EDG_RELEASE_MACRO_CONF}") + "${EDG_EFFECTIVE_RELEASE_MACRO_CONF}") FILE(WRITE "${PROJECT_HEADER_OUTPUT_DIRECTORY}/cmake_release_defines.h" "${configured_cmakedef_definitions}") # Generate a defines.h file that will include either the debug or @@ -166,7 +203,7 @@ function(macro_configuration_to_defines target) add_compile_definitions( "$,CMAKE_DEBUG=1,CMAKE_DEBUG=0>") else() - configure_definitions_as_defines("${target}" "$CACHE{EDG_MACRO_CONF}") + configure_definitions_as_defines("${target}" "${EDG_EFFECTIVE_MACRO_CONF}") FILE(WRITE "${cmake_defines_file_path}" "${configured_cmakedef_definitions}") endif() diff --git a/cmake/wrapper.cmake b/cmake/wrapper.cmake index bf4fbdf4d1..9e20bc1d25 100644 --- a/cmake/wrapper.cmake +++ b/cmake/wrapper.cmake @@ -24,6 +24,14 @@ string(JOIN "\n" lazy_static_env "export EDG_PRELINK_PATH=\"\${EDG_PRELINK_PATH:-${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_prelink}\"" "export ECCP=\"\${ECCP:-${CMAKE_SOURCE_DIR}/util/eccp.sh}\"") +# Default EDG_BASE (without overriding an explicit setting) so that eccp works +# without it being set. +if(NOT EDG_RESOLVED_BASE STREQUAL "") + set(base_env "export EDG_BASE=\"\${EDG_BASE:-${EDG_RESOLVED_BASE}}\"") + string(APPEND static_env "\n${base_env}") + string(APPEND lazy_static_env "\n${base_env}") +endif() + FILE(WRITE ${CMAKE_BINARY_DIR}/environment.sh "${static_env}\n") FILE(WRITE ${CMAKE_BINARY_DIR}/.envrc "${static_env}\nsource_env \"${CMAKE_SOURCE_DIR}/.envrc\"\n") diff --git a/lib_src/cmake/lib_build_platform.cmake b/lib_src/cmake/lib_build_platform.cmake index 73860df4fc..22109741fa 100644 --- a/lib_src/cmake/lib_build_platform.cmake +++ b/lib_src/cmake/lib_build_platform.cmake @@ -5,7 +5,7 @@ # Define and expand an EDG_CPP_RT_LIBS cache variable storing the list of # enabled edg-cpp-rt libraries. -set(EDG_CPP_RT_LIBS "" CACHE STRING +set(EDG_CPP_RT_LIBS "${EDG_HOST_CPP_RT_LIBS}" CACHE STRING "The EDG C++ runtime libs to include in the default target") set(EXPANDED_CPP_RT_LIBS $CACHE{EDG_CPP_RT_LIBS}) separate_arguments(EXPANDED_CPP_RT_LIBS) From fdcd1211a910172f5d1f83266c5bbe6bd102f80e Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 30 Sep 2026 15:58:12 -0400 Subject: [PATCH 2/3] Add missing macos-arm-clang cpfe-cp.cmakedef files --- cmake/macro-conf/macos-arm-clang-release/cpfe-cp.cmakedef | 2 ++ cmake/macro-conf/macos-arm-clang/cpfe-cp.cmakedef | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 cmake/macro-conf/macos-arm-clang-release/cpfe-cp.cmakedef create mode 100644 cmake/macro-conf/macos-arm-clang/cpfe-cp.cmakedef diff --git a/cmake/macro-conf/macos-arm-clang-release/cpfe-cp.cmakedef b/cmake/macro-conf/macos-arm-clang-release/cpfe-cp.cmakedef new file mode 100644 index 0000000000..9d063d30b4 --- /dev/null +++ b/cmake/macro-conf/macos-arm-clang-release/cpfe-cp.cmakedef @@ -0,0 +1,2 @@ +# Auto Generated Default File +import diff --git a/cmake/macro-conf/macos-arm-clang/cpfe-cp.cmakedef b/cmake/macro-conf/macos-arm-clang/cpfe-cp.cmakedef new file mode 100644 index 0000000000..9d063d30b4 --- /dev/null +++ b/cmake/macro-conf/macos-arm-clang/cpfe-cp.cmakedef @@ -0,0 +1,2 @@ +# Auto Generated Default File +import From 26f6be6e773b3387a71c45651553ee8cee38e5f4 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 30 Sep 2026 15:58:31 -0400 Subject: [PATCH 3/3] Update config instructions in HACKING.md --- HACKING.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/HACKING.md b/HACKING.md index eb5006d2a5..eb221cac3e 100644 --- a/HACKING.md +++ b/HACKING.md @@ -55,6 +55,13 @@ and additionally provides direct access to tools like `edgy`, `cmake`, and ## Native +When configuring natively, CMake selects the macro configuration +(`EDG_MACRO_CONF`), `EDG_BASE`, and the runtime libraries (`EDG_CPP_RT_LIBS`) +that match the host platform, compiler, and build type, so a plain configure +(such as an IDE's default CMake profile) behaves like the corresponding preset. +Setting any of these explicitly (e.g., with `export EDG_BASE=...` or +`-DEDG_MACRO_CONF=...`) overrides the automatic selection. + ### Linux To get started with Linux-native development, make sure `g++` and `cmake` are @@ -71,7 +78,6 @@ It should then be possible to follow the build proceedure above with the `edg-docker-test` (from the EDG project directory): ``` -export EDG_BASE="$PWD/bases/docker/dev-env/gcc" export EDG_GCC_INCL_SCRAPE=$(edg-scrape-compiler gcc --lang c++ includes) export EDG_GCC_CINCL_SCRAPE=$(edg-scrape-compiler gcc --lang c includes) export EDG_GCC_VER_SCRAPE=$(edg-scrape-compiler gcc version) @@ -108,7 +114,6 @@ It should then be possible to follow the build proceedure above with the `edg-docker-test` process (from the EDG project directory): ``` -export EDG_BASE="$PWD/bases/cmake-native/macos-arm/clang" export EDG_CLANG_INCL_SCRAPE=$(edg-scrape-compiler clang --lang c++ includes) export EDG_CLANG_CINCL_SCRAPE=$(edg-scrape-compiler clang --lang c includes) export EDG_CLANG_VER_SCRAPE=$(edg-scrape-compiler clang version)