* 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.
443 lines
15 KiB
Handlebars
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
|