Bill Allombert on Tue, 22 Dec 2009 23:17:00 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: A patch for native PARI/GP build on Windows (Mingw+Msys)


On Tue, Dec 22, 2009 at 06:05:15PM +0200, Vasili Burdo wrote:
> Hi, Bill!
>
> Sorry for late reply. I had VERY busy week start.

No problem. I just commited a slightly reduced version of your patch
which work on my cross-compiler+wine set up. Please check for any problem
on the real thing and please repost the part of the patches I did not apply 
but you feel are still needed.

>>> Index: config/get_dlld
>>> ===================================================================
>>> --- config/get_dlld	(revision 12034)
>>> +++ config/get_dlld	(working copy)
>>> @@ -27,6 +27,7 @@
>>>  # On FreeBSD 2.2.5 (Y. Uchikawa) and Cygwin, this does not work.
>>>  case "$osname" in    freebsd|cygwin) 
>>> DL_DFLT_NAME="\\\"\$(LIBPARI_DYN)\\\"" ;;
>>> +  mingw) DL_DFLT_NAME="\\\"\$(LIBPARI_SO)\\\"" ;;
>>>    *) DL_DFLT_NAME=NULL ;;
>>>  esac
>>
>> Do you know why DL_DFLT_NAME=$(LIBPARI_DYN) does not work here ? It did not
>> work with wine and this is strange because LIBPARI_SO is a symlink to
>> LIBPARI_DYN.
> The problem is that Windows does not support symlinks. As result, we  
> should maintain two copies: libpari.dll (because gp-dyn links to it) and  
> libpari-2.4.dll (for install0).
> I think keeping two copies is redundant.

You did not quite answer my question. Since LIBPARI_SO is a symlink for
LIBPARI_DYN, I would expect DL_DFLT_NAME="\\\"\$(LIBPARI_DYN)\\\"" to
work better than DL_DFLT_NAME="\\\"\$(LIBPARI_SO)\\\"", but it is not
the case. Do you know why ?

>>> @@ -84,6 +85,7 @@
>>>    case "$osname" in
>>>      os2) DLLDFLAGS="$CFLAGS -Zdll" ;; # assume DLLD = gcc
>>>      cygwin) DLLDFLAGS="-Wl,--out-implib=\$(LIBPARI_SO)\$(_A),--export-all-symbols";;
>>> +	mingw) DLLDFLAGS="-Wl,--out-implib=\$(LIBPARI_SO)\$(_A)";;
>>>    esac
>>>    if test -n "$DLLDisGCC"; then
>>>      case "$arch" in
>>
>> Do you know why this is different from cygwin ?
> IMHO --export-all-symbols is overkill. It exports all public symbols  
> including symbols from static libgmp and gcc runtime. I think it's  
> redundant.
> A better way is to export only public symbols from libpari object files.
> I implemented makefile rule (see Makefile.SH diff) which generates  
> $(EXPORT_FILE) for Windows DLL. I think this rule can be used for cygwin  
> as well.

I agree with you.

>>> Index: config/Makefile.SH
>>> ===================================================================
>>> --- config/Makefile.SH  (revision 12034)
>>> +++ config/Makefile.SH  (working copy)
>>> @@ -48,6 +48,10 @@
>>>         export_file=pari.def; export_create="emxexp -u"
>>>         # Actually, the build will fail until the switch to -Zomf
>>>         dlld_ignore=- ;;
>>> +  mingw)
>>> +    CFLAGS="$CFLAGS -fno-omit-frame-pointer"
>>> +    export_file='$(LIBPARI).def'
>>> +    ;;
>>>  esac
>>
>> What is the purpose of 'CFLAGS="$CFLAGS -fno-omit-frame-pointer"' ?
> -fomit-frame-pointer ruins setjmp-based error handling - GP produces a  
> lot of "Segfault" error messages. I dont understand why it happens, but  
> -fno-omit-frame-pointer fixes it.
> Probably, there is better place for this option, but I didnt find it yet.

Strange, I did not see any problem with wine.

>>> Index: src/systems/mingw/mingw.c
>>> ===================================================================
>>> --- src/systems/mingw/mingw.c	(revision 0)
>>> +++ src/systems/mingw/mingw.c	(revision 0)
>>> @@ -0,0 +1,93 @@
>>> +#include <windows.h>
>>> +#include <stdio.h>
>>> +
>>> +const char* +win32_GPDATADIR()
>>> +{
>>> +    static char datadir[1024] = {0};
>>> +    if( 0 == *datadir ) {
>>> +        char* slash;
>>> +        GetModuleFileNameA(0, datadir, sizeof(datadir) );
>>> +        slash = strrchr(datadir, '\\');
>>> +        if( slash ) *(slash+1) = 0;
>>> +        //while( (slash = strchr(datadir, '\\')) )
>>> +        //    *slash = '/';
>>> +        strcat(datadir, "gp-data");
>>> +    }
>>> +    return datadir;
>>> +}
>>
>> I do not understand what this is doing. Cannot you do that in Configure
>> instead ?
> It generates default GPDATADIR based on location of executable module.
> Let's have gp.exe at "C:\Program Files\GP\gp.exe". Then, this function  
> will return GPDATADIR as "C:\Program Files\GP\gp-data"
>
> The problem is that fixed path "/usr/local/share/pari" does not make any  
> sense on Windows. I'd like to keep data along with executable module, so  
> I can put it on memory stick and use it everywhere without extra  
> reconfiguration.
>
> On Windows standard location for data files is something like
> "C:\Documents and Settings\(User Name|All Users)\Application  
> Data\(Software Name)" and it may change depend on location where Windows  
> is installed.
> So, I believe my approach is correct, but we should negotiate correct  
> location of GP data dir.

I agree with your approach. I suggest to do things a bit differently:
We define a special value DYNDATADIR for GPDATADIR (say DYNDATADIR="" ) and
we test if GPDATADIR is equal to DYNDATADIR, and in that case we set
datadir to win32_GPDATADIR instead of GPDATADIR. 
We change Configure to set GPDATADIR to DYNDATADIR by default.

Cheers,
Bill.