Files
harbour-core/harbour/contrib/makefile.hbs
Viktor Szakats 126a3a7c17 2010-07-05 12:15 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* contrib/hbqt/hbmk2_plugin_qt.hbs
    + Return errors if required tools are not detected.
      (these errors are not yet all handled by hbmk2)
    + Refined tools detection on Windows to not try HB_WITH_QT 
      if not set at all.
    ! Fixed tool detection failure err msg to display proper 
      list of envvars able to control the process.

  * contrib/makefile.hbs
    + Employed several different techniques to avoid long 
      cmdline length to make certain (f.e. MS-DOS) hosts happy.
    
  * utils/hbmk2/hbmk2.prg
    + Added hbmk2_ArrayToList() function.
2010-07-06 10:15:45 +00:00

417 lines
14 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 _PS_ hb_osPathSeparator()
#define _ACT_CLEAN 1
#define _ACT_INC 2
#define _ACT_INC_INST 3
#define _ACT_INC_REBUILD_INST 4
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 tmp
LOCAL nAction
s_lMigr := "migr" $ hb_cmdLine()
IF s_lMigr
OutStd( "! New contrib make orchestrator test run. |" + hb_cmdLine() + "|" + GetEnv( "HB_MAKECMDGOALS" ) + "|" + hb_dirBase() + "|" + CurDir() + "|", hb_osNewLine() )
/* 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_INST -inc -instpath=
#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()
DO CASE
CASE AScan( aParams, "clean" ) > 0
nAction := _ACT_CLEAN
CASE AScan( aParams, "install" ) > 0
nAction := _ACT_INC_INST
OTHERWISE
nAction := _ACT_INC
ENDCASE
/* 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 */
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" ) )
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" ) )
hb_setenv( "HBMK_OPTIONS" )
/* 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_osNewLine() ) */
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 */
hb_setenv( "HBMK_OPTIONS", cOptionsPre )
nErrorLevel := mk_hb_processRun( PathSepToSelf( GetEnv( "HB_HOST_BIN_DIR" ) ) + _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_osNewLine() )
RETURN .F.
ENDIF
RETURN .T.
STATIC FUNCTION mk_hb_processRun( cCommand )
OutStd( cCommand, hb_osNewLine() )
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