Skip to content

Commit 160993d

Browse files
committed
maint/build ~ (Makefile.win) update (v2024.04.16)
- commentary polish - enable runner ARG configuration - fix clang and gcc dynamic linking - revise `cl` exception handling to reduce chance of undefined behavior (with minimal performance impact)
1 parent 2625f2d commit 160993d

1 file changed

Lines changed: 31 additions & 20 deletions

File tree

Makefile.win

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Makefile (C/C++; OOS-build support; gmake-form/style; v2024.03.02)
1+
# Makefile (C/C++; OOS-build support; gmake-form/style; v2024.04.16)
22
# Cross-platform (bash/sh + CMD/PowerShell)
33
# `bcc32`, `cl`, `clang`, `embcc32`, and `gcc` (defaults to `CC=clang`)
44
# * supports multi-binary projects; adapts to project structure
55
# GNU make (gmake) compatible; ref: <https://www.gnu.org/software/make/manual>
6-
# Copyright (C) 2020-2023 ~ Roy Ivy III <rivy.dev@gmail.com>; MIT+Apache-2.0 license
6+
# Copyright (C) 2020-2024 ~ Roy Ivy III <rivy.dev@gmail.com>; MIT+Apache-2.0 license
77

88
# NOTE: * requires `make` version 4.0+ (minimum needed for correct path functions); for windows, install using `scoop install make`
99
# NOTE: `make` doesn't handle spaces within file names without gyrations (see <https://stackoverflow.com/questions/9838384/can-gnu-make-handle-filenames-with-spaces>@@<https://archive.is/PYKKq>)
@@ -89,15 +89,17 @@ makefile_set_abs := $(abspath ${makefile_set})
8989
# note: environment/${OS}=="Windows_NT" for XP, 2000, Vista, 7, 10, 11, ...
9090
OSID := $(or $(and $(filter .exe,$(patsubst %.exe,.exe,$(subst $() $(),_,${SHELL}))),$(filter win,${OS:Windows_NT=win})),nix)## OSID == [nix,win]
9191
ifeq (${OSID},win)
92+
# WinOS-specific settings
9293
# * set SHELL (from COMSPEC or SystemRoot, if possible)
93-
# ... `make` may otherwise use an incorrect shell (eg, `bash`), if found; "syntax error: unexpected end of file" or "CreateProcess(NULL,...)" error output is indicative
94-
SHELL := cmd## for WinOS, use `cmd` as reasonable default fallback shell (NOTE: requires XP+)
95-
# avoid environment var case variance issues; NOTE: assumes *no spaces* within the path values specified by ${ComSpec}, ${SystemRoot}, or ${windir}
94+
# ... `make` may otherwise use an incorrect shell (eg, `sh` or `bash`, if found in PATH); "syntax error: unexpected end of file" or "CreateProcess(NULL,...)" error output is indicative
95+
SHELL := cmd$()## start with a known default shell (`cmd` for WinOS XP+)
96+
# * set internal variables from environment variables (if available)
97+
# ... avoid env var case variance issues and use fallbacks
98+
# ... note: assumes *no spaces* within the path values specified by ${ComSpec}, ${SystemRoot}, or ${windir}
99+
HOME := $(or $(strip $(shell echo %HOME%)),$(strip $(shell echo %UserProfile%)))
96100
COMSPEC := $(strip $(shell echo %ComSpec%))
97101
SystemRoot := $(or $(strip $(shell echo %SystemRoot%)),$(strip $(shell echo %windir%)))
98102
SHELL := $(firstword $(wildcard ${COMSPEC} ${SystemRoot}/System32/cmd.exe) cmd)
99-
# * set HOME
100-
HOME := $(or $(strip $(shell echo %HOME%)),$(strip $(shell echo %UserProfile%)))
101103
endif
102104

103105
#### * determine compiler ID
@@ -399,16 +401,6 @@ runner_positions := $(call %map,$(eval %f=$$(call %position,$${1},${MAKECMDGOALS
399401
runner_position := $(firstword ${runner_positions})
400402

401403
make_runner_ARGS := $(if ${has_runner_target},$(call %tail,$(wordlist ${runner_position},$(call %length,${make_ARGS}),${make_ARGS})),)
402-
override ARGS := $(or $(and ${ARGS},${ARGS}${SPACE})${make_runner_ARGS},${ARGS_default_${has_runner_target}})
403-
404-
$(call %debug_var,has_runner_first)
405-
$(call %debug_var,has_runner_target)
406-
$(call %debug_var,runner_position)
407-
$(call %debug_var,MAKECMDGOALS)
408-
$(call %debug_var,make_ARGS)
409-
$(call %debug_var,make_runner_ARGS)
410-
$(call %debug_var,ARGS_default_${has_runner_target})
411-
$(call %debug_var,ARGS)
412404

413405
has_debug_target := $(strip $(call %map,$(eval %f=$$(findstring $${1},${MAKECMDGOALS}))%f,debug))
414406
ifneq (${has_debug_target},)
@@ -422,6 +414,19 @@ $(call %debug_var,DEBUG)
422414
# include sibling configuration file, if exists (easier project config with a stable base Makefile)
423415
-include ${makefile_path}.config
424416

417+
####
418+
419+
override ARGS := $(or $(and ${ARGS},${ARGS}${SPACE})${make_runner_ARGS},${ARGS_default_${has_runner_target}})
420+
421+
$(call %debug_var,has_runner_first)
422+
$(call %debug_var,has_runner_target)
423+
$(call %debug_var,runner_position)
424+
$(call %debug_var,MAKECMDGOALS)
425+
$(call %debug_var,make_ARGS)
426+
$(call %debug_var,make_runner_ARGS)
427+
$(call %debug_var,ARGS_default_${has_runner_target})
428+
$(call %debug_var,ARGS)
429+
425430
#### End of basic configuration section ####
426431

427432
# ref: [Understanding and Using Makefile Flags](https://earthly.dev/blog/make-flags) @@ <https://archive.is/vEpEU>
@@ -504,7 +509,10 @@ LDFLAGS += $()
504509
LDFLAGS_ARCH_32 := ${CFLAGS_ARCH_32}
505510
LDFLAGS_ARCH_64 := ${CFLAGS_ARCH_64}
506511
LDFLAGS_DEBUG_false := $(if $(filter nix,${OSID}),-Xlinker --strip-all,)
507-
LDFLAGS_DEBUG_true := $(if $(filter win,${OSID}),$(if $(filter clang,${CC_ID}),-Xlinker /NODEFAULTLIB:libcmt -Xlinker /NODEFAULTLIB:libcmtd -lmsvcrtd,),)
512+
LDFLAGS_DEBUG_true_STATIC_false_clang := -Xlinker /NODEFAULTLIB:libcmt -Xlinker /NODEFAULTLIB:libcmtd -lmsvcrtd
513+
LDFLAGS_DEBUG_false_STATIC_false_clang := -Xlinker /NODEFAULTLIB:libcmt -Xlinker /NODEFAULTLIB:libcmtd -lmsvcrt
514+
LDFLAGS_DEBUG_true_STATIC_false_gcc := -shared-libgcc -shared-libstdc++
515+
LDFLAGS_DEBUG_false_STATIC_false_gcc := -shared-libgcc -shared-libstdc++
508516
# LDFLAGS_STATIC_false := -pie
509517
# LDFLAGS_STATIC_false := -shared
510518
# LDFLAGS_STATIC_true := -static -static-libgcc -static-libstdc++
@@ -568,7 +576,8 @@ STRIP := $()
568576
## /W3 :: set warning level to 3 [1..4, all; increasing level of warning scrutiny]
569577
## /WX :: treat warnings as errors
570578
## /wd4996 :: suppress POSIX function name deprecation warning (#C4996)
571-
## /EHsc :: enable C++ EH (no SEH exceptions) + extern "C" defaults to nothrow (replaces deprecated /GX)
579+
## /EHs :: enable synchronous C++ EH (`throw`; no SEH exceptions) + extern "C" may also throw; usually minimal performance decrease unless there is 'heavy use of external "C" functions that throw'
580+
## /EHsc :: enable synchronous C++ EH (`throw`; no SEH exceptions) + extern "C" defaults to nothrow (replaces deprecated /GX); undefined behavior occurs if the extern "C" function throws an exception
572581
## /D "_CRT_SECURE_NO_WARNING" :: compiler directive == suppress "unsafe function" compiler warning
573582
## /Od :: disable optimization
574583
## /Ox :: maximum optimizations
@@ -595,7 +604,7 @@ STRIP := $()
595604
## /subsystem:console,4.00 :: generate "Win32 character-mode" console application; 4.00 => minimum supported system is Win9x/NT; supported only by MSVC 9 (`cl` version "15xx" from 2008) or less
596605
## /subsystem:console,5.01 :: generate "Win32 character-mode" console application; 5.01 => minimum supported system is XP; supported by MSVC 10 (`cl` version "16xx") or later when compiling for 32-bit
597606
## /subsystem:console,5.02 :: generate "Win32 character-mode" console application; 5.02 => minimum supported system is XP; supported by MSVC 10 (`cl` version "16xx") or later when compiling for 64-bit
598-
CFLAGS = /nologo /W3 /WX /EHsc $(call %cflags_incs,${INCLUDE_DIRS})## requires delayed expansion (b/c uses `%shell_quote` which is defined later)
607+
CFLAGS = /nologo /W3 /WX /EHs $(call %cflags_incs,${INCLUDE_DIRS})## requires delayed expansion (b/c uses `%shell_quote` which is defined later)
599608
%cflags_incs = $(call %map,$(eval %f=/I $(call %shell_quote,$${1}))%f,$(strip ${1}))
600609
CFLAGS_COMPILE_ONLY := -c
601610
CFLAGS_ARCH_32 := $(if $(filter clang-cl,${CC}),-m32,)
@@ -1026,6 +1035,8 @@ LDFLAGS += ${LDFLAGS_ARCH_${ARCH_ID}}
10261035
LDFLAGS += ${LDFLAGS_TARGET}
10271036
LDFLAGS += ${LDFLAGS_DEBUG_${DEBUG}}
10281037
LDFLAGS += ${LDFLAGS_STATIC_${STATIC}}
1038+
LDFLAGS += ${LDFLAGS_DEBUG_${DEBUG}_STATIC_${STATIC}}
1039+
LDFLAGS += ${LDFLAGS_DEBUG_${DEBUG}_STATIC_${STATIC}_${CC_ID}}
10291040
LDFLAGS += ${LDFLAGS_VC6_${is_VC6}}## name-expanded variable is only defined for ${CC_ID}=='cl'
10301041
LDFLAGS += ${LDFLAGS_${CC_ID}}
10311042
LDFLAGS += ${LDFLAGS_${CC_ID}_${OSID}}

0 commit comments

Comments
 (0)