Hi Viktor, I've just tried hbmk2.prg and I have few notes about it.
1. the C compiler auto detection should be extended to use also compiler used to compile Harbour. This is peace of code I was using from my hb-tools.prg: if empty( s_hb_compiler ) cEnv := getEnv( "HB_COMPILER" ) if !empty( cEnv ) s_hb_compiler := cEnv else cEnv := hb_compiler() if ( "Borland" $ cEnv .or. "CodeGear" $ cEnv ) .and. ; isExecutable( s_hb_ccprefix + "bcc32" ) s_hb_compiler := "bcc32" elseif "DJGPP" $ cEnv .and. isExecutable( s_hb_ccprefix + "gcc" ) s_hb_compiler := "djgpp" elseif "MinGW" $ cEnv .and. isExecutable( s_hb_ccprefix + "gcc" ) s_hb_compiler := "mingw" elseif "GNU C++" $ cEnv .and. isExecutable( s_hb_ccprefix + "g++" ) s_hb_compiler := "g++" elseif "GNU C" $ cEnv .and. isExecutable( s_hb_ccprefix + "gcc" ) s_hb_compiler := "gcc" elseif "Watcom C++" $ cEnv .and. isExecutable( s_hb_ccprefix + "wpp386" ) s_hb_compiler := "wpp386" elseif "Watcom C" $ cEnv .and. isExecutable( s_hb_ccprefix + "wcc386" ) s_hb_compiler := "wcc386" elseif "(XCC)" $ cEnv .and. isExecutable( s_hb_ccprefix + "xcc" ) s_hb_compiler := "xcc" elseif "Pelles ISO C" $ cEnv .and. isExecutable( s_hb_ccprefix + "pocc" ) s_hb_compiler := "pocc" elseif "Digital Mars" $ cEnv .and. isExecutable( s_hb_ccprefix + "dmc" ) s_hb_compiler := "dmc" elseif "Microsoft Visual C" $ cEnv .and. isExecutable( s_hb_ccprefix + "cl" ) s_hb_compiler := "msvc" endif endif endif /* in few cases compiler can be used only with single platform so we * can always set it here overloading any auto detections */ switch s_hb_compiler case "mingw" case "mingwce" case "bcc32" case "xcc" case "pocc" case "dmc" case "msvc" s_hb_arch := "win" exit case "djgpp" s_hb_arch := "dos" exit endswitch static function isExecutable( cExecName ) return findExecutable( cExecName ) != NIL static function findExecutable( cExecName ) local cFile, cPath, cExt hb_FNameSplit( cExecName,, @cExecName, @cExt ) #if defined( __PLATFORM__DOS ) .or. ; defined( __PLATFORM__WINDOWS ) .or. ; defined( __PLATFORM__OS2 ) if empty( cExt ) cExt := ".exe" endif #endif hb_FNameSplit( hb_argv( 0 ), @cPath ) if !empty( cPath ) cFile := hb_FNameMerge( cPath, cExecName, cExt ) if hb_fileExists( cFile ) return cFile endif endif for each cPath in hb_aTokens( getEnv( "PATH" ), hb_osPathListSeparator() ) cFile := hb_FNameMerge( cPath, cExecName, cExt ) if hb_fileExists( cFile ) return cFile endif next return NIL 2. install dir auto detection should be updated. In general we have two version of installation: a) <basdir>/bin <basdir>/include <basdir>/lib b) <basdir>/bin <basdir>/include/harbour <basdir>/lib/harbour so I was using this code: if !empty( s_hb_hbexe ) hb_FNameSplit( s_hb_hbexe, @cBinPath ) if right( cBinPath, 1 ) $ hb_osPathDelimiters() cBinPath := left( cBinPath, len( cBinPath ) - 1 ) endif hb_FNameSplit( cBinPath, @cPath, @cName ) if lower( cName ) == "bin" if !right( cPath, 1 ) $ hb_osPathDelimiters() cPath += hb_osPathSeparator() endif if hb_dirExists( cPath + "lib" ) .and. hb_dirExists( cPath + "include" ) if isLib( "hbvm", cPath + "lib" ) .and. ; hb_fileExists( cPath + "include" + hb_osPathSeparator() + "hbvm.h" ) s_hb_bindir := cBinPath s_hb_libdir := cPath + "lib" s_hb_incdir := cPath + "include" elseif isLib( "hbvm", cPath + "lib" + hb_osPathSeparator() + ; "harbour" ) .and. ; hb_fileExists( cPath + "include" + hb_osPathSeparator() + ; "harbour" + hb_osPathSeparator() + "hbvm.h" ) s_hb_bindir := cBinPath s_hb_libdir := cPath + "lib" + hb_osPathSeparator() + "harbour" s_hb_incdir := cPath + "include" + hb_osPathSeparator() + "harbour" endif endif endif endif static function isLib( cLib, cPath ) return hb_fileExists( iif( cPath == NIL, s_hb_libdir, cPath ) + ; hb_osPathSeparator() + ; s_hb_libpfx + cLib + s_hb_libext ) 3. in *nixes GTCGI have to be used as GT driver in hbmk.prg otherwise output from external command is lost. Probably it should be default also for all other platforms. 4. Such tool should be as invisible as possible so it should not any additional information until not explicitly requested by some switch, f.e. -verbose or sth like that to not mix the default output from executed compilers. It will be good to have additional verbose level in which executed command are shown before running compiler application to verify final results, f.e. options included by -bldflags 5. non of Harbour compiler options ( -n -q -w -es2, ...) should be enabled by default except the options necessary to compile the code: -I<HarbourIncludeDir>, -D<crossBuildDefines>, -undef:<crossBuildDefines> and of course -gc[0-3] to force .c output but only if user does not specify other form, f.e. -gh. 6. -bldflags should be probably divided into C flags and .prg flags. User may use completely different .prg flags then the ones we used to build Harbour but need C flags which can be necessary to create valid binaries. It will be also good to add automatic support for inheriting some C flags we know that are always necessary to create valid binaries, f.e. -m32/-m64 on some platforms which can create 32 or 64 bit binaries. For GCC I was always using this flags: if s_hb_cc == "gcc" .or. s_hb_cc == "g++" if "-mlp64" $ s_hb_bldflags s_hb_cc_opt -= " -mlp64" elseif "-mlp32" $ s_hb_bldflags s_hb_cc_opt -= " -mlp32" elseif "-m64" $ s_hb_bldflags s_hb_cc_opt -= " -m64" elseif "-m32" $ s_hb_bldflags s_hb_cc_opt -= " -m32" endif if "-fPIC" $ s_hb_bldflags s_hb_cc_opt -= " -fPIC" elseif "-fpic" $ s_hb_bldflags s_hb_cc_opt -= " -fpic" endif endif 7. output file name auto detection should respect the compilation mode, f.e. hbmk -cmp a.prg it should generate a.{o,obj} not 'a' or 'a.exe' 8. When -l<libname> gcc option is used then <libname> should not contain prefix (lib) and extension (.so,.dll,.a) 9. We should have support for passing object archives (.a) in link file list and then pass it to GCC without -l parameter. Using 'mylib.a' and '-lmylib' as GCC parameters has different meaning so mylib.a should not be converted to -lmylib but simply passed to GCC as is. 10. In GCC builds on platforms which support -Wl,--start-group <HARBOUR_LIBS> -Wl,--end-group (linux, mingw) we should use it to not replicate libraries with cross bindings. BTW current library list is not well ordered so it's not possible to create some binaries, f.e. try hbmk hbrun.prg in some GCC builds. It has to be updated for platforms which does not support above library grouping. 11. There is no support for automatic main function detection in GCC builds. This code extracts 1-st function name from the 1-st linked file in my hb-tools.prg. It can receive the name of .c file generated from .prg file or .o file name but in such case it works only for gcc/g++ based compilers (it uses nm tool). /* in GCC LD (except DJGPP) the order of registering init function * does not depend directly on the order of linked files. If we want * to inform HVM about valid startup function then we should try to * locate it ourselves and pass it to HVM using our startup function */ static func getFirstFunc( cFile ) local cFuncList, cExecNM, cFuncName, cExt, cLine, n, c cFuncName := "" if ( s_hb_cc == "gcc" .or. s_hb_cc == "g++" ) .and. !s_hb_compiler == "djgpp" hb_FNameSplit( cFile,,, @cExt ) if cExt == ".c" for each cLine in hb_aTokens( strtran( memoread( cFile ), chr( 13 ), chr( 10 ) ), chr( 10 ) ) cLine := alltrim( cLine ) if cLine = '{ "' .and. "HB_FS_FIRST" $ cLine n := 4 while ( c := substr( cLine, n++, 1 ) ) != '"' cFuncName += c enddo exit endif next elseif !empty( cExecNM := findExecutable( s_hb_ccprefix + "nm" ) ) cFuncList := commandResult( cExecNM + " " + cFile + " -g -n --defined-only -C" ) if ( n := at( " T HB_FUN_", cFuncList ) ) != 0 n += 10 while ( c := substr( cFuncList, n++, 1 ) ) = "_" .or. ; isdigit( c ) .or. isAlpha( c ) cFuncName += c enddo endif endif endif return cFuncName static function commandResult( cCommand, nResult ) local hFile, cFileName, cResult hFile := hb_FTempCreate( ,,, @cFileName ) if hFile == -1 outErr( "Error: cannot create temporary file" + EOL ) break endif fclose( hFile ) cCommand += ">" + cFileName nResult := hb_run( cCommand ) cResult := memoRead( cFileName ) ferase( cFileName ) return cResult when we will have fully functional hbmk.prg then we can change the startup code and replace current -n1 and default support for HB_FS_FIRST. HB_FS_FIRST will be generated only by new explicit switch which will be used by hbmk for 1-st file only. 12. hbdebug and hbcplr libraries are not part of Harbour shared library and always should be added as static libraries even when harbour shared library is used 13. the -o can point also to directory name not only file. hbmk.prg should respect it and check the type of destination. Some C compilers does not support -o as directory name so they will need different calling if more then one .c file is passed in single command, f.e. explicitly used chdir. Harbour compiler support -o as directory name if the last character is path separator, f.e.: harbour test.prg -ooutdir/ it would be very nice if hbmk.prg can use -o<dir> also for temporary C files. HTH and thank you for your job. best regards, Przemek _______________________________________________ Harbour mailing list Harbour@harbour-project.org http://lists.harbour-project.org/mailman/listinfo/harbour