Quando a gente formata a máquina, ou troca de máquina, é configurar tudo de novo.
É relativamente fácil, mas... a gente pode esquecer de coisas.
Meu pré-hbmk é uma ajuda nisso.
Mas cada um precisa ajustar de acordo com o que usa.
/*
BUILD - PRE-COMPILACAO
José Quintas
*/
REQUEST errorsys
#include "directry.ch"
FUNCTION Main( ... )
LOCAL aParams
SetMode( 38, 132 )
aParams := hb_AParams()
CheckPath()
checkHbmkHbc()
CheckGetEnv()
CheckBuild()
WriteBat( aParams )
Inkey(2)
RETURN NIL
STATIC FUNCTION WriteBat( aParams )
LOCAL oElement, cPath, cCmd := "", cBatFile := "d:\tools\util\c.bat"
cPath := Upper( hb_cwd() )
DO CASE
CASE "\HMGE\" $ cPath ; AAdd( aParams, "hmge.hbc" )
CASE "\HMG3\" $ cPath ; AAdd( aParams, "hmg3.hbc" )
CASE "\OOHG" $ cPath ; AAdd( aParams, "oohg.hbc" )
CASE "\HWGUI\" $ cPath ; AAdd( aParams, "hwgui.hbc" )
ENDCASE
IF Len( aParams ) != 0 .AND. aParams[ 1 ] == "/cmd"
hb_ADel( aParams, 1, .T. )
ELSEIF Len( Directory( "*.hbp" ) ) != 0
AAdd( aParams, "*.hbp" )
ELSEIF Len( Directory( "*.prg" ) ) != 0
Aadd( aParams, "*.prg" )
AAdd( aParams, "*.rc" )
ELSE
? hb_cwd()
Inkey(0)
ENDIF
AAdd( aParams, "-workdir=c:\temp" )
//AAdd( aParams, "-quiet" )
AAdd( aParams, "-q" )
AAdd( aParams, "-I" + hb_FNameDir( hb_ProgName() ) )
cCmd += "HBMK2 "
FOR EACH oElement IN aParams
cCmd += oElement + " "
NEXT
cCmd := hb_ProgName() + " %*" + hb_Eol() + cCmd + hb_Eol()
DO CASE
CASE "\SJPA\" $ cPath .AND. File( "..\sjpa.exe" ); cCmd += "assina ..\sjpa.exe" + hb_Eol()
CASE "\HAROLDO\" $ cPath .AND. File( "hl.exe" ); cCmd += "assina hl.exe" + hb_Eol()
CASE "\LABOROIL\" $ cPath .AND. File( "nfe.exe" ); cCmd += "assina nfe.exe" + hb_Eol()
CASE "\BUILD\" $ cPath .AND. File( "build.exe" ); cCmd += "assina build.exe" + hb_Eol()
CASE "\INTEGRA\" $ cPath .AND. File( "jpa.exe" ); cCmd += "assina jpa.exe" + hb_Eol()
ENDCASE
? "Atualizando " + cBatFile
hb_MemoWrit( cBatFile, cCmd )
RETURN NIL
STATIC FUNCTION CheckHbmkHbc()
LOCAL lUpdate := .F., cParam, cTxt := "", cFileHbmk, cPath
LOCAL aParams := { ;
"mt=yes", ;
"gui=yes", ;
"strip=yes", ;
"compr=yes", ;
"libpaths=d:/cdrom/fontes/integra/sefazclass", ;
"libpaths=d:/cdrom/fontes/integra/josequintas", ;
"libpaths=d:/cdrom/fontes/integra/josequintas/bostaurus", ;
"libpaths=d:/github/allgui/hmg3", ;
"libpaths=d:/github/allgui/hmge", ;
"libpaths=d:/github/allgui/hwgui", ;
"libpaths=d:/github/allgui/oohg", ;
"CFLAGS=-Wno-implicit-fallthrough -Wno-cast-function-type -Wno-misleading-indentation", ;
"PRGFLAGS=-m -n -w3 -es2 -ge1" }
cPath := CheckFileOnPath( "hbmk2.exe" )
IF Empty( cPath )
? "hbmk2.exe not found on path to check hbmk.hbc"
RETURN NIL
ENDIF
IF Right( cPath, 1 ) != "\"
cPath += "\"
ENDIF
cFileHbmk := cPath + "hbmk.hbc"
IF File( cFileHbmk )
cTxt := MemoRead( cFileHbmk )
IF Right( cTxt, 2 ) != hb_Eol()
cTxt += hb_Eol()
ENDIF
ENDIF
IF "xharbour" $ Lower( cPath )
AAdd( aParams, "-xhb" )
ENDIF
FOR EACH cParam IN aParams
IF ! cParam $ cTxt
cTxt += cParam + hb_Eol()
lUpdate := .T.
ENDIF
NEXT
IF lUpdate
hb_MemoWrit( cFileHbmk, cTxt )
ENDIF
RETURN NIL
STATIC FUNCTION CheckGetEnv()
LOCAL oElement
LOCAL aList := { ;
{ "HB_BUILD_DYN", "no" }, ;
{ "HB_BUILD_CONTRIB_DYN", "no" }, ;
{ "HB_BUILD_STRIP", "all" }, ;
{ "HB_COMPILER", "mingw" }, ;
{ "HB_INSTALL_PREFIX", "" } }
FOR EACH oElement IN aList
IF GetEnv( oElement[ 1 ] ) != oElement[ 2 ] .OR. Empty( GetEnv( oElement[ 1 ] ) )
? "Not found SET " + oElement[ 1 ] + "=" + oElement[ 2 ]
ENDIF
NEXT
RETURN NIL
STATIC FUNCTION CheckPath()
LOCAL cFile
FOR EACH cFile IN { "hbmk2.exe", "gcc.exe", "harbour.exe", "upx.exe", "c.bat" }
IF Empty( CheckFileOnPath( cFile ) )
? cFile + " not in PATH"
ENDIF
NEXT
RETURN NIL
STATIC FUNCTION CheckFileOnPath( cFile )
LOCAL cPath, cPathFile
cFile := Lower( cFile )
FOR EACH cPath IN hb_RegExSplit( ";", GetEnv( "PATH" ) )
IF Right( cPath, 1 ) != "\"
cPath := cPath + "\"
ENDIF
IF File( cPath + cFile )
cPathFile := cPath
EXIT
ENDIF
NEXT
RETURN cPathFile
STATIC FUNCTION CheckBuild()
LOCAL cDateTime, cTxt, nBuildNum, cFileName, cLastPath
cFileName := hb_FNameDir( hb_ProgName() ) + hb_FNameName( hb_ProgName() )
cDateTime := Dtos( Date() ) + Substr( Time(), 1, 2 ) + Substr( Time(), 4, 2 )
cTxt := MemoRead( cFileName + ".xml" )
nBuildNum := Val( XmlNode( cTxt, "BuildNum" ) ) + 1
cLastPath := XmlNode( cTxt, "LastPath" )
IF ! Upper( cLastPath ) == Upper( hb_cwd() )
DeleteContent( "c:\temp", .F. )
// DeleteContent( "c:\users\joseq\appdata\local\temp", .F. )
ENDIF
cTxt := "#define JOSEQUINTAS_VERSAO " + ["] + Transform( cDateTime, "@R 9999.99.99.9999" ) + ["] + hb_Eol()
cTxt += "#define JOSEQUINTAS_VERSAO_RC " + Transform( cDateTime, "@R 9999,99,99,9999" ) + hb_Eol()
hb_MemoWrit( cFileName + ".ch", cTxt )
IF File( "build.ch" ) // BHP ou projeto extra
hb_MemoWrit( "build.ch", cTxt )
ENDIF
cTxt := XmlTag( "BuildNum", nBuildNum, 0 ) + hb_Eol()
cTxt += XmlTag( "LastPath", hb_cwd() ) + hb_Eol()
cTxt += XmlTag( "BuildDate", Dtos( Date() ) ) + hb_Eol()
cTxt += XmlTag( "BuildTime", Time() ) + hb_Eol()
hb_MemoWrit( cFileName + ".xml", cTxt )
? "Build atual " + cDateTime
RETURN NIL
STATIC FUNCTION DeleteContent( cFolder, lDeleteFolder )
LOCAL oFiles, oFile, lDelete
hb_Default( @lDeleteFolder, .F. )
? "Delete on " + cFolder
oFiles := Directory( cFolder + "*.*" )
FOR EACH oFile IN oFiles
IF oFile[ F_ATTR ] == "D"
IF oFile[ F_NAME ] != "." .AND. oFile[ F_NAME ] != ".."
DeleteContent( cFolder + "\" + oFile[ F_NAME ], .T. )
ENDIF
ELSE
lDelete := .T.
DO CASE
CASE hb_FNameExt( oFile[ F_NAME ] ) == ".c"
CASE hb_FNameExt( oFile[ F_NAME ] ) == ".o"
CASE oFile[ F_DATE ] != Date()
CASE Left( oFile[ F_TIME ], 4 ) != Left( Time(), 4 )
OTHERWISE
lDelete := .F.
ENDCASE
IF lDelete
? "Deleting " + cFolder + "\" + oFile[ F_NAME ]
fErase( cFolder + "\" + oFile[ F_NAME ] )
ENDIF
ENDIF
NEXT
IF lDeleteFolder
DirRemove( cFolder )
ENDIF
RETURN NIL
FUNCTION HB_GT_SYS()
REQUEST HB_GT_WVG_DEFAULT
RETURN NIL
FUNCTION AppVersaoExe()
RETURN ""
O que ele tem de diferente?
Nada.
Apenas fui colocando o que achava interessante, ou coisas que eu poderia esquecer, ou coisas pra facilitar o dia a dia.
Primeiro princÃpio básico: um bat pode ser alterado.
tenho meu c.bat em \tools\útil que fica no path.
ele chama este programa, o build.exe
E o build.exe REESCREVE o que vai acontecer depois.
Começa por aÃ....
---c.bat----
d:\cdrom\fontes\build\build.exe %*
Em CheckGetEnv(), ele verifica se configurei as variáveis de ambiente do Harbour, isso faz parte do meu trabalho do dia a dia.
Em CheckPath(), ele verifica se os utilitários do Harbour estão no PATH, isso faz parte do meu dia a dia
Em CheckBuild(), ele vai atualizando o arquivo que indica versão/build, e também verifica se troquei minha pasta de trabalho, fazendo uma limpeza na temporária c:\temp
Em CheckHbmkHbc(), ele verifica se criei a pasta hbmk.hbc na pasta do Harbour, pra configurar minha compilação, com os parâmetros que uso
E finalmente, em WriteBat(), ele coloca o comando do HBMK2 que uso pra compilar.
Qualquer um pode fazer um programa assim, é só ir adicionando o que usa.
Vantagens:
Numa máquina zerada, vai me avisar tudo que preciso configurar.
Olhando o fonte, vejo tudo que uso.
Limpa minha pasta temporária ao trocar de projeto, pra eu não esquecer, e não misturar compilações
Já cria o comando do hbmk2 do jeito que uso
Nos programas que preciso assinar, já acrescenta pra assinar
Se forem pastas de minigui, hmg3, hmg extended, oohg, hwgui, já acrescenta o que precisa a mais pra essas LIBs
TODO meu trabalho sempre conferido, mesmo que eu troque de máquina.
A única coisa que preciso fazer é: pra compilar um projeto numa pasta digito C <ENTER>
Acrescentei a opção /cmd, pra poder digitar comandos livres, diferentes do padrão que ele usa.
Quem precisa disso?
Quem se perde pra configurar, e nem sabe configurar direito.
O problema é: vão saber ajustar para suas próprias necessidades?
Está aà pra quem quiser aproveitar a idéia.
Somos todos programadores, podemos fazer ferramentas pra nós.
Pra que espalhar BATs, se dá pra simplificar e centralizar?