Skip to content

Commit ca5890b

Browse files
mborlandDarkArc
authored andcommitted
Add automatic build configuration []
This change additionally: - disables the in-source build (to prevent conflicts with .envrc), - makes EDG_BASE a cached variable more closely associated with the build, - and fixes a bug with Unix Makefiles.
1 parent 158320e commit ca5890b

9 files changed

Lines changed: 177 additions & 19 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ endif()
1414
# set the project name
1515
project(cpfe)
1616

17+
# Check for attempts to use an in-source build.
18+
if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
19+
message(FATAL_ERROR
20+
"In-source builds are not supported: please specify a build "
21+
"directory with -B or use a one of the available presets.")
22+
endif()
23+
1724
# Set a common directory for "binaries"
1825
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
1926
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
@@ -89,19 +96,37 @@ set(EDG_EAGER_REBUILD_LIB FALSE CACHE BOOL
8996
# Support for 32-bit build
9097
set(32BIT_BUILD FALSE CACHE BOOL "Build cpfe as a 32-bit executable")
9198

99+
# Detect the defaults (macro configuration, EDG_BASE, etc.) for this host and
100+
# compiler, used when a configuration doesn't specify them.
101+
include(${CMAKE_SOURCE_DIR}/cmake/host-defaults.cmake)
102+
detect_host_defaults()
103+
92104
# Include and initialize supporting logic for EDG cmake macro configurations.
93105
include(${CMAKE_SOURCE_DIR}/cmake/macro-conf.cmake)
94106
init_macro_configuration_support()
95107

108+
# Resolve EDG_BASE, preferring the environment over the host default. The
109+
# result is exported by environment.sh for use by eccp.
110+
if(NOT "$ENV{EDG_BASE}" STREQUAL "")
111+
set(EDG_BASE "$ENV{EDG_BASE}" CACHE STRING "The EDG base to use.")
112+
else()
113+
set(EDG_BASE "${EDG_HOST_BASE}" CACHE STRING "The EDG base to use.")
114+
endif()
115+
96116
add_subdirectory(util)
97117
add_subdirectory(src)
98118

99119
if($CACHE{EDG_BUILD_LIB})
100120
if(NOT WIN32)
101121
add_subdirectory(lib_src)
102122
# Check edg_eccp_config/EDG_BASE setup
103-
message(STATUS "Checking for edg_eccp_config in \"$ENV{EDG_BASE}\".")
104-
if(NOT DEFINED ENV{EDG_BASE} OR NOT EXISTS $ENV{EDG_BASE}/edg_eccp_config)
123+
message(STATUS
124+
"Checking for edg_eccp_config in \"$CACHE{EDG_BASE}\".")
125+
if("$CACHE{EDG_BASE}" STREQUAL "")
126+
message(FATAL_ERROR
127+
"There is no default EDG_BASE for this host and compiler; "
128+
"please set EDG_BASE to a folder with an \"edg_eccp_config\".")
129+
elseif(NOT EXISTS "$CACHE{EDG_BASE}/edg_eccp_config")
105130
message(FATAL_ERROR
106131
"Please set EDG_BASE to a folder with an \"edg_eccp_config\".")
107132
endif()

‎HACKING.md‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ and additionally provides direct access to tools like `edgy`, `cmake`, and
5555

5656
## Native
5757

58+
When configuring natively, CMake selects the macro configuration
59+
(`EDG_MACRO_CONF`), `EDG_BASE`, and the runtime libraries (`EDG_CPP_RT_LIBS`)
60+
that match the host platform, compiler, and build type, so a plain configure
61+
(such as an IDE's default CMake profile) behaves like the corresponding preset.
62+
Setting any of these explicitly (e.g., with `export EDG_BASE=...` or
63+
`-DEDG_MACRO_CONF=...`) overrides the automatic selection.
64+
5865
### Linux
5966

6067
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
7178
`edg-docker-test` (from the EDG project directory):
7279

7380
```
74-
export EDG_BASE="$PWD/bases/docker/dev-env/gcc"
7581
export EDG_GCC_INCL_SCRAPE=$(edg-scrape-compiler gcc --lang c++ includes)
7682
export EDG_GCC_CINCL_SCRAPE=$(edg-scrape-compiler gcc --lang c includes)
7783
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
108114
`edg-docker-test` process (from the EDG project directory):
109115

110116
```
111-
export EDG_BASE="$PWD/bases/cmake-native/macos-arm/clang"
112117
export EDG_CLANG_INCL_SCRAPE=$(edg-scrape-compiler clang --lang c++ includes)
113118
export EDG_CLANG_CINCL_SCRAPE=$(edg-scrape-compiler clang --lang c includes)
114119
export EDG_CLANG_VER_SCRAPE=$(edg-scrape-compiler clang version)
@@ -147,8 +152,8 @@ edgy
147152
> is not an official testing process that works directly on Windows. Once the
148153
> Bash dependencies are removed, testing directly on Windows should become
149154
> possible. At this point remaining issues will be similar to the challenges
150-
> faced with running tests on MacOS (namely different system tools and different
151-
> system headers).
155+
> faced with running tests on MacOS (namely different system tools and
156+
> different system headers).
152157
153158
To get started with Windows-native development, make sure `msvc`, `python`, and
154159
`cmake` are installed (additionally -- if not using the Visual Studio IDE --

‎cmake/host-defaults.cmake‎

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Part of the EDG Compiler Project, under the Apache License v2.0 with LLVM
2+
# Exceptions.
3+
# See https://edgcpp.org/LICENSE.txt for license information.
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
# Defaults derived from the host platform and compiler, so that a configure
7+
# which doesn't use a preset (e.g., an IDE's default CMake profile) makes the
8+
# same selections as the matching preset in CMakePresets.json.
9+
10+
function(detect_host_defaults)
11+
# This function sets up the variables:
12+
# - EDG_HOST_MACRO_CONF: the debug macro configuration for this host and
13+
# compiler (the release configuration, if any, adds a "-release"
14+
# suffix), or "" if none is known.
15+
# - EDG_HOST_BASE: the default EDG_BASE directory, or "" if none is known.
16+
# - EDG_HOST_CPP_RT_LIBS: the default EDG_CPP_RT_LIBS list.
17+
set(macro_conf "")
18+
set(base "")
19+
set(cpp_rt_libs "")
20+
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" processor)
21+
22+
if(APPLE)
23+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
24+
if(processor MATCHES "^(arm64|aarch64)$")
25+
set(macro_conf "macos-arm-clang")
26+
set(base "cmake-native/macos-arm/clang")
27+
set(cpp_rt_libs "macos_arm64")
28+
elseif(processor STREQUAL "x86_64")
29+
set(macro_conf "macos-x86-clang")
30+
set(base "cmake-native/macos-x86_64/clang")
31+
set(cpp_rt_libs "macos_x86_64")
32+
endif()
33+
endif()
34+
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
35+
# The Linux configurations all target an x86_64 (or, for 32-bit builds,
36+
# i686) host.
37+
if(processor MATCHES "^(x86_64|amd64)$")
38+
if($CACHE{32BIT_BUILD})
39+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
40+
set(macro_conf "linux-i686-gcc")
41+
set(base "docker/dev-env/gcc-i686")
42+
set(cpp_rt_libs "linux_i686 win32")
43+
endif()
44+
else()
45+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
46+
set(macro_conf "linux-gcc")
47+
set(base "docker/dev-env/gcc")
48+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
49+
set(macro_conf "linux-clang")
50+
set(base "docker/dev-env/clang")
51+
endif()
52+
if(NOT macro_conf STREQUAL "")
53+
string(CONCAT cpp_rt_libs
54+
"linux_riscv64 linux_riscv32 linux_aarch64 linux_armv7 "
55+
"linux_i686 linux_x86_64 win32 win64")
56+
endif()
57+
endif()
58+
endif()
59+
elseif(WIN32 AND MSVC)
60+
if(processor MATCHES "^(x86_64|amd64)$")
61+
set(macro_conf "windows-msvc")
62+
endif()
63+
endif()
64+
65+
if(NOT base STREQUAL "")
66+
set(base "${CMAKE_SOURCE_DIR}/bases/${base}")
67+
endif()
68+
69+
# Export shared state.
70+
set(EDG_HOST_MACRO_CONF "${macro_conf}" PARENT_SCOPE)
71+
set(EDG_HOST_BASE "${base}" PARENT_SCOPE)
72+
set(EDG_HOST_CPP_RT_LIBS "${cpp_rt_libs}" PARENT_SCOPE)
73+
endfunction()
74+
75+
function(host_macro_configuration result_var build_type)
76+
# Set result_var to the host's macro configuration for build_type, or to ""
77+
# if there isn't one.
78+
set(result "")
79+
if(NOT EDG_HOST_MACRO_CONF STREQUAL "")
80+
set(result "${EDG_HOST_MACRO_CONF}")
81+
string(TOUPPER "${build_type}" build_type)
82+
if(build_type MATCHES "^(RELEASE|RELWITHDEBINFO|MINSIZEREL)$")
83+
string(APPEND result "-release")
84+
endif()
85+
if(NOT IS_DIRECTORY "${CMAKE_SOURCE_DIR}/cmake/macro-conf/${result}")
86+
set(result "")
87+
endif()
88+
endif()
89+
set(${result_var} "${result}" PARENT_SCOPE)
90+
endfunction()

‎cmake/macro-conf.cmake‎

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,46 @@ else()
1414
PATHS "${CMAKE_SOURCE_DIR}/dev_tools/bin")
1515
endif()
1616

17-
function(init_macro_configuration_support)
18-
set(default "")
19-
20-
# Migrate "EDG_BASE" to "MACRO_CONF"
21-
if(DEFINED CACHE{EDG_BASE})
22-
message(STATUS "Migrating EDG_BASE -> EDG_MACRO_CONF")
23-
set(default "$CACHE{EDG_BASE}")
24-
unset(EDG_BASE CACHE)
17+
function(resolve_macro_configuration result_var macro_conf build_type)
18+
# Set result_var to macro_conf, or, if that's empty, to the host's macro
19+
# configuration for build_type.
20+
set(result "${macro_conf}")
21+
if(result STREQUAL "")
22+
host_macro_configuration(result "${build_type}")
23+
if(result STREQUAL "")
24+
message(WARNING
25+
"No macro configuration matches this host, compiler, and "
26+
"build type \"${build_type}\"; set EDG_MACRO_CONF or use a "
27+
"preset from CMakePresets.json.")
28+
else()
29+
message(STATUS "Auto-selected macro configuration \"${result}\" for "
30+
"build type \"${build_type}\".")
31+
endif()
2532
endif()
33+
set(${result_var} "${result}" PARENT_SCOPE)
34+
endfunction()
2635

27-
set(EDG_MACRO_CONF ${default}
28-
CACHE STRING "The debug macro configuration to use")
36+
function(init_macro_configuration_support)
37+
# An empty macro configuration selects the one matching the host platform,
38+
# compiler, and build type. The selections are exported as
39+
# CACHE{EDG_MACRO_CONF} (single-configuration generators) or
40+
# CACHE{EDG_DEBUG_MACRO_CONF} and CACHE{EDG_RELEASE_MACRO_CONF}
41+
# (multi-configuration generators).
42+
if(CMAKE_CONFIGURATION_TYPES)
43+
resolve_macro_configuration(debug_conf "$CACHE{EDG_DEBUG_MACRO_CONF}"
44+
"Debug")
45+
resolve_macro_configuration(release_conf
46+
"$CACHE{EDG_RELEASE_MACRO_CONF}" "Release")
47+
set(EDG_DEBUG_MACRO_CONF "${debug_conf}" CACHE STRING
48+
"The macro configuration for debug builds")
49+
set(EDG_RELEASE_MACRO_CONF "${release_conf}" CACHE STRING
50+
"The macro configuration for release builds")
51+
else()
52+
resolve_macro_configuration(conf "${EDG_MACRO_CONF}"
53+
"${CMAKE_BUILD_TYPE}")
54+
set(EDG_MACRO_CONF "${conf}" CACHE STRING
55+
"The macro configuration for the build")
56+
endif()
2957
endfunction()
3058

3159
function(process_macro_configuration_setup target macro_conf)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto Generated Default File
2+
import <default/cpfe-cp>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto Generated Default File
2+
import <default/cpfe-cp>

‎cmake/wrapper.cmake‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ string(JOIN "\n" static_env
1313
"export EDG_MUNCH_PATH=\"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_munch\""
1414
"export EDG_DECODE_PATH=\"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_decode\""
1515
"export EDG_PRELINK_PATH=\"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_prelink\""
16-
"export ECCP=\"${CMAKE_SOURCE_DIR}/util/eccp.sh\"")
16+
"export ECCP=\"${CMAKE_SOURCE_DIR}/util/eccp.sh\""
17+
"export EDG_BASE=\"$CACHE{EDG_BASE}\"")
1718

1819
string(JOIN "\n" lazy_static_env
1920
"export CPFE=\"\${CPFE:-${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cpfe}\""
@@ -22,7 +23,8 @@ string(JOIN "\n" lazy_static_env
2223
"export EDG_MUNCH_PATH=\"\${EDG_MUNCH_PATH:-${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_munch}\""
2324
"export EDG_DECODE_PATH=\"\${EDG_DECODE_PATH:-${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_decode}\""
2425
"export EDG_PRELINK_PATH=\"\${EDG_PRELINK_PATH:-${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/edg_prelink}\""
25-
"export ECCP=\"\${ECCP:-${CMAKE_SOURCE_DIR}/util/eccp.sh}\"")
26+
"export ECCP=\"\${ECCP:-${CMAKE_SOURCE_DIR}/util/eccp.sh}\""
27+
"export EDG_BASE=\"\${EDG_BASE:-$CACHE{EDG_BASE}}\"")
2628

2729
FILE(WRITE ${CMAKE_BINARY_DIR}/environment.sh "${static_env}\n")
2830
FILE(WRITE ${CMAKE_BINARY_DIR}/.envrc

‎lib_src/cmake/lib_build_platform.cmake‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# Define and expand an EDG_CPP_RT_LIBS cache variable storing the list of
77
# enabled edg-cpp-rt libraries.
8-
set(EDG_CPP_RT_LIBS "" CACHE STRING
8+
set(EDG_CPP_RT_LIBS "${EDG_HOST_CPP_RT_LIBS}" CACHE STRING
99
"The EDG C++ runtime libs to include in the default target")
1010
set(EXPANDED_CPP_RT_LIBS $CACHE{EDG_CPP_RT_LIBS})
1111
separate_arguments(EXPANDED_CPP_RT_LIBS)

‎lib_src/cmake/lib_build_support.cmake‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ function(add_edg_cpp_rt_target target_name)
113113
# Create an empty variable to be used as a list of object files.
114114
set(obj_files "")
115115

116+
# Explicitly create the cache directory (needed for some generators -- e.g.,
117+
# Unix Makefiles).
118+
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${target_name}-cache")
119+
116120
# Add the build for the main object files.
117121
foreach(bare_file_name IN LISTS BARE_FILE_NAMES)
118122
set(src_file_name "${PROJECT_SOURCE_DIR}/${bare_file_name}.c")

0 commit comments

Comments
 (0)