Skip to content

Commit

Permalink
2024-10-10 14:21 UTC+0200 Aleksander Czajczynski (hb fki.pl)
Browse files Browse the repository at this point in the history
  + 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).
  • Loading branch information
alcz committed Oct 10, 2024
1 parent 77d3748 commit 60a1066
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 34 deletions.
35 changes: 35 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
102 changes: 80 additions & 22 deletions config/global.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),)
Expand Down Expand Up @@ -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),)
Expand Down Expand Up @@ -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
Expand Down
90 changes: 90 additions & 0 deletions config/win/clang-noauto.mk
Original file line number Diff line number Diff line change
@@ -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
39 changes: 27 additions & 12 deletions config/win/clang.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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, )
Expand Down Expand Up @@ -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
14 changes: 14 additions & 0 deletions utils/hbmk2/hbmk2.prg
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 60a1066

Please sign in to comment.