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.
This commit is contained in:
Viktor Szakats
2010-05-08 09:54:50 +00:00
parent d1fa4c942b
commit 5e3f92ac36
3 changed files with 101 additions and 8 deletions

View File

@@ -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,

View File

@@ -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 */

View File

@@ -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 "!<arch>"
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.