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" }, ;