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.
This commit is contained in:
Aleksander Czajczynski
2025-10-18 23:15:08 +02:00
parent 1465b9cc53
commit aba6779100
13 changed files with 307 additions and 28 deletions

View File

@@ -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

1
config/bsd/zig-noauto.mk Normal file
View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig-noauto.mk

1
config/bsd/zig.mk Normal file
View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig.mk

View File

@@ -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

104
config/common/zig.mk Normal file
View File

@@ -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

View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig-noauto.mk

1
config/darwin/zig.mk Normal file
View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig.mk

View File

@@ -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__

View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig-noauto.mk

1
config/linux/zig.mk Normal file
View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig.mk

1
config/win/zig-noauto.mk Normal file
View File

@@ -0,0 +1 @@
include $(TOP)$(ROOT)config/common/zig-noauto.mk

10
config/win/zig.mk Normal file
View File

@@ -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

View File

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