diff --git a/harbour/ChangeLog b/harbour/ChangeLog index b857501c3a..27767561d0 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,40 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-05-08 11:53 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * utils/hbmk2/hbmk2.prg + + Extended -mkimplib option for windows gcc compilers (mingw/cygwin) + to first look for matching COFF .lib file and use it to create + import library. If such is not found, try to use matching .def + file and automatically generate import library using dlltool. + If none if these were found, use the .dll directly, to create + the import library. In case of Harbour, this method resolves + almost all mingw implib needs. + See longer note in source (in function win_implib_command_gcc()) + about the details of the problem, the only thing I cannot see + is why mingw/cygwin developers insist on not fixing this issue + since ten year, while all other compilers can properly resolve + this problem. Anyhow until then mingw cannot use .dll using + stdcall calling convention without COFF .lib or .def file. If + both are missing, the only solution is to manually build a + .def file by first generating it from .dll then manually + adding '@nn' decoration according to function prototypes. + Thanks mingw. + + * config/postinst.prg + - Deleted APOLLO implib generation. Apollo fall into the + problematic category for mingw, because developers chose + to use stdcall callconv and they forgot to provide + implib or .def file. It's not part of core anyway. + * Slightly changed mysql implib generation to also work + for mingw. + - Deleted no more necessary manuall hack for mysql implib + generation. + + Added manual hack for firebird implib generation. In + this hbmk2 automatism cannot work as they distribute + COFF .lib in another directory and using a different + name than the .dll. + 2010-05-08 09:32 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * include/hbsetup.h + Added detection for HB_OS_IPHONE. Name tentative, diff --git a/harbour/config/postinst.prg b/harbour/config/postinst.prg index d9713f10a0..3a9d8d660c 100644 --- a/harbour/config/postinst.prg +++ b/harbour/config/postinst.prg @@ -81,18 +81,16 @@ PROCEDURE Main() { "HB_WITH_ADS" , "ace32.dll" , .F., "" },; { "HB_WITH_ADS" , "32bit\ace32.dll" , .F., "" },; { "HB_WITH_ALLEGRO" , "..\bin\alleg42.dll" , .T., "alleg" },; - { "HB_WITH_APOLLO" , "..\sde61.dll" , .F., "" },; - { "HB_WITH_APOLLO" , "..\sde7.dll" , .F., "" },; { "HB_WITH_BLAT" , "..\blat.dll" , .T., "" },; { "HB_WITH_CAIRO" , "..\..\bin\libcairo-2.dll" , .T., "cairo" },; { "HB_WITH_CURL" , "..\libcurl.dll" , .T., "" },; { "HB_WITH_CURL" , "..\bin\libcurl.dll" , .T., "" },; - { "HB_WITH_FIREBIRD" , "..\bin\fbclient.dll" , .F., "" },; + { "HB_WITH_FIREBIRD" , "..\bin\fbclient.dll" , .F., "" },; /* Doesn't work for mingw, because .lib has another name in another directory */ { "HB_WITH_FREEIMAGE" , "..\Dist\FreeImage.dll" , .F., "" },; { "HB_WITH_GD" , "..\bin\bgd.dll" , .F., "" },; { "HB_WITH_LIBHARU" , "..\libhpdf.dll" , .F., "" },; { "HB_WITH_LIBHARU" , "..\lib_dll\libhpdf.dll" , .F., "" },; - { "HB_WITH_MYSQL" , "..\bin\libmySQL.dll" , .F., "" },; + { "HB_WITH_MYSQL" , "..\lib\opt\libmySQL.dll" , .F., "" },; { "HB_WITH_OCILIB" , "..\lib32\ociliba.dll" , .F., "" },; { "HB_WITH_OCILIB" , "..\lib32\ocilibm.dll" , .F., "" },; { "HB_WITH_OCILIB" , "..\lib32\ocilibw.dll" , .F., "" },; @@ -113,9 +111,9 @@ PROCEDURE Main() ENDIF NEXT - /* HACK: Copying .dll to .a doesn't work in case of mysql, so we copy over the supplied import lib. [vszakats] */ - IF GetEnv( "HB_COMPILER" ) $ "mingw|mingw64" - hb_FCopy( GetEnv( "HB_WITH_MYSQL" ) + _PS_ + StrTran( "..\lib\opt\libmySQL.lib", "\", _PS_ ), GetEnv( "HB_LIB_INSTALL" ) + _PS_ + "liblibmysql.a" ) + /* HACK: Automatic implib generation doesn't work in case of FireBird, so we manually create it. [vszakats] */ + IF GetEnv( "HB_COMPILER" ) $ "mingw|mingw64|cygwin" + hb_FCopy( GetEnv( "HB_WITH_FIREBIRD" ) + _PS_ + StrTran( "..\lib\fbclient_ms.lib", "\", _PS_ ), GetEnv( "HB_LIB_INSTALL" ) + _PS_ + "libfbclient.a" ) ENDIF /* Exception: We use static libs with mingw */ diff --git a/harbour/utils/hbmk2/hbmk2.prg b/harbour/utils/hbmk2/hbmk2.prg index 41e49a6054..ac081ca83c 100644 --- a/harbour/utils/hbmk2/hbmk2.prg +++ b/harbour/utils/hbmk2/hbmk2.prg @@ -2685,7 +2685,7 @@ FUNCTION hbmk2( aArgs, /* @ */ lPause ) cOpt_Dyn := "-shared -o {OD} {LO} {FD} {DL} {LS}" cBin_Link := cBin_CompC cOpt_Link := "{LO} {LA} {LS} {FL} {DL}" - bBlk_ImpLib := {| cSourceDLL, cTargetLib | hb_FCopy( cSourceDLL, cTargetLib ) != F_ERROR } + bBlk_ImpLib := {| cSourceDLL, cTargetLib, cFlags | win_implib_command_gcc( hbmk, hbmk[ _HBMK_cCCPREFIX ] + "dlltool" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] + " {FI} -d {ID} -l {OL}", nCmd_Esc, cSourceDLL, cTargetLib, cFlags ) } cLibPathPrefix := "-L" cLibPathSep := " " cLibLibExt := ".a" @@ -7854,6 +7854,67 @@ STATIC FUNCTION win_implib_command( hbmk, cCommand, nCmd_Esc, cSourceDLL, cTarge RETURN hb_processRun( cCommand ) == 0 +#define _COFF_LIB_SIGNATURE "!" + +STATIC FUNCTION IsCOFFLib( cFileName ) + LOCAL fhnd := FOpen( cFileName, FO_READ ) + LOCAL cBuffer + + IF fhnd != F_ERROR + cBuffer := Space( Len( _COFF_LIB_SIGNATURE ) ) + FRead( fhnd, @cBuffer, Len( cBuffer ) ) + FClose( fhnd ) + IF cBuffer == _COFF_LIB_SIGNATURE + RETURN .T. + ENDIF + ENDIF + + RETURN .F. + +STATIC FUNCTION win_implib_command_gcc( hbmk, cCommand, nCmd_Esc, cSourceDLL, cTargetLib, cFlags ) + LOCAL tmp + + /* NOTE: There is a big problem with mingw/cygwin 'ld' linker: + It cannot properly link stdcall decorated (_sym@nn) function names + directly with .dlls, since in .dlls the decoration is stripped from + the exported symbols. So, it _requires_ a .def file or a COFF import .lib + which have the the decorated version of the symbols. Such .def/.lib + file cannot be automatically generated from the .dll, as the + decoration needs to be rebuilt based on function parameters. + Not even 'ld' option '--enable-stdcall-fixup' ("Link _sym to _sym@nn without warnings") + option will help the case, since we'd need a "Link _sym@nn to _sym" + option. For some reason and despite the frequent complaints, gcc + developers failed to add such option since year ~2000. + To circumvent that and make it possible for Harbour users to + effortlessly generate implibs from .dlls, we cannot do more than + rely on .dll distributors to provide .def or COFF import .libs + and make use of these automatically if they are available. + Hopefully one day gcc will introduce a feature to make such tricks + unnecessary and make it possible to create proper implibs out of + ordinary .dlls, like with every other compiler. + [vszakats] */ + + /* Try to find COFF .lib with the same name */ + IF hb_FileExists( tmp := FN_ExtSet( cSourceDLL, ".lib" ) ) + IF IsCOFFLib( tmp ) + IF ! hbmk[ _HBMK_lQuiet ] + hbmk_OutStd( hbmk, I_( "Found COFF .lib with the same name, falling back to using it instead of the .dll." ) ) + ENDIF + RETURN hb_FCopy( tmp, cTargetLib ) != F_ERROR + ENDIF + ENDIF + + /* Try to find .def file with the same name */ + IF hb_FileExists( tmp := FN_ExtSet( cSourceDLL, ".def" ) ) + IF ! hbmk[ _HBMK_lQuiet ] + hbmk_OutStd( hbmk, I_( "Found .def file with the same name, falling back to using it instead of the .dll." ) ) + ENDIF + RETURN win_implib_command( hbmk, cCommand, nCmd_Esc, tmp, cTargetLib, cFlags ) + ENDIF + + /* Use .dll directly if all other attempts failed */ + RETURN hb_FCopy( cSourceDLL, cTargetLib ) != F_ERROR + STATIC FUNCTION win_implib_command_msvc( hbmk, cCommand, nCmd_Esc, cSourceDLL, cTargetLib, cFlags ) LOCAL lSuccess := .F.