Files
harbour-core/harbour/contrib/make.hbs
Viktor Szakats a170ec0c28 2010-07-07 11:52 UTC+0200 Viktor Szakats (harbour.01 syenar.hu)
* INSTALL
    * GNU Make 3.81 recommended (without 'or upper')
    + Documented GNU Make 3.81.90 bug.

  * contrib/make.hbs
    * Minor tweak to avoid line ending spaces in stdout.
    * Minor visual cleanup.

  * contrib/hbide/hbide.hbp
    + Added instfile option to install .dlls on Windows systems.

  * config/postinst.hbs
    ! Fixes in comment and feedback output.
    - Deleted commented .hbl generation stuff based on hbmk2.
2010-07-07 09:52:53 +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( "! project '%s' 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