2024-10-10 14:21 UTC+0200 Aleksander Czajczynski (hb fki.pl)

+ config/win/clang-noauto.mk
    + additional clang flavour checking when the compiler is specified
      via set HB_COMPILER=clang (not auto-detected)

      This is important for distributions of clang that bundle both
      gcc and clang in the same directory. Harbour 3.2 by default
      prioritize gcc over clang.

      For example you should be now able to build from winlibs.com by
      Brecht Sanders with environment setup such as:
      PATH=C:\winlibs\mingw64\bin;%PATH%
      HB_COMPILER=clang
      win-make

  * config/global.mk
    ! added workaround for common GNU Make issue with
      $(dir path with spaces/file) macro, commonly striking on Windows
      systems under "Program Files", but also possible in other setups.
      Workaround is to call $(call dir_with_spaces,$(HB_COMP_PATH)).
      I have only used this workaround in clang detection, but keep
      this in mind while revisiting detection of another compiler.

  * config/win/clang.mk
  * utils/hbmk2/hbmk2.prg
    * another rework of Clang on Windows detection (ARM64, x86_64, x86),
      solved problems with different availability of resource compiler,
      They are now probed in order: windres, llvm-windres, llvm-rc.

    * added option to use MinGW INPUT(file.o) link scripts for old tools
      To apply workaround with clang, set HB_USER_DFLAGS=--mingw-script
      It is not supported in at least some of current clang toolchains,
      but it's still needed to succesfully build on old ones (those
      using GNU ld on Windows).
This commit is contained in:
Aleksander Czajczynski
2024-10-10 14:21:17 +02:00
parent 77d37481be
commit 60a10666f4
5 changed files with 246 additions and 34 deletions

View File

@@ -7,6 +7,41 @@
Entries may not always be in chronological/commit order.
See license at the end of file. */
2024-10-10 14:21 UTC+0200 Aleksander Czajczynski (hb fki.pl)
+ config/win/clang-noauto.mk
+ additional clang flavour checking when the compiler is specified
via set HB_COMPILER=clang (not auto-detected)
This is important for distributions of clang that bundle both
gcc and clang in the same directory. Harbour 3.2 by default
prioritize gcc over clang.
For example you should be now able to build from winlibs.com by
Brecht Sanders with environment setup such as:
PATH=C:\winlibs\mingw64\bin;%PATH%
HB_COMPILER=clang
win-make
* config/global.mk
! added workaround for common GNU Make issue with
$(dir path with spaces/file) macro, commonly striking on Windows
systems under "Program Files", but also possible in other setups.
Workaround is to call $(call dir_with_spaces,$(HB_COMP_PATH)).
I have only used this workaround in clang detection, but keep
this in mind while revisiting detection of another compiler.
* config/win/clang.mk
* utils/hbmk2/hbmk2.prg
* another rework of Clang on Windows detection (ARM64, x86_64, x86),
solved problems with different availability of resource compiler,
They are now probed in order: windres, llvm-windres, llvm-rc.
* added option to use MinGW INPUT(file.o) link scripts for old tools
To apply workaround with clang, set HB_USER_DFLAGS=--mingw-script
It is not supported in at least some of current clang toolchains,
but it's still needed to succesfully build on old ones (those
using GNU ld on Windows).
2024-10-07 11:40 UTC+0200 Aleksander Czajczynski (hb fki.pl)
* config/global.mk
! detect ARM64 CPU on Windows also under non-native shell (MSYS2 sh)

View File

@@ -40,6 +40,8 @@ endif
# Arbitrary pattern which we do not expect to occur in real-world path names
substpat := !@!@
# On the other hand a very common pattern
chr_space := $(subst ,, )
# This is not strictly necessary, but it does significantly reduce
# the number of rules that make has to evaluate otherwise, which may give
@@ -79,6 +81,7 @@ find_in_path = $(strip $(subst $(substpat), ,$(firstword $(subst |, ,$(subst
find_in_path_raw = $(strip $(subst $(substpat), ,$(firstword $(subst |, ,$(subst $(subst x, ,x),$(substpat),$(filter-out |,$(foreach dir, $(subst $(PTHSEP), ,$(subst $(subst x, ,x),$(substpat),$(PATH))),|$(wildcard $(subst //,/,$(subst $(substpat),\ ,$(subst \,/,$(dir)))/$(1))))))))))
find_in_path_par = $(strip $(subst $(substpat), ,$(firstword $(subst |, ,$(subst $(subst x, ,x),$(substpat),$(filter-out |,$(foreach dir, $(subst $(PTHSEP), ,$(subst $(subst x, ,x),$(substpat),$(2))),|$(wildcard $(subst //,/,$(subst $(substpat),\ ,$(subst \,/,$(dir)))/$(1))$(HB_HOST_BIN_EXT)))))))))
find_in_path_prw = $(strip $(subst $(substpat), ,$(firstword $(subst |, ,$(subst $(subst x, ,x),$(substpat),$(filter-out |,$(foreach dir, $(subst $(PTHSEP), ,$(subst $(subst x, ,x),$(substpat),$(2))),|$(wildcard $(subst //,/,$(subst $(substpat),\ ,$(subst \,/,$(dir)))/$(1))))))))))
dir_with_spaces = $(subst $(substpat), ,$(dir $(subst $(chr_space),$(substpat),$(1))))
# Some presets based on HB_BUILD_NAME
ifneq ($(HB_BUILD_NAME),)
@@ -708,39 +711,90 @@ ifeq ($(HB_COMPILER),)
endif
endif
else
HB_COMP_PATH := $(call find_in_path,clang)
HB_COMP_PATH := $(call find_in_path_raw,clang.exe)
HB_COMP_PWD := $(call dir_with_spaces,$(HB_COMP_PATH))
ifneq ($(HB_COMP_PATH),)
HB_COMPILER = clang
ifneq ($(wildcard $(dir $(HB_COMP_PATH))aarch64-w64-mingw32-clang$(HB_HOST_BIN_EXT)),)
HB_COMPILER := clang
ifneq ($(wildcard $(HB_COMP_PWD)aarch64-w64-mingw32-clang$(HB_HOST_BIN_EXT)),)
HB_CPU := arm64
ifeq ($(HB_BUILD_NAME),)
export HB_BUILD_NAME := arm64
endif
ifneq ($(MSYSTEM),)
export MSYSTEM := CLANGARM64
endif
MSYSTEM := CLANGARM64
else
ifneq ($(wildcard $(dir $(HB_COMP_PATH))x86_64-w64-mingw32-clang$(HB_HOST_BIN_EXT)),)
ifneq ($(wildcard $(HB_COMP_PWD)x86_64-w64-mingw32-clang$(HB_HOST_BIN_EXT)),)
HB_CPU := x86_64
ifeq ($(HB_BUILD_NAME),)
export HB_BUILD_NAME := 64
endif
ifneq ($(MSYSTEM),)
export MSYSTEM := CLANG64
endif
MSYSTEM := CLANG64
else
ifneq ($(wildcard $(dir $(HB_COMP_PATH))i686-w64-mingw32-clang$(HB_HOST_BIN_EXT)),)
ifneq ($(MSYSTEM),)
export MSYSTEM := CLANG32
endif
ifneq ($(wildcard $(HB_COMP_PWD)i686-w64-mingw32-clang$(HB_HOST_BIN_EXT)),)
HB_CPU := x86
MSYSTEM := CLANG32
else
ifneq ($(wildcard $(dir $(HB_COMP_PATH))lldb-vscode$(HB_HOST_BIN_EXT)),)
export MSYSTEM :=
ifneq ($(findstring /VC/Tools/Llvm/ARM64/,$(HB_COMP_PATH)),)
MSYSTEM :=
HB_CPU := arm64
else
ifneq ($(findstring /VC/Tools/Llvm/x64/,$(HB_COMP_PATH)),)
MSYSTEM :=
HB_CPU := x86_64
else
ifneq ($(findstring mingw64,$(HB_COMP_PATH)),)
HB_CPU := x86_64
MSYSTEM := CLANG64
else
ifneq ($(findstring mingw32,$(HB_COMP_PATH)),)
HB_CPU := x86
MSYSTEM := CLANG32
else
MSYSTEM := $(shell clang --version)
ifneq ($(findstring x86_64-pc-windows-msvc,$(MSYSTEM)),)
MSYSTEM :=
HB_CPU := x86_64
else
ifneq ($(findstring i686-pc-windows-msvc,$(MSYSTEM)),)
MSYSTEM :=
HB_CPU := x86
else
ifneq ($(findstring aarch64-pc-windows-msvc,$(MSYSTEM)),)
MSYSTEM :=
HB_CPU := arm64
ifneq ($(findstring x86_64-w64-windows-gnu,$(MSYSTEM)),)
HB_CPU := x86_64
MSYSTEM := CLANG64
else
ifneq ($(findstring i686-w64-windows-gnu,$(MSYSTEM)),)
HB_CPU := x86
MSYSTEM := CLANG32
else
ifneq ($(findstring aarch64-w64-windows-gnu,$(MSYSTEM)),)
HB_CPU := arm64
MSYSTEM := CLANGARM64
else
ifneq ($(findstring -windows-gnu,$(MSYSTEM)),)
MSYSTEM := CLANG
else
MSYSTEM :=
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
export MSYSTEM
ifneq ($(HB_CPU),$(HB_HOST_CPU))
ifeq ($(HB_BUILD_NAME),)
ifeq ($(HB_CPU),x86_64)
export HB_BUILD_NAME := 64
else
export HB_BUILD_NAME := HB_CPU
endif
endif
endif
else
HB_COMP_PATH := $(call find_in_path,wcc386)
ifneq ($(HB_COMP_PATH),)
@@ -1077,6 +1131,10 @@ ifeq ($(HB_COMPILER),)
endif
endif
endif
else
ifneq ($(wildcard $(TOP)$(ROOT)config/$(HB_PLATFORM)/$(HB_COMPILER)-noauto.mk),)
include $(TOP)$(ROOT)config/$(HB_PLATFORM)/$(HB_COMPILER)-noauto.mk
endif
endif
# auto-detect CC values for given platform/compiler

View File

@@ -0,0 +1,90 @@
# Brecht Sanders winlibs clang distribution and possiblty others are impossible
# to detect from path alone as clang.exe resides in the same directory with gcc,
# in Harbour 3.2 gcc has priority over clang for backwards compatibility
# supp. actions if the set HB_COMPILER=clang was specified, not auto-detected
ifneq ($(HB_COMPILER_ORI),)
HB_COMP_PATH := $(call find_in_path_raw,clang.exe)
HB_COMP_PWD := $(call dir_with_spaces,$(HB_COMP_PATH))
ifneq ($(HB_COMP_PATH),)
ifneq ($(wildcard $(HB_COMP_PWD)../x86_64-w64-mingw32/lib/lib*.a),)
MSYSTEM := CLANG64
HB_CPU := x86_64
else
ifneq ($(wildcard $(HB_COMP_PWD)../i686-w64-mingw32/lib/lib*.a),)
MSYSTEM := CLANG32
HB_CPU := x86
else
ifneq ($(wildcard $(HB_COMP_PWD)../aarch64-w64-mingw32/lib/lib*.a),)
MSYSTEM := CLANGARM64
HB_CPU := arm64
else
ifneq ($(findstring /VC/Tools/Llvm/ARM64/,$(HB_COMP_PATH)),)
MSYSTEM :=
HB_CPU := arm64
else
ifneq ($(findstring /VC/Tools/Llvm/x64/,$(HB_COMP_PATH)),)
MSYSTEM :=
HB_CPU := x86_64
else
ifneq ($(findstring mingw64,$(HB_COMP_PWD)),)
MSYSTEM := CLANG64
else
ifneq ($(findstring mingw32,$(HB_COMP_PWD)),)
MSYSTEM := CLANG32
HB_CPU := x86
else
MSYSTEM := $(shell clang --version)
ifneq ($(findstring x86_64-pc-windows-msvc,$(MSYSTEM)),)
MSYSTEM :=
HB_CPU := x86_64
else
ifneq ($(findstring i686-pc-windows-msvc,$(MSYSTEM)),)
MSYSTEM :=
HB_CPU := x86
else
ifneq ($(findstring aarch64-pc-windows-msvc,$(MSYSTEM)),)
MSYSTEM :=
HB_CPU := arm64
ifneq ($(findstring x86_64-w64-windows-gnu,$(MSYSTEM)),)
HB_CPU := x86_64
MSYSTEM := CLANG64
else
ifneq ($(findstring i686-w64-windows-gnu,$(MSYSTEM)),)
HB_CPU := x86
MSYSTEM := CLANG32
else
ifneq ($(findstring aarch64-w64-windows-gnu,$(MSYSTEM)),)
HB_CPU := arm64
MSYSTEM := CLANGARM64
else
ifneq ($(findstring -windows-gnu,$(MSYSTEM)),)
MSYSTEM := CLANG
else
MSYSTEM :=
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
endif
export MSYSTEM
ifneq ($(HB_CPU),$(HB_HOST_CPU))
ifeq ($(HB_BUILD_NAME),)
ifeq ($(HB_CPU),x86_64)
export HB_BUILD_NAME := 64
else
export HB_BUILD_NAME := HB_CPU
endif
endif
endif
endif
endif

View File

@@ -54,6 +54,8 @@ AR := $(HB_CCPREFIX)llvm-ar
AR_RULE = ( $(AR) $(ARFLAGS) $(HB_AFLAGS) $(HB_USER_AFLAGS) rcs $(LIB_DIR)/$@ $(^F) $(ARSTRIP) ) || ( $(RM) $(subst /,$(DIRSEP),$(LIB_DIR)/$@) && $(FALSE) )
# TODO: add resource compiler detect chain in this stage: GNU windres, llvm-windres, llvm-rc
DY := $(CC)
DFLAGS += -shared $(LIBPATHS)
DY_OUT := -o$(subst x,x, )
@@ -84,24 +86,37 @@ else
endef
endif
TMPSPEC := @__dyn__.tmp
# setting HB_USER_DFLAGS=--mingw-script[...]
# may help to workaround if old clang + MinGW linker is in use,
# build may fail either with too long command line or unrecognized argument
ifneq ($(filter --mingw-script, $(HB_USER_DFLAGS)),)
HB_USER_DFLAGS := $(subst --mingw-script,,$(HB_USER_DFLAGS))
# NOTE: The empty line directly before 'endef' HAS TO exist!
override define dynlib_object
@$(ECHO) $(ECHOQUOTE)INPUT($(subst \,/,$(file)))$(ECHOQUOTE) >> __dyn__.tmp
endef
TMPSPEC := __dyn__.tmp
endif
define create_dynlib
$(if $(wildcard __dyn__.tmp),@$(RM) __dyn__.tmp,)
$(foreach file,$^,$(dynlib_object))
$(DY) $(DFLAGS) $(HB_USER_DFLAGS) $(DY_OUT)$(DYN_DIR)/$@ $(TMPSPEC) $(DLIBS) $(IMPLIBFLAGS) $(DYSTRIP) $(DYSTRIP)
$(dynlib_ln)
endef
# clang distributed by MS uses lld-link, libs are *.lib not lib*.a
# in opposite MSYS/MinGW needs args to actually make an implib
ifeq ($(MSYSTEM),)
define create_dynlib
$(if $(wildcard __dyn__.tmp),@$(RM) __dyn__.tmp,)
$(foreach file,$^,$(dynlib_object))
$(DY) $(DFLAGS) $(HB_USER_DFLAGS) $(DY_OUT)$(DYN_DIR)/$@ @__dyn__.tmp $(DLIBS) $(DYSTRIP) $(DYSTRIP)
$(dynlib_ln)
endef
LDFLAGS += -Wl,-subsystem:console
DFLAGS += -Wl,-subsystem:console
else
define create_dynlib
$(if $(wildcard __dyn__.tmp),@$(RM) __dyn__.tmp,)
$(foreach file,$^,$(dynlib_object))
$(DY) $(DFLAGS) $(HB_USER_DFLAGS) $(DY_OUT)$(DYN_DIR)/$@ @__dyn__.tmp $(DLIBS) -Wl,--out-implib,$(IMP_FILE),--output-def,$(DYN_DIR)/$(basename $@).def $(DYSTRIP) $(DYSTRIP)
$(dynlib_ln)
endef
IMPLIBFLAGS = -Wl,--out-implib,$(IMP_FILE),--output-def,$(DYN_DIR)/$(basename $@).def
endif
DY_RULE = $(create_dynlib)
include $(TOP)$(ROOT)config/rules.mk

View File

@@ -4368,6 +4368,11 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit
IF hb_fileExists( hb_DirSepAdd( hbmk[ _HBMK_cHB_INSTALL_LIB ] ) + "hbrtl.lib" ) /* selfcheck if clang ld emits .lib extension */
cLibLibPrefix := ""
cLibLibExt := ".lib"
IF hbmk[ _HBMK_lGUI ]
AAdd( hbmk[ _HBMK_aOPTL ], "-Wl,-subsystem:windows" )
ELSE
AAdd( hbmk[ _HBMK_aOPTL ], "-Wl,-subsystem:console" )
ENDIF
ENDIF
CASE hbmk[ _HBMK_cCOMP ] == "tcc"
cBin_CompCPP := "tcc.exe"
@@ -4571,6 +4576,15 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit
cBin_Res := hbmk[ _HBMK_cCCPREFIX ] + "windres" + hbmk[ _HBMK_cCCEXT ]
cResExt := ".reso"
cOpt_Res := "{FR} {IR} -O coff -o {OS}"
IF hbmk[ _HBMK_cCOMP ] == "clang" .AND. FindInPath( cBin_Res ) == NIL
IF FindInPath( cBin_Res := "llvm-" + cBin_Res ) == NIL
cBin_Res := "llvm-rc"
cResExt := ".res"
/* codepage default in llvm-rc is confusing, a .rc file could be multi-language */
cOpt_Res := "/C 1252 {FR} /FO {OS} {IR}"
ENDIF
ENDIF
IF ! Empty( hbmk[ _HBMK_cCCPATH ] )
cBin_Res := FNameEscape( hbmk[ _HBMK_cCCPATH ] + hb_ps() + cBin_Res, hbmk[ _HBMK_nCmd_Esc ] )
ENDIF