Skip to content

Commit 27a157b

Browse files
committed
Improve command detection in CMake
1 parent 07fd814 commit 27a157b

File tree

8 files changed

+139
-98
lines changed

8 files changed

+139
-98
lines changed

.github/workflows/clang-format.yml

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ jobs:
3030
name: clang-format
3131
runs-on: ubuntu-latest
3232
steps:
33-
- run: sudo rm /usr/bin/clang-format
3433
- name: Checkout
3534
uses: actions/checkout@v4
3635
with:
@@ -49,20 +48,12 @@ jobs:
4948
- name: Install LLVM
5049
run: |
5150
curl -fsSL https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.LLVM_VERSION_MAJOR }} all
52-
- run: ls -l /usr/lib/llvm-${LLVM_VERSION_MAJOR}/bin/
53-
- run: echo "/usr/lib/llvm-${LLVM_VERSION_MAJOR}/bin/" >> $GITHUB_PATH
54-
- name: Clang Format Version
55-
env:
56-
ENABLE_CCACHE: OFF
57-
LLVM_VERSION: ${{ env.LLVM_VERSION }}
58-
run: |
59-
bun run clang-format:version
6051
- name: Clang Format
6152
env:
6253
ENABLE_CCACHE: OFF
6354
LLVM_VERSION: ${{ env.LLVM_VERSION }}
6455
run: |
65-
bun run clang-format
56+
bun run clang-format:diff
6657
- name: Commit
6758
uses: stefanzweifel/git-auto-commit-action@v5
6859
with:

CMakeLists.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ include(BuildBun)
4343

4444
# --- Analysis ---
4545

46-
include(RunClangFormat)
47-
include(RunClangTidy)
48-
include(RunZigFormat)
46+
optionx(ENABLE_ANALYSIS BOOL "If analysis targets should be enabled" DEFAULT OFF)
4947

50-
if (ENABLE_PRETTIER)
48+
if(ENABLE_ANALYSIS)
49+
include(RunClangFormat)
50+
include(RunClangTidy)
51+
include(RunZigFormat)
5152
include(RunPrettier)
5253
endif()

bench/snippets/color.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Color from "color";
22
import tinycolor from "tinycolor2";
3-
import { bench, run, group } from "./runner.mjs";
3+
import { bench, group, run } from "./runner.mjs";
44

55
const inputs = ["#f00", "rgb(255, 0, 0)", "rgba(255, 0, 0, 1)", "hsl(0, 100%, 50%)"];
66

cmake/Globals.cmake

Lines changed: 121 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ macro(optionx variable type description)
3030
set(multiValueArgs)
3131
cmake_parse_arguments(${variable} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
3232

33+
if(DEFINED ${variable})
34+
set(${variable}_VALUE ${${variable}})
35+
endif()
36+
3337
if(NOT ${type} MATCHES "^(BOOL|STRING|FILEPATH|PATH|INTERNAL)$")
3438
set(${variable}_REGEX ${type})
3539
set(${variable}_TYPE STRING)
@@ -65,7 +69,9 @@ macro(optionx variable type description)
6569
message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\", please use ${${variable}_PREVIEW}=<${${variable}_REGEX}>")
6670
endif()
6771

68-
message(STATUS "Set ${variable}: ${${variable}}")
72+
if(NOT ${variable}_VALUE STREQUAL ${variable})
73+
message(STATUS "Set ${variable}: ${${variable}}")
74+
endif()
6975
endmacro()
7076

7177
# unsupported()
@@ -194,102 +200,153 @@ function(setenv variable value)
194200
message(STATUS "Set ENV ${variable}: ${value}")
195201
endfunction()
196202

197-
# check_command()
203+
# satisfies_range()
198204
# Description:
199-
# Checks if a command is available, used by `find_command()` as a validator.
205+
# Check if a version satisfies a version range
200206
# Arguments:
201-
# FOUND bool - The variable to set to true if the version is found
202-
# CMD string - The executable to check the version of
203-
function(check_command FOUND CMD)
204-
set(${FOUND} OFF PARENT_SCOPE)
205-
206-
if(${CMD} MATCHES "zig")
207-
set(CHECK_COMMAND ${CMD} version)
208-
else()
209-
set(CHECK_COMMAND ${CMD} --version)
207+
# version string - The version to check (e.g. "1.2.3")
208+
# range string - The range to check against (e.g. ">=1.2.3")
209+
# variable string - The variable to store the result in
210+
function(satisfies_range version range variable)
211+
if(range STREQUAL "ignore")
212+
set(${variable} ON PARENT_SCOPE)
213+
return()
210214
endif()
211215

212-
execute_process(
213-
COMMAND ${CHECK_COMMAND}
214-
RESULT_VARIABLE RESULT
215-
OUTPUT_VARIABLE OUTPUT
216-
OUTPUT_STRIP_TRAILING_WHITESPACE
217-
)
216+
set(${variable} OFF PARENT_SCOPE)
218217

219-
if(NOT RESULT EQUAL 0 OR NOT OUTPUT)
220-
message(DEBUG "${CHECK_COMMAND}, exited with code ${RESULT}")
218+
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${version}")
219+
if(NOT match)
221220
return()
222221
endif()
222+
set(version ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3})
223223

224-
parse_semver(${OUTPUT} CMD)
225-
parse_semver(${CHECK_COMMAND_VERSION} CHECK)
226-
227-
if(CHECK_COMMAND_VERSION MATCHES ">=")
228-
if(NOT CMD_VERSION VERSION_GREATER_EQUAL ${CHECK_VERSION})
229-
message(DEBUG "${CHECK_COMMAND}, actual: ${CMD_VERSION}, expected: ${CHECK_COMMAND_VERSION}")
230-
return()
231-
endif()
232-
elseif(CHECK_COMMAND_VERSION MATCHES ">")
233-
if(NOT CMD_VERSION VERSION_GREATER ${CHECK_VERSION})
234-
message(DEBUG "${CHECK_COMMAND}, actual: ${CMD_VERSION}, expected: ${CHECK_COMMAND_VERSION}")
235-
return()
236-
endif()
224+
string(REGEX MATCH "(>=|<=|>|<)?([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${range}")
225+
if(NOT match)
226+
return()
227+
endif()
228+
set(comparator ${CMAKE_MATCH_1})
229+
set(range ${CMAKE_MATCH_2}.${CMAKE_MATCH_3}.${CMAKE_MATCH_4})
230+
231+
if(comparator STREQUAL ">=")
232+
set(comparator VERSION_GREATER_EQUAL)
233+
elseif(comparator STREQUAL ">")
234+
set(comparator VERSION_GREATER)
235+
elseif(comparator STREQUAL "<=")
236+
set(comparator VERSION_LESS_EQUAL)
237+
elseif(comparator STREQUAL "<")
238+
set(comparator VERSION_LESS)
237239
else()
238-
if(NOT CMD_VERSION VERSION_EQUAL ${CHECK_VERSION})
239-
message(DEBUG "${CHECK_COMMAND}, actual: ${CMD_VERSION}, expected: =${CHECK_COMMAND_VERSION}")
240-
return()
241-
endif()
240+
set(comparator VERSION_EQUAL)
242241
endif()
243242

244-
set(${FOUND} TRUE PARENT_SCOPE)
243+
if(version ${comparator} ${range})
244+
set(${variable} ON PARENT_SCOPE)
245+
endif()
245246
endfunction()
246247

247248
# find_command()
248249
# Description:
249250
# Finds a command, similar to `find_program()`, but allows for version checking.
250251
# Arguments:
251-
# VARIABLE string - The variable to set
252-
# COMMAND string[] - The names of the command to find
253-
# PATHS string[] - The paths to search for the command
254-
# REQUIRED bool - If false, the command is optional
255-
# VERSION string - The version of the command to find (e.g. "1.2.3" or ">1.2.3")
252+
# VARIABLE string - The variable to set
253+
# VERSION_VARIABLE string - The variable to check for the version
254+
# COMMAND string[] - The names of the command to find
255+
# PATHS string[] - The paths to search for the command
256+
# REQUIRED bool - If false, the command is optional
257+
# VERSION string - The version of the command to find (e.g. "1.2.3" or ">1.2.3")
256258
function(find_command)
257-
set(options)
258-
set(args VARIABLE VERSION MIN_VERSION REQUIRED)
259+
set(args VARIABLE VERSION_VARIABLE REQUIRED VERSION)
259260
set(multiArgs COMMAND PATHS)
260-
cmake_parse_arguments(CMD "${options}" "${args}" "${multiArgs}" ${ARGN})
261+
cmake_parse_arguments(FIND "" "${args}" "${multiArgs}" ${ARGN})
261262

262-
if(NOT CMD_VARIABLE)
263-
message(FATAL_ERROR "find_command: VARIABLE is required")
263+
if(NOT FIND_VARIABLE OR NOT FIND_COMMAND)
264+
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: VARIABLE and COMMAND are required")
264265
endif()
265266

266-
if(NOT CMD_COMMAND)
267-
message(FATAL_ERROR "find_command: COMMAND is required")
267+
if(NOT FIND_VERSION_VARIABLE)
268+
set(FIND_VERSION_VARIABLE ${FIND_VARIABLE}_VERSION)
268269
endif()
269270

270-
if(CMD_VERSION)
271-
set(CHECK_COMMAND_VERSION ${CMD_VERSION}) # special global variable
272-
set(CMD_VALIDATOR VALIDATOR check_command)
271+
list(GET FIND_COMMAND 0 FIND_NAME)
272+
optionx(${FIND_VERSION_VARIABLE} STRING "The version of ${FIND_NAME} to find" DEFAULT "${FIND_VERSION}")
273+
274+
if(${FIND_VERSION_VARIABLE})
275+
function(find_command_version variable exe)
276+
set(${variable} OFF PARENT_SCOPE)
277+
278+
if(${exe} MATCHES "(go|zig)(\.exe)?$")
279+
set(command ${exe} version)
280+
else()
281+
set(command ${exe} --version)
282+
endif()
283+
284+
execute_process(
285+
COMMAND ${command}
286+
RESULT_VARIABLE result
287+
OUTPUT_VARIABLE output
288+
OUTPUT_STRIP_TRAILING_WHITESPACE
289+
)
290+
291+
if(NOT result EQUAL 0)
292+
set(reason "exited with ${result}")
293+
elseif(NOT output)
294+
set(reason "no output")
295+
else()
296+
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${output}")
297+
if(match)
298+
set(version ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3})
299+
set(reason "\"${version}\"")
300+
else()
301+
set(reason "no version")
302+
endif()
303+
endif()
304+
305+
set_property(GLOBAL PROPERTY ${FIND_NAME} "${exe}: ${reason}" APPEND)
306+
307+
if(version)
308+
satisfies_range(${version} ${${FIND_VERSION_VARIABLE}} ${variable})
309+
set(${variable} ${${variable}} PARENT_SCOPE)
310+
endif()
311+
endfunction()
312+
313+
set(FIND_VALIDATOR VALIDATOR find_command_version)
273314
endif()
274315

275316
find_program(
276-
${CMD_VARIABLE}
277-
NAMES ${CMD_COMMAND}
278-
PATHS ${CMD_PATHS}
279-
${CMD_VALIDATOR}
317+
${FIND_VARIABLE}
318+
NAMES ${FIND_COMMAND}
319+
PATHS ${FIND_PATHS}
320+
${FIND_VALIDATOR}
280321
)
281322

282-
if(NOT CMD_REQUIRED STREQUAL "OFF" AND ${CMD_VARIABLE} MATCHES "NOTFOUND")
283-
if(CMD_VERSION)
284-
message(FATAL_ERROR "Command not found: \"${CMD_COMMAND}\" that matches version \"${CHECK_COMMAND_VERSION}\"")
323+
if(NOT FIND_REQUIRED STREQUAL "OFF" AND ${FIND_VARIABLE} MATCHES "NOTFOUND")
324+
set(error "Command not found: \"${FIND_NAME}\"")
325+
326+
if(FIND_VERSION)
327+
set(error "${error} that satisfies version \"${${FIND_VERSION_VARIABLE}}\"")
285328
endif()
286-
message(FATAL_ERROR "Command not found: \"${CMD_COMMAND}\"")
329+
330+
get_property(FIND_RESULTS GLOBAL PROPERTY ${FIND_NAME})
331+
if(NOT FIND_RESULTS MATCHES "NOTFOUND")
332+
set(error "${error}\nThe following commands did not satisfy the requirement:")
333+
foreach(result ${FIND_RESULTS})
334+
set(error "${error}\n ${result}")
335+
endforeach()
336+
endif()
337+
338+
set(error "${error}\nTo fix this, either:
339+
1. Install ${FIND_NAME} ${${FIND_VERSION_VARIABLE}}
340+
2. Set -D${FIND_VERSION_VARIABLE}=<version> to require a different version
341+
3. Set -D${FIND_VERSION_VARIABLE}=ignore to allow any version
342+
")
343+
message(FATAL_ERROR ${error})
287344
endif()
288345

289-
if(${CMD_VARIABLE} MATCHES "NOTFOUND")
290-
unset(${CMD_VARIABLE} PARENT_SCOPE)
346+
if(${FIND_VARIABLE} MATCHES "NOTFOUND")
347+
unset(${FIND_VARIABLE} PARENT_SCOPE)
291348
else()
292-
setx(${CMD_VARIABLE} ${${CMD_VARIABLE}} PARENT_SCOPE)
349+
setx(${FIND_VARIABLE} ${${FIND_VARIABLE}} PARENT_SCOPE)
293350
endif()
294351
endfunction()
295352

cmake/analysis/RunClangFormat.cmake

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
find_command(
44
VARIABLE
55
CLANG_FORMAT_PROGRAM
6+
VERSION_VARIABLE
7+
LLVM_VERSION
68
COMMAND
79
clang-format
810
REQUIRED
@@ -11,17 +13,6 @@ find_command(
1113

1214
set(CLANG_FORMAT_SOURCES ${BUN_C_SOURCES} ${BUN_CXX_SOURCES})
1315

14-
register_command(
15-
TARGET
16-
clang-format-version
17-
COMMENT
18-
"Print clang-format version"
19-
COMMAND
20-
${CLANG_FORMAT_PROGRAM}
21-
--version
22-
ALWAYS_RUN
23-
)
24-
2516
register_command(
2617
TARGET
2718
clang-format-check

cmake/analysis/RunClangTidy.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
find_command(
44
VARIABLE
55
CLANG_TIDY_PROGRAM
6+
VERSION_VARIABLE
7+
LLVM_VERSION
68
COMMAND
79
clang-tidy
8-
VERSION
9-
${LLVM_VERSION}
1010
REQUIRED
1111
OFF
1212
)

cmake/tools/SetupLLVM.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ set(LLVM_PATH ${LLVM_PREFIX}/bin)
3535
macro(find_llvm_command VARIABLE COMMAND)
3636
find_command(
3737
VARIABLE ${VARIABLE}
38+
VERSION_VARIABLE LLVM_VERSION
3839
COMMAND ${COMMAND} ${COMMAND}-${LLVM_VERSION_MAJOR}
3940
PATHS ${LLVM_PATH}
4041
VERSION ${LLVM_VERSION}
@@ -45,6 +46,7 @@ endmacro()
4546
macro(find_llvm_command_no_version VARIABLE COMMAND)
4647
find_command(
4748
VARIABLE ${VARIABLE}
49+
VERSION_VARIABLE LLVM_VERSION
4850
COMMAND ${COMMAND} ${COMMAND}-${LLVM_VERSION_MAJOR}
4951
PATHS ${LLVM_PATH}
5052
REQUIRED ON

package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,8 @@
5858
"zig:check": "bun run zig build check --summary new",
5959
"zig:check-all": "bun run zig build check-all --summary new",
6060
"zig:check-windows": "bun run zig build check-windows --summary new",
61-
"cmake": "bun ./scripts/build.mjs -DCMAKE_BUILD_TYPE=Debug -B build/debug",
61+
"cmake": "bun ./scripts/build.mjs -DCMAKE_BUILD_TYPE=Debug -DENABLE_ANALYSIS=ON -B build/debug",
6262
"clang-format": "bun run cmake --target clang-format",
63-
"clang-format:version": "bun run cmake --target clang-format-version",
6463
"clang-format:check": "bun run cmake --target clang-format-check",
6564
"clang-format:diff": "bun run cmake --target clang-format-diff",
6665
"clang-tidy": "bun run cmake --target clang-tidy",
@@ -69,9 +68,9 @@
6968
"zig-format": "bun run cmake --target zig-format",
7069
"zig-format:check": "bun run cmake --target zig-format-check",
7170
"zig-format:diff": "bun run cmake --target zig-format-diff",
72-
"prettier": "bun run cmake -DENABLE_PRETTIER=ON --target prettier",
73-
"prettier:check": "bun run cmake -DENABLE_PRETTIER=ON --target prettier-check",
74-
"prettier:extra": "bun run cmake -DENABLE_PRETTIER=ON --target prettier-extra",
75-
"prettier:diff": "bun run cmake -DENABLE_PRETTIER=ON --target prettier-diff"
71+
"prettier": "bun run cmake --target prettier",
72+
"prettier:check": "bun run cmake --target prettier-check",
73+
"prettier:extra": "bun run cmake --target prettier-extra",
74+
"prettier:diff": "bun run cmake --target prettier-diff"
7675
}
7776
}

0 commit comments

Comments
 (0)