From aba677910005dc5e97d07fbb8bc8350568a75ec5 Mon Sep 17 00:00:00 2001 From: Aleksander Czajczynski Date: Sat, 18 Oct 2025 23:15:08 +0200 Subject: [PATCH] 2025-10-18 23:15 UTC+0200 Aleksander Czajczynski (hb fki.pl) + config/bsd/zig-noauto.mk + config/bsd/zig.mk + config/common/zig-noauto.mk + config/common/zig.mk + config/darwin/zig-noauto.mk + config/darwin/zig.mk + config/linux/zig-noauto.mk + config/linux/zig.mk + config/win/zig-noauto.mk + config/win/zig.mk * config/global.mk * utils/hbmk2/hbmk2.prg ! typo fixed in Alpha target (this path was really untested) + added support for using Zig as LLVM C compiler frontend. Recent idea comes from Marcos Gambeta Harbour++ fork, though I haven't borrowed any code. Here the functionalty is complete, whole Harbour source tree can be compiled, together with shared libs. Zig has unique ability of managing cross-compiled builds, mostly without downloading anything else. For example you should be able to easily make a Linux+musl libc build of your Harbour application that will run on any distribution with Linux kernel >= 2.6.39 (untested). Zig is not auto-detected by the Harbour build process, HB_COMPILER=zig has to be defined. The only exception is that, hbmk2 on Windows can locate "zig.exe" while building final Harbour applications. Usually there are no conflicting tools on PATH on this platform. After downloading zig from https://ziglang.org/download/ specific to your OS, assuming the tool being unpacked to /home/user/zig or C:\zig, usage is as follows: Linux/BSD native build: PATH=$PATH:/home/user/zig HB_COMPILER=zig make -j8 Unix to Windows x64 cross: PATH=$PATH:/home/user/zig export HB_ZIG_TARGET=x86_64-windows # (or) export HB_ZIG_TARGET=x86_64-windows-gnu export HB_CPU=x86_64 # have to build a Harbour for your host first, for a native hbmk2 export HB_HOST_BIN=/home/user/harbour/bin/linux/zig export HB_PLATFORM=win export HB_BUILD_NAME=64cross export HB_COMPILER=zig make -j16 Windows native build: PATH=C:\zig;%PATH% set HB_COMPILER=zig win-make -j8 Windows to Windows-on-ARM cross: set HB_ZIG_TARGET=aarch64-windows set HB_CPU=arm64 set HB_HOST_BIN=C:\harbour\bin\win\zig set HB_COMPILER=zig win-make -j8 Windows to Linux ARM64: set HB_USER_CFLAGS=-fPIC set HB_ZIG_TARGET=aarch64-linux set HB_PLATFORM=linux set HB_CPU=arm64 set HB_HOST_BIN=C:\harbour\bin\win\zig set HB_COMPILER=zig win-make -j8 Instead of setting HB_ZIG_TARGET, the less convenient way is: HB_USER_CFLAGS=-target aarch64-linux HB_USER_LDFLAGS=-target aarch64-linux HB_USER_DFLAGS=-target aarch64-linux Some target platforms need PIC mode even for static builds, in such case add: HB_USER_CFLAGS=-fPIC ; TOFIX: shared lib symlinks are not created when cross-building from Windows to Linux, could copy or adapt modern Windows counterpart olectl.h is missing when cross-building hbwin contrib from Linux to Windows (likely needs headers from Windows SDK) basically a non issue, but HB_CPU and HB_PLATFORM are not guessed from HB_ZIG_TARGET - conversion table seems to be doable, if someone is interested in making a patch. --- ChangeLog.txt | 90 +++++++++++++++++++++++++++++++ config/bsd/zig-noauto.mk | 1 + config/bsd/zig.mk | 1 + config/common/zig-noauto.mk | 24 +++++++++ config/common/zig.mk | 104 ++++++++++++++++++++++++++++++++++++ config/darwin/zig-noauto.mk | 1 + config/darwin/zig.mk | 1 + config/global.mk | 7 ++- config/linux/zig-noauto.mk | 1 + config/linux/zig.mk | 1 + config/win/zig-noauto.mk | 1 + config/win/zig.mk | 10 ++++ utils/hbmk2/hbmk2.prg | 93 ++++++++++++++++++++++---------- 13 files changed, 307 insertions(+), 28 deletions(-) create mode 100644 config/bsd/zig-noauto.mk create mode 100644 config/bsd/zig.mk create mode 100644 config/common/zig-noauto.mk create mode 100644 config/common/zig.mk create mode 100644 config/darwin/zig-noauto.mk create mode 100644 config/darwin/zig.mk create mode 100644 config/linux/zig-noauto.mk create mode 100644 config/linux/zig.mk create mode 100644 config/win/zig-noauto.mk create mode 100644 config/win/zig.mk diff --git a/ChangeLog.txt b/ChangeLog.txt index 5995510af7..b619382e2f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,96 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2025-10-18 23:15 UTC+0200 Aleksander Czajczynski (hb fki.pl) + + config/bsd/zig-noauto.mk + + config/bsd/zig.mk + + config/common/zig-noauto.mk + + config/common/zig.mk + + config/darwin/zig-noauto.mk + + config/darwin/zig.mk + + config/linux/zig-noauto.mk + + config/linux/zig.mk + + config/win/zig-noauto.mk + + config/win/zig.mk + * config/global.mk + * utils/hbmk2/hbmk2.prg + ! typo fixed in Alpha target (this path was really untested) + + + added support for using Zig as LLVM C compiler frontend. Recent + idea comes from Marcos Gambeta Harbour++ fork, though I haven't + borrowed any code. Here the functionalty is complete, whole + Harbour source tree can be compiled, together with shared libs. + + Zig has unique ability of managing cross-compiled builds, mostly + without downloading anything else. For example you should be able + to easily make a Linux+musl libc build of your Harbour application + that will run on any distribution with Linux kernel >= 2.6.39 (untested). + + Zig is not auto-detected by the Harbour build process, HB_COMPILER=zig + has to be defined. The only exception is that, hbmk2 on Windows can + locate "zig.exe" while building final Harbour applications. Usually + there are no conflicting tools on PATH on this platform. + + After downloading zig from https://ziglang.org/download/ + specific to your OS, assuming the tool being unpacked to + /home/user/zig or C:\zig, usage is as follows: + + Linux/BSD native build: + PATH=$PATH:/home/user/zig + HB_COMPILER=zig make -j8 + + Unix to Windows x64 cross: + PATH=$PATH:/home/user/zig + export HB_ZIG_TARGET=x86_64-windows + # (or) export HB_ZIG_TARGET=x86_64-windows-gnu + export HB_CPU=x86_64 + # have to build a Harbour for your host first, for a native hbmk2 + export HB_HOST_BIN=/home/user/harbour/bin/linux/zig + export HB_PLATFORM=win + export HB_BUILD_NAME=64cross + export HB_COMPILER=zig + make -j16 + + Windows native build: + PATH=C:\zig;%PATH% + set HB_COMPILER=zig + win-make -j8 + + Windows to Windows-on-ARM cross: + set HB_ZIG_TARGET=aarch64-windows + set HB_CPU=arm64 + set HB_HOST_BIN=C:\harbour\bin\win\zig + set HB_COMPILER=zig + win-make -j8 + + Windows to Linux ARM64: + set HB_USER_CFLAGS=-fPIC + set HB_ZIG_TARGET=aarch64-linux + set HB_PLATFORM=linux + set HB_CPU=arm64 + set HB_HOST_BIN=C:\harbour\bin\win\zig + set HB_COMPILER=zig + win-make -j8 + + Instead of setting HB_ZIG_TARGET, the less convenient way is: + HB_USER_CFLAGS=-target aarch64-linux + HB_USER_LDFLAGS=-target aarch64-linux + HB_USER_DFLAGS=-target aarch64-linux + + Some target platforms need PIC mode even for static builds, + in such case add: + HB_USER_CFLAGS=-fPIC + + ; TOFIX: shared lib symlinks are not created when cross-building from + Windows to Linux, could copy or adapt modern Windows counterpart + + olectl.h is missing when cross-building hbwin contrib from + Linux to Windows (likely needs headers from Windows SDK) + + basically a non issue, but HB_CPU and HB_PLATFORM are not guessed + from HB_ZIG_TARGET - conversion table seems to be doable, if + someone is interested in making a patch. + 2025-10-16 22:04 UTC+0200 Aleksander Czajczynski (hb fki.pl) * utils/hbmk2/hbmk2.prg * remaining LEFTEQUAL() changed to hb_LeftEq() calls diff --git a/config/bsd/zig-noauto.mk b/config/bsd/zig-noauto.mk new file mode 100644 index 0000000000..203c8af0cc --- /dev/null +++ b/config/bsd/zig-noauto.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig-noauto.mk diff --git a/config/bsd/zig.mk b/config/bsd/zig.mk new file mode 100644 index 0000000000..911eb9b101 --- /dev/null +++ b/config/bsd/zig.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig.mk diff --git a/config/common/zig-noauto.mk b/config/common/zig-noauto.mk new file mode 100644 index 0000000000..aec7a38280 --- /dev/null +++ b/config/common/zig-noauto.mk @@ -0,0 +1,24 @@ +ifneq ($(HB_COMPILER_ORI),) + ifeq ($(filter -target, $(HB_USER_CFLAGS)),) + ifeq ($(HB_ZIG_TARGET),) + HB_CPU := $(HB_HOST_CPU) + else + ifeq ($(HB_CPU),) + $(error ! zig toolchain helper setting HB_ZIG_TARGET is specified, please also set equivalent HB_CPU and possibly HB_PLATFORM, HB_HOST_BIN to proceed with cross-compilation ) + endif + endif + else + ifeq ($(HB_CPU),) + $(error ! zig toolchain -target option is specified in HB_USER_CFLAGS, please also set equivalent HB_CPU and possibly HB_PLATFORM, HB_HOST_BIN to proceed with cross-compilation ) + endif + endif + 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 diff --git a/config/common/zig.mk b/config/common/zig.mk new file mode 100644 index 0000000000..eb80d6457f --- /dev/null +++ b/config/common/zig.mk @@ -0,0 +1,104 @@ +ifeq ($(HB_BUILD_MODE),cpp) + HB_CMP := zig c++ +else + HB_CMP := zig cc +endif + +OBJ_EXT := .o +LIB_PREF := lib +LIB_EXT := .a + +HB_DYN_COPT := -DHB_DYNLIB + +CC := $(HB_CCPATH)$(HB_CCPREFIX)$(HB_CMP)$(HB_CCSUFFIX) +ifneq ($(filter --analyze, $(HB_USER_CFLAGS)),) + CC_IN := +else + CC_IN := -c +endif +CC_OUT := -o + +CFLAGS += -I. -I$(HB_HOST_INC) + +CFLAGS += -Wno-error=date-time +# NOTE: no reproducible builds guaranteed by Harbour 3.2 + +ifneq ($(HB_ZIG_TARGET),) + LDFLAGS += -target $(HB_ZIG_TARGET) + DFLAGS += -target $(HB_ZIG_TARGET) + CFLAGS += -target $(HB_ZIG_TARGET) +endif + +ifneq ($(HB_BUILD_WARN),no) + CFLAGS += -W -Wall +else + CFLAGS += -Wmissing-braces -Wreturn-type -Wformat + ifneq ($(HB_BUILD_MODE),cpp) + CFLAGS += -Wimplicit-int -Wimplicit-function-declaration + endif +endif + +ifneq ($(HB_BUILD_OPTIM),no) + CFLAGS += -O3 +endif + +ifeq ($(HB_BUILD_DEBUG),yes) + CFLAGS += -g +endif + +LD := $(CC) +LD_OUT := -o + +LIBPATHS := $(foreach dir,$(LIB_DIR) $(SYSLIBPATHS),-L$(dir)) +LDLIBS := $(foreach lib,$(HB_USER_LIBS) $(LIBS) $(SYSLIBS),-l$(lib)) + +LDFLAGS += $(LIBPATHS) + +AR := zig ar + +AR_RULE = ( $(AR) $(ARFLAGS) $(HB_AFLAGS) $(HB_USER_AFLAGS) rcs $(LIB_DIR)/$@ $(^F) $(ARSTRIP) ) || ( $(RM) $(subst /,$(DIRSEP),$(LIB_DIR)/$@) && $(FALSE) ) + +DY := $(CC) +DFLAGS += -shared $(LIBPATHS) +DY_OUT := -o$(subst x,x, ) +DLIBS := $(foreach lib,$(HB_USER_LIBS) $(SYSLIBS),-l$(lib)) + +ifeq ($(HB_SHELL),nt) + define dynlib_object + @$(ECHO) $(ECHOQUOTE)$(subst \,/,$(file)) $(ECHOQUOTE) >> __dyn__.tmp + + endef + # no-op under cmd.exe shell + define dynlib_ln + + endef + +# FIXME: symlinks for dynlibs generated when cross compiling from windows +# to unix are not created, decide if we want a copy or something else +# +# define dynlib_ln +# $(LN) $(subst /,\,$(DYN_DIR)\$(LIB_PREF)$(basename $@)$(LIB_EXT)) $(subst /,\,$(LIB_DIR)\$(LIB_PREF)$(basename $@)$(LIB_EXT)) +# endef + +else + define dynlib_object + @$(ECHO) -n $(ECHOQUOTE)$(subst \,/,$(file)) $(ECHOQUOTE) >> __dyn__.tmp + + endef + define dynlib_ln + $(LN) $(@F) $(DYN_FILE_NVR) && $(LN) $(@F) $(DYN_FILE_CPT) + endef +endif + +TMPSPEC := @__dyn__.tmp + +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 + +DY_RULE = $(create_dynlib) + +include $(TOP)$(ROOT)config/rules.mk diff --git a/config/darwin/zig-noauto.mk b/config/darwin/zig-noauto.mk new file mode 100644 index 0000000000..203c8af0cc --- /dev/null +++ b/config/darwin/zig-noauto.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig-noauto.mk diff --git a/config/darwin/zig.mk b/config/darwin/zig.mk new file mode 100644 index 0000000000..911eb9b101 --- /dev/null +++ b/config/darwin/zig.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig.mk diff --git a/config/global.mk b/config/global.mk index 28a926e3b7..c59def84c1 100644 --- a/config/global.mk +++ b/config/global.mk @@ -286,6 +286,11 @@ ifeq ($(HB_INIT_DONE),) ifneq ($(HB_MT),) $(info ! HB_MT: $(HB_MT)) endif + ifeq ($(HB_COMPILER),zig) + ifneq ($(HB_ZIG_TARGET),) + $(info ! HB_ZIG_TARGET: $(HB_ZIG_TARGET)) + endif + endif endif # Shell detection @@ -1779,7 +1784,7 @@ ifneq ($(HB_HOST_PLAT)$(HB_HOST_CPU),$(HB_PLATFORM)$(HB_CPU)) # NOTE: MIPS64 is not yet distinctly recognized by the build system HB_PRGFLAGS += -D__ARCH64BIT__ else - ifeq ($(HB_CPU),alpha)) + ifeq ($(HB_CPU),alpha) # Alpha began as 64-bit CPU, only WinNT releases were limited to 32-bit ifeq ($(HB_PLATFORM),win) HB_PRGFLAGS += -D__ARCH32BIT__ diff --git a/config/linux/zig-noauto.mk b/config/linux/zig-noauto.mk new file mode 100644 index 0000000000..203c8af0cc --- /dev/null +++ b/config/linux/zig-noauto.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig-noauto.mk diff --git a/config/linux/zig.mk b/config/linux/zig.mk new file mode 100644 index 0000000000..911eb9b101 --- /dev/null +++ b/config/linux/zig.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig.mk diff --git a/config/win/zig-noauto.mk b/config/win/zig-noauto.mk new file mode 100644 index 0000000000..203c8af0cc --- /dev/null +++ b/config/win/zig-noauto.mk @@ -0,0 +1 @@ +include $(TOP)$(ROOT)config/common/zig-noauto.mk diff --git a/config/win/zig.mk b/config/win/zig.mk new file mode 100644 index 0000000000..3d2ec49c8c --- /dev/null +++ b/config/win/zig.mk @@ -0,0 +1,10 @@ +RC := zig rc +RCFLAGS := /I. /I$(HB_HOST_INC) /C 1252 +RC_OUT := /FO$(subst x,x, ) +RES_EXT := .res + +ifeq ($(HB_PLATFORM),win) + IMPLIBFLAGS = -Wl,--out-implib,$(IMP_FILE) +endif + +include $(TOP)$(ROOT)config/common/zig.mk diff --git a/utils/hbmk2/hbmk2.prg b/utils/hbmk2/hbmk2.prg index 2ae3eb1306..834c4db079 100644 --- a/utils/hbmk2/hbmk2.prg +++ b/utils/hbmk2/hbmk2.prg @@ -1862,11 +1862,11 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit CASE HBMK_ISPLAT( "darwin|bsd|hpux|sunos|beos|qnx|android|vxworks|symbian|linux|cygwin|minix|aix|wasm" ) DO CASE CASE hbmk[ _HBMK_cPLAT ] == "linux" - aCOMPSUP := { "gcc", "clang", "icc", "watcom", "sunpro", "open64", "pcc" } + aCOMPSUP := { "gcc", "clang", "icc", "watcom", "sunpro", "open64", "pcc", "zig" } CASE hbmk[ _HBMK_cPLAT ] == "darwin" - aCOMPSUP := { "gcc", "clang", "icc", "pcc" } + aCOMPSUP := { "gcc", "clang", "icc", "pcc", "zig" } CASE hbmk[ _HBMK_cPLAT ] == "bsd" - aCOMPSUP := { "gcc", "clang", "pcc" } + aCOMPSUP := { "gcc", "clang", "pcc", "zig" } CASE hbmk[ _HBMK_cPLAT ] == "sunos" aCOMPSUP := { "gcc", "sunpro", "pcc" } CASE hbmk[ _HBMK_cPLAT ] == "android" @@ -1987,10 +1987,11 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit { {|| FindInPath( "icl.exe" ) }, "icc" }, ; { {|| FindInPath( "xCC.exe" ) }, "xcc" }, ; { {|| FindInPath( "tcc.exe" ) }, "tcc" }, ; - { {|| FindInPath( "dmc.exe" ) }, "dmc" } } + { {|| FindInPath( "dmc.exe" ) }, "dmc" }, ; + { {|| FindInPath( "zig.exe" ) }, "zig" } } #endif aCOMPSUP := { ; - "mingw", "msvc", "clang", "bcc", "watcom", "icc", "pocc", "xcc", "tcc", ; + "mingw", "msvc", "clang", "bcc", "watcom", "icc", "pocc", "xcc", "tcc", "zig", ; "mingw64", "msvc64", "msvcarm", "msvcarm64", "msvcia64", "bcc64", "iccia64", "pocc64" } l_aLIBHBGT := { "gtwin", "gtwvt", "gtgui" } hbmk[ _HBMK_cGTDEFAULT ] := "gtwin" @@ -3616,7 +3617,7 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit CASE hb_FNameExt( cParamL ) == ".res" IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) .OR. ; - ( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang" ) ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang|zig" ) ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "os2" .AND. HBMK_ISCOMP( "gcc|gccomf" ) ) /* For MinGW/EMX GCC family add .res files as source input, as they will need to be converted to coff format with windres (just @@ -3903,7 +3904,7 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit hb_default( @hbmk[ _HBMK_lSHAREDDIST ], hbmk[ _HBMK_lSysLoc ] ) - IF hbmk[ _HBMK_lSHAREDDIST ] .OR. ! HBMK_ISCOMP( "gcc|clang|open64" ) + IF hbmk[ _HBMK_lSHAREDDIST ] .OR. ! HBMK_ISCOMP( "gcc|zig|clang|open64" ) l_cDynLibDir := "" ELSE /* Only supported by gcc, clang, open64 compilers. */ @@ -4008,6 +4009,13 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit cLibHBX_Regex := R_( "[\s]_?HB_FUN_([A-Z0-9_]*)[\s]" ) + /* is there a zig's own variable that does this? */ + IF hbmk[ _HBMK_cCOMP ] == "zig" .AND. ! Empty( GetEnv("HB_ZIG_TARGET") ) + AAdd( hbmk[ _HBMK_aOPTC ], "-target " + GetEnv("HB_ZIG_TARGET") ) + AAdd( hbmk[ _HBMK_aOPTL ], "-target " + GetEnv("HB_ZIG_TARGET") ) + AAdd( hbmk[ _HBMK_aOPTD ], "-target " + GetEnv("HB_ZIG_TARGET") ) + ENDIF + DO CASE /* GCC family */ CASE ( hbmk[ _HBMK_cPLAT ] == "bsd" .AND. hbmk[ _HBMK_cCOMP ] == "gcc" ) .OR. ; @@ -4036,6 +4044,9 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit ( hbmk[ _HBMK_cPLAT ] == "sunos" .AND. hbmk[ _HBMK_cCOMP ] == "pcc" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "minix" .AND. hbmk[ _HBMK_cCOMP ] == "gcc" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "aix" .AND. hbmk[ _HBMK_cCOMP ] == "gcc" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "linux" .AND. hbmk[ _HBMK_cCOMP ] == "zig" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "darwin" .AND. hbmk[ _HBMK_cCOMP ] == "zig" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "bsd" .AND. hbmk[ _HBMK_cCOMP ] == "zig" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "wasm" .AND. hbmk[ _HBMK_cCOMP ] == "emcc" ) #if defined( __PLATFORM__UNIX ) @@ -4058,7 +4069,7 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit cLibPrefix := "-l" cLibExt := "" cObjExt := ".o" - IF hbmk[ _HBMK_cPLAT ] == "darwin" + IF hbmk[ _HBMK_cPLAT ] == "darwin" .AND. ! hbmk[ _HBMK_cCOMP ] == "zig" cBin_Lib := "libtool" cOpt_Lib := "-static -no_warning_for_no_symbols {FA} -o {OL} {LO}" ELSE @@ -4069,6 +4080,8 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit cBin_Lib := "xiar" CASE hbmk[ _HBMK_cPLAT ] == "vxworks" cBin_Lib := hbmk[ _HBMK_cCCPREFIX ] + "ar" + hbmk[ _HBMK_cCCSUFFIX ] + CASE hbmk[ _HBMK_cCOMP ] == "zig" + cBin_Lib := "zig ar" OTHERWISE cBin_Lib := hbmk[ _HBMK_cCCPREFIX ] + "ar" ENDCASE @@ -4102,6 +4115,9 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit CASE hbmk[ _HBMK_cCOMP ] == "emcc" cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "em++" + hbmk[ _HBMK_cCCSUFFIX ] cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "emcc" + hbmk[ _HBMK_cCCSUFFIX ] ) + CASE hbmk[ _HBMK_cCOMP ] == "zig" + cBin_CompCPP := "zig c++" + cBin_CompC := "zig cc" OTHERWISE cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "g++" + hbmk[ _HBMK_cCCSUFFIX ] cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "gcc" + hbmk[ _HBMK_cCCSUFFIX ] ) @@ -4152,15 +4168,17 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit AAdd( hbmk[ _HBMK_aOPTL ], "-sWASM=1" ) AAdd( hbmk[ _HBMK_aOPTD ], "-sWASM=1" ) ENDIF + cOpt_CompC += " {FC}" IF ! Empty( hbmk[ _HBMK_cWorkDir ] ) /* Symbian gcc cross-compiler (on Windows) crashes if compiling multiple files at once */ IF ! hbmk[ _HBMK_cPLAT ] == "symbian" .AND. ; /* EXPERIMENTAL */ - ! hbmk[ _HBMK_cCOMP ] == "emcc" /* It creates the output in the source directory if no -o option is passed */ + ! hbmk[ _HBMK_cCOMP ] == "emcc" .AND. ; /* It creates the output in the source directory if no -o option is passed */ + ! hbmk[ _HBMK_cCOMP ] == "zig" lCHD_Comp := .T. cOpt_CompC += " {LC}" ELSE - IF HBMK_ISPLAT( "linux|bsd" ) .AND. hbmk[ _HBMK_cCOMP ] == "clang" + IF HBMK_ISPLAT( "linux|bsd" ) .AND. HBMK_ISCOMP( "clang|zig") /* NOTE: It is also accepted by darwin/clang */ cOpt_CompC += " {IC} -o{OO}" ELSE @@ -4400,6 +4418,7 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "mingw64" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "clang" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "tcc" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "zig" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "wce" .AND. hbmk[ _HBMK_cCOMP ] == "mingw" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "wce" .AND. hbmk[ _HBMK_cCOMP ] == "mingwarm" ) @@ -4425,6 +4444,9 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit AAdd( hbmk[ _HBMK_aOPTL ], "-Wl,-subsystem:console" ) ENDIF ENDIF + CASE hbmk[ _HBMK_cCOMP ] == "zig" + cBin_CompCPP := "zig" + hbmk[ _HBMK_cCCEXT ] + " c++" + cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, "zig" + hbmk[ _HBMK_cCCEXT ] + " cc" ) CASE hbmk[ _HBMK_cCOMP ] == "tcc" cBin_CompCPP := "tcc.exe" cBin_CompC := cBin_CompCPP @@ -4477,7 +4499,13 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit cOpt_CompC += " {FC}" cOptIncMask := "-I{DI}" IF ! Empty( hbmk[ _HBMK_cWorkDir ] ) - IF .T. /* EXPERIMENTAL */ + IF ! hbmk[ _HBMK_cCOMP ] == "zig" + /* IF .T. -- EXPERIMENTAL was here + * experiment was successful, except now + * not for zig compiler front on Windows + * it bugs out with such message: + * error: coff does not support linking multiple objects into one + * on multiple source files [alcz] ... which are not objects */ lCHD_Comp := .T. cOpt_CompC += " {LC}" ELSE @@ -4493,7 +4521,7 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit cOpt_Dyn := "-shared -o {OD} {LO} {FD} {IM} {DL} {LS}" IF "--script-mingw" $ GetEnv("HB_USER_FIXES") cOpt_Dyn += "{SCRIPT_MINGW}" - ELSEIF hbmk[ _HBMK_cCOMP ] == "clang" + ELSEIF HBMK_ISCOMP( "clang|zig") cOpt_Dyn += "{SCRIPT}{ESCAPE_BS}" ELSEIF ! hbmk[ _HBMK_cCOMP ] == "tcc" cOpt_Dyn += "{SCRIPT_MINGW}" @@ -4510,6 +4538,8 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit IF hbmk[ _HBMK_cCOMP ] == "clang" .AND. !( FindInPath( hbmk[ _HBMK_cCCPREFIX ] + "llvm-ar" + hbmk[ _HBMK_cCCEXT ] ) == NIL ) /* new clang toolchains not always distribute llvm-ar (or it is renamed) */ cBin_Lib := hbmk[ _HBMK_cCCPREFIX ] + "llvm-ar" + hbmk[ _HBMK_cCCEXT ] + ELSEIF hbmk[ _HBMK_cCOMP ] == "zig" + cBin_Lib := "zig" + hbmk[ _HBMK_cCCEXT ] + " ar" ELSEIF hbmk[ _HBMK_cCOMP ] == "tcc" cBin_Lib := "tiny_libmaker.exe" ELSE @@ -4645,6 +4675,15 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit ENDIF ENDIF + IF ! Empty( hbmk[ _HBMK_cCCPATH ] ) + cBin_Res := FNameEscape( hbmk[ _HBMK_cCCPATH ] + hb_ps() + cBin_Res, hbmk[ _HBMK_nCmd_Esc ] ) + ENDIF + ELSEIF hbmk[ _HBMK_cCOMP ] == "zig" + cBin_Res := "zig" + hbmk[ _HBMK_cCCEXT ] + " rc" + cResExt := ".res" + /* codepage default is confusing here too, a .rc file could be multi-language */ + cOpt_Res := "/C 1252 {FR} /FO {OS} {IR}" + IF ! Empty( hbmk[ _HBMK_cCCPATH ] ) cBin_Res := FNameEscape( hbmk[ _HBMK_cCCPATH ] + hb_ps() + cBin_Res, hbmk[ _HBMK_nCmd_Esc ] ) ENDIF @@ -6278,7 +6317,7 @@ STATIC FUNCTION __hbmk( aArgs, nArgTarget, nLevel, /* @ */ lPause, /* @ */ lExit "LNK4217: locally defined symbol ... imported in function ..." if using 'dllimport'. [vszakats] */ tmp := "" - CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) + CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang|zig" ) tmp := "__attribute__ (( dllimport ))" CASE HBMK_ISCOMP( "bcc|bcc64|watcom" ) tmp := "__declspec( dllimport )" @@ -8013,7 +8052,7 @@ STATIC PROCEDURE Set_lCreateDyn( hbmk, lValue ) STATIC FUNCTION gcc_opt_lngc_fill( hbmk ) DO CASE - CASE HBMK_ISCOMP( "gcc|gccarm|gccomf|mingw|mingw64|mingwarm|djgpp|icc|icc64|clang|clang64" ) + CASE HBMK_ISCOMP( "gcc|gccarm|gccomf|mingw|mingw64|mingwarm|djgpp|icc|icc64|clang|clang64|zig" ) SWITCH hbmk[ _HBMK_cC ] CASE "iso90" ; RETURN "-std=c89" /* aka c89, aka ansi */ @@ -8031,7 +8070,7 @@ STATIC FUNCTION gcc_opt_lngc_fill( hbmk ) STATIC FUNCTION gcc_opt_lngcpp_fill( hbmk ) DO CASE - CASE HBMK_ISCOMP( "gcc|gccarm|gccomf|mingw|mingw64|mingwarm|djgpp|clang|clang64" ) + CASE HBMK_ISCOMP( "gcc|gccarm|gccomf|mingw|mingw64|mingwarm|djgpp|clang|clang64|zig" ) SWITCH hbmk[ _HBMK_cCPP ] CASE "iso98" ; RETURN "-std=c++98" /* ~aka c++03, ~aka ansi */ @@ -8492,7 +8531,7 @@ STATIC FUNCTION FindNewerHeaders( hbmk, cFileName, tTimeParent, lCMode, cBin_Com cExt := Lower( hb_FNameExt( cFileName ) ) /* Filter out non-source format inputs for MinGW / windres */ - IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) .AND. HBMK_ISPLAT( "win|wce" ) .AND. cExt == ".res" + IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang|zig" ) .AND. HBMK_ISPLAT( "win|wce" ) .AND. cExt == ".res" RETURN .F. ENDIF @@ -8545,7 +8584,7 @@ STATIC FUNCTION FindNewerHeaders( hbmk, cFileName, tTimeParent, lCMode, cBin_Com ENDIF NEXT - ELSEIF lCMode .AND. hbmk[ _HBMK_nHEAD ] == _HEAD_NATIVE .AND. HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|djgpp|gccomf|clang|open64" ) + ELSEIF lCMode .AND. hbmk[ _HBMK_nHEAD ] == _HEAD_NATIVE .AND. HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|djgpp|gccomf|clang|open64|zig" ) IF hbmk[ _HBMK_lDEBUGINC ] _hbmk_OutStd( hbmk, hb_StrFormat( "debuginc: Calling C/C++ compiler to detect dependencies of %1$s", cFileName ) ) @@ -9553,7 +9592,7 @@ STATIC FUNCTION LibExists( hbmk, cDir, cLib, cLibPrefix, cLibExt ) cDir := hb_DirSepAdd( hb_DirSepToOS( cDir ) ) DO CASE - CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) .AND. HBMK_ISPLAT( "win|wce|cygwin" ) + CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang|zig" ) .AND. HBMK_ISPLAT( "win|wce|cygwin" ) /* NOTE: ld/gcc option -dll-search-prefix is not taken into account here, So, 'xxx.dll' format libs will not be found here in any case. */ DO CASE @@ -10280,7 +10319,7 @@ STATIC FUNCTION ListCookLib( hbmk, aLIB, aLIBA, array, cPrefix, cExtNew ) LOCAL cLibNameCooked LOCAL cName, cExt - IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|djgpp|gccomf|clang|open64" ) + IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|djgpp|gccomf|clang|open64|zig" ) FOR EACH cLibName IN array hb_FNameSplit( cLibName, @cDir ) IF Empty( cDir ) @@ -10415,7 +10454,7 @@ STATIC FUNCTION PathSepToTarget( hbmk, cFileName, nStart ) hb_default( @nStart, 1 ) - IF HBMK_ISPLAT( "win|wce|dos|os2" ) .AND. ! HBMK_ISCOMP( "mingw|mingw64|mingwarm|clang" ) + IF HBMK_ISPLAT( "win|wce|dos|os2" ) .AND. ! HBMK_ISCOMP( "mingw|mingw64|mingwarm|clang|zig" ) RETURN Left( cFileName, nStart - 1 ) + StrTran( SubStr( cFileName, nStart ), "/", "\" ) ENDIF @@ -10792,7 +10831,7 @@ STATIC FUNCTION HBC_ProcessOne( hbmk, cFileName, nNestingLevel ) NEXT CASE hb_FNameExt( cItemL ) == ".res" IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) .OR. ; - ( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang" ) ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang|zig" ) ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "os2" .AND. HBMK_ISCOMP( "gcc|gccomf" ) ) /* For MinGW/EMX GCC family add .res files as source input, as they will need to be converted to coff format with windres (just @@ -11950,7 +11989,7 @@ STATIC FUNCTION getFirstFunc( hbmk, cFile ) LOCAL cFuncList, cExecNM, cFuncName, cExt, cLine, n, c cFuncName := "" - IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|gccomf|clang" ) + IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|gccomf|clang|zig" ) hb_FNameSplit( cFile,,, @cExt ) IF cExt == ".c" FOR EACH cLine IN hb_ATokens( StrTran( hb_MemoRead( cFile ), Chr( 13 ), Chr( 10 ) ), Chr( 10 ) ) @@ -13234,7 +13273,7 @@ FUNCTION hbmk_KEYW( hbmk, cFileName, cKeyword, cValue, cOperator ) "|win|wce|dos|os2" + ; "|bsd|hpux|sunos|beos|qnx|android|vxworks|symbian|linux|darwin|cygwin|minix|aix" + ; "|msvc|msvc64|msvcia64|msvcarm|msvcarm64" + ; - "|pocc|pocc64|poccarm|xcc|tcc" + ; + "|pocc|pocc64|poccarm|xcc|tcc|zig" + ; "|mingw|mingw64|mingwarm|bcc|bcc64|watcom" + ; "|gcc|gccomf|djgpp" + ; "|hblib|hbdyn|hbdynvm|hbimplib|hbexe" + ; @@ -15931,13 +15970,13 @@ STATIC PROCEDURE ShowHelp( hbmk, lMore, lLong ) LOCAL aLst_Supp := { ; , ; - { "linux" , "gcc, clang, icc, watcom, sunpro, open64" }, ; - { "darwin" , "gcc, clang, icc" }, ; - { "win" , "mingw, msvc, clang, bcc, bcc64, watcom, icc, pocc, xcc, mingw64, msvc64, msvcarm, msvcarm64, msvcia64, iccia64, pocc64" }, ; + { "linux" , "gcc, clang, icc, watcom, sunpro, open64, zig" }, ; + { "darwin" , "gcc, clang, icc, zig" }, ; + { "win" , "mingw, msvc, clang, bcc, bcc64, watcom, icc, pocc, xcc, mingw64, msvc64, msvcarm, msvcarm64, msvcia64, iccia64, pocc64, zig" }, ; { "wce" , "mingwarm, mingw, msvcarm, poccarm" }, ; { "os2" , "gcc, gccomf, watcom" }, ; { "dos" , "djgpp, watcom" }, ; - { "bsd" , "gcc, clang, pcc" }, ; + { "bsd" , "gcc, clang, pcc, zig" }, ; { "hpux" , "gcc" }, ; { "beos" , "gcc" }, ; { "qnx" , "gcc" }, ;