Files
harbour-core/harbour/contrib/make.hbs
Viktor Szakats db1fbb5aed 2010-07-06 21:00 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* utils/hbrun/hbrun.prg
    ! Don't search passed program in PATH and hbrun dir, if
      program name has path component.

  * contrib/xhb/xhbenum.c
  * contrib/xhb/xhbqself.c
  * contrib/xhb/xhbwith.c
  * contrib/xhb/xhberrc.c
    ! Fixed msvc64 warnings after HB_SIZE extension in stack API.

  * contrib/make.hbs
    + Added logic to protect against case when 'clean install'
      is used but hbrun or hbmk2 isn't available when launching
      the make process. In this case 'clean' phase won't be executed
      for contribs, which is solved by forcing a -rebuild in
      'install' phase.

  * src/vm/strapi.c
  * src/vm/runner.c
  * src/vm/itemapi.c
  * src/vm/asort.c
  * src/vm/hvm.c
  * src/vm/arrays.c
  * src/vm/memvars.c
  * src/vm/set.c
  * src/vm/classes.c
  * src/rtl/lennum.c
  * src/rtl/strcase.c
  * src/rtl/replic.c
  * src/rtl/padr.c
  * src/rtl/padc.c
  * src/rtl/strtran.c
  * src/rtl/strtoexp.c
  * src/rtl/padl.c
  * src/rtl/saverest.c
  * src/rtl/right.c
  * src/rtl/philes.c
  * src/rtl/mlcfunc.c
  * src/rtl/left.c
  * src/rtl/xsavescr.c
  * src/rtl/setkey.c
  * src/rtl/stuff.c
  * src/rtl/trace.c
  * src/rtl/samples.c
  * src/rtl/inkeyapi.c
  * src/rtl/inkey.c
  * src/rtl/mtran.c
  * src/rtl/colorind.c
  * src/rtl/rat.c
  * include/hbapi.h
  * include/hbapistr.h
    * Renamed HB_SIZE variables to have 'n' prefix.
      (verified to generate the same objects as before)

  * src/rtl/philes.c
    * Changed hb_retnint()/hb_retni() to hb_retns().

  * contrib/hbgd/gdwrp.c
    * Formatting.
2010-07-06 19:02:19 +00:00

443 lines
15 KiB
Handlebars

/*
* $Id$
*/
/*
* This Harbour script is part of the GNU Make-based build system.
* WARNING: Running it separately is not supported.
*
* Copyright 2010 Viktor Szakats (harbour.01 syenar.hu)
* See COPYING for licensing terms.
*/
/* TODO:
1. error handling / reporting / feedback
2. solve the automatic in-dir make clean/install/rebuild workflow
*/
/* #pragma warninglevel=3 */
/* TOFIX: Ugly hack to avoid #include "directry.ch" */
#define F_NAME 1 /* File name */
#define F_ATTR 5 /* File attribute */
#define _ACT_EXIT 0
#define _ACT_CLEAN 1
#define _ACT_INC 2
#define _ACT_INC_INST 3
#define _ACT_INC_REBUILD_INST 4
STATIC s_lStdAlone
STATIC s_lTest
STATIC s_lMigr
PROCEDURE Main( ... )
LOCAL cBase := ""
LOCAL cRoot := "../"
LOCAL aImpLibs := {;
"gtalleg/gtalleg.hbi" ,;
"hbblat/hbblat.hbi" ,;
"hbcairo/hbcairo.hbi" ,;
"hbcurl/hbcurl.hbi" ,;
"hbfbird/hbfbird.hbi" ,;
"hbfimage/hbfimage.hbi" ,;
"hbgd/hbgd.hbi" ,;
"hbhpdf/hbhpdf.hbi" ,;
"hbmysql/hbmysql.hbi" ,;
"hbpgsql/hbpgsql.hbi" ,;
"hbssl/hbssl.hbi" ,;
"rddads/rddads.hbi" ,;
"sddfb/sddfb.hbi" ,;
"sddmy/sddmy.hbi" ,;
"sddoci/sddoci.hbi" ,;
"sddpg/sddpg.hbi" }
/* external libs hosted locally */
LOCAL aLibsPass0 := {}
LOCAL aLibsPass1 := {;
"hbblink/hbblink.hbp" ,;
"hbbz2/hbbz2.hbp" ,; /* uses: bz2 (external) */
"hbclipsm/hbclipsm.hbp" ,;
"hbcomm/hbcomm.hbp" ,;
"hbct/hbct.hbp" ,;
"hbfoxpro/hbfoxpro.hbp" ,;
"hbfship/hbfship.hbp" ,;
"hbgt/hbgt.hbp" ,;
"hbmemio/hbmemio.hbp" ,;
"hbmisc/hbmisc.hbp" ,;
"hbmzip/hbmzip.hbp" ,; /* uses: minizip (external) */
"hbnetio/hbnetio.hbp" ,;
"hbnf/hbnf.hbp" ,;
"hbodbc/hbodbc.hbp" ,;
"hbsms/hbsms.hbp" ,;
"hbsqlit3/hbsqlit3.hbp" ,; /* uses: sqlite3 (external) */
"hbtpathy/hbtpathy.hbp" ,;
"hbwin/hbwin.hbp" ,;
"hbxpp/hbxpp.hbp" ,;
"rddbmcdx/hbbmcdx.hbp" }
LOCAL aLibsPass2 := {;
"gtalleg/gtalleg.hbp" ,;
"gtalleg/gtallegs.hbp" ,;
"hbblat/hbblat.hbp" ,;
"hbcairo/hbcairo.hbp" ,;
"hbcups/hbcups.hbp" ,;
"hbcurl/hbcurl.hbp" ,;
"hbcurl/hbcurls.hbp" ,;
"hbfbird/hbfbird.hbp" ,;
"hbfimage/hbfimage.hbp" ,;
"hbgd/hbgd.hbp" ,; /* uses: hbct */
"hbhpdf/hbhpdf.hbp" ,;
"hbmysql/hbmysql.hbp" ,;
"hbpgsql/hbpgsql.hbp" ,;
"hbqt/hbqt.hbp" ,;
"hbqt/hbqtcore.hbp" ,;
"hbqt/hbqtcores.hbp" ,;
"hbqt/hbqtgui.hbp" ,;
"hbqt/hbqtguis.hbp" ,;
"hbqt/hbqtnetwork.hbp" ,;
"hbqt/hbqtnetworks.hbp" ,;
"hbqt/hbqts.hbp" ,;
"hbssl/hbssl.hbp" ,;
"hbssl/hbssls.hbp" ,;
"hbxbp/hbxbp.hbp" ,; /* uses: hbqt */
"rddads/rddads.hbp" ,;
"rddsql/rddsql.hbp" ,;
"sddfb/sddfb.hbp" ,; /* uses: rddsql */
"sddmy/sddmy.hbp" ,; /* uses: rddsql */
"sddoci/sddoci.hbp" ,; /* uses: rddsql */
"sddodbc/sddodbc.hbp" ,; /* uses: rddsql */
"sddpg/sddpg.hbp" ,; /* uses: rddsql */
"sddsqlt3/sddsqlt3.hbp" } /* uses: rddsql, sqlite3 (external) */
LOCAL aLibsPass3 := {;
"gtwvg/gtwvg.hbp" ,; /* uses: hbwin */
"hbtip/hbtip.hbp" ,;
"hbtip/hbtipssl.hbp" ,; /* uses: hbssl */
"hbziparc/hbziparc.hbp" ,; /* uses: hbmzip */
"xhb/xhb.hbp" } /* uses: hbct, hbtip, hbwin */
LOCAL aUtils := {;
"hbnetio/utils/hbnetio.hbp" ,; /* uses: hbnetio */
"hbide/hbide.hbp" } /* uses: hbxbp, hbqt */
LOCAL aAll
LOCAL hItem
LOCAL cProject
LOCAL cProjectDir
LOCAL cInstallDirVar
LOCAL cTargetDir
LOCAL cBaseOptions
LOCAL cOptionsPre
LOCAL cOptionsPost
LOCAL lBuildName
LOCAL cFilter
LOCAL aFilter
LOCAL lFilterNegative
LOCAL aParams
LOCAL aGNUMakeParams
LOCAL tmp
LOCAL nAction
s_lStdAlone := Empty( "HB_HOST_BIN_DIR" )
s_lMigr := "migr" $ hb_cmdLine()
IF s_lMigr
OutStd( "! New contrib make orchestrator test run. |" + hb_cmdLine() + "|" + GetEnv( "HB_MAKECMDGOALS" ) + "|" + hb_dirBase() + "|" + CurDir() + "|", hb_eol() )
/* testing with a limited set of contribs */
aLibsPass1 := {;
"hbblat/hbblat.hbp" ,;
"hbblink/hbblink.hbp" ,;
"hbclipsm/hbclipsm.hbp" ,;
"hbnetio/hbnetio.hbp" ,;
"rddbmcdx/hbbmcdx.hbp" }
aLibsPass2 := {}
aLibsPass3 := {}
aUtils := {;
"hbnetio/utils/hbnetio.hbp" }
ENDIF
/*
Workflow translation from GNU Make to hbmk2:
GNU Make parameter HB_MAKECMDGOALS nAction hbmk2 options
-- -------------- ---------- ---------------- ---------------------- -------------------------
#1 clean clean clean _ACT_CLEAN -clean
#2 install install install _ACT_INC_INST -inc -instpath=
#3 clean install clean clean install _ACT_CLEAN -clean
install clean install _ACT_INC_REBUILD_INST -inc -instpath= -rebuild
#4 install clean install install clean _ACT_INC_INST -inc -instpath=
clean install clean _ACT_CLEAN -clean
#5 all _ACT_INC -inc
*/
/* Determine the mode of operation */
s_lTest := "test" $ hb_cmdLine()
aParams := hb_AParams()
aGNUMakeParams := hb_ATokens( Lower( GetEnv( "HB_MAKECMDGOALS" ) ) )
DO CASE
CASE AScan( aParams, "clean" ) > 0
IF AScan( aGNUMakeParams, "clean" ) > 0 .AND. ;
AScan( aGNUMakeParams, "install" ) > 0 .AND. ;
AScan( aGNUMakeParams, "install" ) > AScan( aGNUMakeParams, "clean" )
nAction := _ACT_CLEAN
ELSE
nAction := _ACT_CLEAN
ENDIF
CASE AScan( aParams, "install" ) > 0
IF AScan( aGNUMakeParams, "clean" ) > 0 .AND. ;
AScan( aGNUMakeParams, "install" ) > 0 .AND. ;
AScan( aGNUMakeParams, "install" ) > AScan( aGNUMakeParams, "clean" )
/* Use rebuild mode. This is needed because the clean phase
might not have been called previously by GNU Make, f.e.
because hbrun or hbmk2 wasn't available. -rebuild is
costless, so we do it to make sure to build cleanly.
[vszakats] */
nAction := _ACT_INC_REBUILD_INST
ELSE
nAction := _ACT_INC_INST
ENDIF
OTHERWISE
nAction := _ACT_INC
ENDCASE
IF nAction == _ACT_EXIT
ErrorLevel( 0 )
RETURN
ENDIF
/* Check if the requirements are met and if we have anything to do */
IF Empty( GetEnv( "HB_PLATFORM" ) ) .OR. ;
Empty( GetEnv( "HB_COMPILER" ) ) .OR. ;
Empty( GetEnv( "HB_HOST_BIN_DIR" ) )
ErrorLevel( 9 )
RETURN
ENDIF
cFilter := GetEnv( "HB_CONTRIBLIBS" )
IF cFilter == "no"
ErrorLevel( 0 )
RETURN
ENDIF
SetCancel( .F. )
/* Converting build options to hbmk2 options */
cBaseOptions := "-quiet -lang=en -width=0 -q0"
IF s_lMigr
cBaseOptions += " -quiet- -info -trace"
ENDIF
IF GetEnv( "HB_BUILD_MODE" ) == "cpp"
cBaseOptions += " -cpp=yes"
ELSEIF GetEnv( "HB_BUILD_MODE" ) == "c"
cBaseOptions += " -cpp=no"
ENDIF
IF GetEnv( "HB_BUILD_DEBUG" ) == "yes"
cBaseOptions += " -debug"
ENDIF
IF ! Empty( GetEnv( "HB_BUILD_NAME" ) )
cBaseOptions += " -build=" + GetEnv( "HB_BUILD_NAME" )
lBuildName := .T.
ELSE
lBuildName := .F.
ENDIF
/* Clearing envvars that may interact with hbmk2 */
/* Copy original install dirs to our own variables */
hb_setenv( "_HB_BIN_INSTALL", GetEnv( "HB_BIN_INSTALL" ) )
hb_setenv( "_HB_LIB_INSTALL", GetEnv( "HB_LIB_INSTALL" ) )
hb_setenv( "_HB_DYN_INSTALL", GetEnv( "HB_DYN_INSTALL" ) )
hb_setenv( "_HB_INC_INSTALL", GetEnv( "HB_INC_INSTALL" ) )
/* Override hbmk2 autodetection */
hb_setenv( "HB_INSTALL_PREFIX", cRoot )
hb_setenv( "HB_BIN_INSTALL", cRoot + "bin/" + GetEnv( "HB_PLATFORM" ) + "/" + GetEnv( "HB_COMPILER" ) + iif( lBuildName, "/" + GetEnv( "HB_BUILD_NAME" ), "" ) )
hb_setenv( "HB_LIB_INSTALL", cRoot + "lib/" + GetEnv( "HB_PLATFORM" ) + "/" + GetEnv( "HB_COMPILER" ) + iif( lBuildName, "/" + GetEnv( "HB_BUILD_NAME" ), "" ) )
hb_setenv( "HB_DYN_INSTALL" )
hb_setenv( "HB_INC_INSTALL", cRoot + "include" )
/* Using shorter vars to save on cmdline length */
hb_setenv( "__HB_B", GetEnv( "HB_BIN_INSTALL" ) )
hb_setenv( "__HB_L", GetEnv( "HB_LIB_INSTALL" ) )
hb_setenv( "__HB_D", GetEnv( "HB_DYN_INSTALL" ) )
hb_setenv( "__HB_I", GetEnv( "HB_INC_INSTALL" ) )
/* Parse filter */
aFilter := iif( Empty( cFilter ), {}, hb_ATokens( cFilter,, .T. ) )
IF Len( aFilter ) >= 1 .AND. aFilter[ 1 ] == "no"
hb_ADel( aFilter, 1, .T. )
lFilterNegative := .T.
ELSE
lFilterNegative := .F.
ENDIF
/* Start building */
aAll := {;
{ "type" => "implib", "list" => aImpLibs },;
{ "type" => "lib" , "list" => aLibsPass0 },;
{ "type" => "lib" , "list" => aLibsPass1 },;
{ "type" => "lib" , "list" => aLibsPass2 },;
{ "type" => "lib" , "list" => aLibsPass3 },;
{ "type" => "bin" , "list" => aUtils },;
{ "type" => "lib" , "list" => hb_ATokens( GetEnv( "HB_ADDONS_LIB" ),, .T. ) },;
{ "type" => "bin" , "list" => hb_ATokens( GetEnv( "HB_ADDONS_BIN" ),, .T. ) } }
FOR EACH hItem IN aAll
FOR EACH cProject IN hItem[ "list" ]
IF ! Empty( cProject )
cProject := StrTran( cProject, "\", "/" )
IF ( tmp := At( "/", cProject ) ) > 0
cProjectDir := Left( cProject, tmp - 1 )
ELSE
cProjectDir := ""
ENDIF
IF Empty( aFilter ) .OR. ;
iif( lFilterNegative,;
AScan( aFilter, {| tmp | tmp == cProjectDir } ) == 0,;
AScan( aFilter, {| tmp | tmp == cProjectDir } ) > 0 )
cOptionsPre := cBaseOptions
cOptionsPost := ""
SWITCH hItem[ "type" ]
CASE "lib"
CASE "implib"
cTargetDir := "${__HB_L}"
cInstallDirVar := "_HB_LIB_INSTALL"
EXIT
CASE "bin"
cTargetDir := "${__HB_B}"
cInstallDirVar := "_HB_BIN_INSTALL"
IF GetEnv( "HB_BUILD_SHARED" ) == "yes"
cOptionsPre += " -shared"
ENDIF
EXIT
ENDSWITCH
IF nAction == _ACT_CLEAN
cOptionsPre += " -clean"
ELSE
cOptionsPre += " -inc"
IF nAction == _ACT_INC_REBUILD_INST
cOptionsPre += " -rebuild"
ENDIF
IF nAction == _ACT_INC_INST .OR. ;
nAction == _ACT_INC_REBUILD_INST
IF ! Empty( GetEnv( cInstallDirVar ) ) .AND. ;
( ! ( hItem[ "type" ] == "implib" ) .OR. GetEnv( "HB_BUILD_IMPLIB" ) == "yes" )
cOptionsPre += " -instpath=${" + cInstallDirVar + "}/"
IF hItem[ "type" ] == "lib"
cOptionsPre += " -instpath=inc:${_HB_INC_INSTALL}/"
ENDIF
ENDIF
ENDIF
ENDIF
call_hbmk2( cBase + cProject, cTargetDir, cOptionsPre, cOptionsPost, .F. )
/* Highly experimental */
IF hItem[ "type" ] == "lib" .AND. GetEnv( "HB_BUILD_CONTRIB_DLL" ) == "yes" .AND. ;
hb_FileExists( FN_ExtSet( cBase + cProject, ".hbc" ) )
cInstallDirVar := "_HB_DYN_INSTALL"
cOptionsPre := cBaseOptions
/* TOFIX: Add -implib option. It collides with static lib so needs to be resolved. */
cOptionsPost := " -hbdyn -nohblib- " + FN_ExtSet( cProject, ".hbc" )
IF nAction == _ACT_CLEAN
cOptionsPre += " -clean"
ELSE
cOptionsPre += " -inc"
IF nAction == _ACT_INC_REBUILD_INST
cOptionsPre += " -rebuild"
ENDIF
IF nAction == _ACT_INC_INST .OR. ;
nAction == _ACT_INC_REBUILD_INST
IF ! Empty( GetEnv( cInstallDirVar ) )
cOptionsPre += " -instpath=${" + cInstallDirVar + "}/"
ENDIF
ENDIF
ENDIF
call_hbmk2( cBase + cProject, cTargetDir, cOptionsPre, cOptionsPost, .T. )
ENDIF
ELSE
/* OutStd( hb_StrFormat( "'%s' project skipped", cProject ), hb_eol() ) */
ENDIF
ENDIF
NEXT
NEXT
ErrorLevel( 0 )
RETURN
STATIC FUNCTION call_hbmk2( cProject, cTargetDir, cOptionsPre, cOptionsPost, lDyn )
LOCAL nErrorLevel
LOCAL cDir, cName
hb_FNameSplit( cProject, @cDir, @cName )
/* Keeping cmdline as short as possible. Also making sure that user settings
do not interfere with the std build process. */
hb_setenv( "HBMK_OPTIONS", cOptionsPre )
nErrorLevel := mk_hb_processRun( PathSepToSelf( GetEnv( "HB_HOST_BIN_DIR" ) ) + hb_ps() + "hbmk2" +;
" " + cProject +;
cOptionsPost +;
" -workdir=" + cTargetDir + "/${hb_work}/" + cName + iif( lDyn, "${hb_workdynsub}", "" ) +;
" -o" + cTargetDir + "/" )
IF nErrorLevel != 0
OutStd( hb_StrFormat( "'%s' returned status: %s", cProject, hb_ntos( nErrorLevel ) ), hb_eol() )
RETURN .F.
ENDIF
RETURN .T.
STATIC FUNCTION mk_hb_processRun( cCommand )
OutStd( cCommand, hb_eol() )
RETURN iif( s_lTest, 0, hb_processRun( cCommand ) )
STATIC FUNCTION FN_ExtSet( cFileName, cExt )
LOCAL cDir, cName
hb_FNameSplit( cFileName, @cDir, @cName )
RETURN hb_FNameMerge( cDir, cName, cExt )
STATIC FUNCTION PathSepToSelf( cFileName )
#if defined( __PLATFORM__WINDOWS ) .OR. ;
defined( __PLATFORM__DOS ) .OR. ;
defined( __PLATFORM__OS2 )
RETURN StrTran( cFileName, "/", "\" )
#else
RETURN StrTran( cFileName, "\", "/" )
#endif