| Vasili Burdo on Wed, 23 Dec 2009 17:22:50 +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) |
Please check for any problem on the real thing
Everything is OK. make test-all passed
and please repost the part of the patches I did not apply but you feel are still needed.
See my current patch in attachment. What's done: - implemented "~" handling in paths - see pari_get_homedir() in es.c - implemented unzipping from .zip archives I mentioned in previous post. See pari_get_infile(). If this function sees ".zip/" substring in file name, it tries to pipe it through "unzip -p".As result, it's possible it set GPDATADIR to something like "/path/path/gpdata.zip". - removed "-wb" option from diff command in dotest. Instead, "sed -e 's/\r//'" used as you suggested. The same way dotest should be fixed in gp2c sources
- reimplemented -fno-omit-frame-pointer hack. See file config/get_cc- added mingw support to config/get_modld - it's neccessary for gp2c interoperability
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).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.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 ?
In my setup, LIBPARI_DYN == "libpari-gmp-2.4.dll" and LIBPARI_SO == "libpari.dll"Because Windows does not support symlinks, we have two copies of the same file, but under different names.
"libpari.dll" (i.e LIBPARI_SO) is linked to gp-dyn.exe and thus it must be present. "libpari-gmp-2.4.dll" (i.e. DL_DFLT_NAME, i.e LIBPARI_DYN in your setup) used as default library name for "install" function.
I dont like to keep another copy of the same file (remember, Windows does not support symlinks) just because it's named differently somewhere. So, I use LIBPARI_SO (i.e "libpari.dll") for DL_DFLT_NAME.
-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.What is the purpose of 'CFLAGS="$CFLAGS -fno-omit-frame-pointer"' ?Probably, there is better place for this option, but I didnt find it yet.Strange, I did not see any problem with wine.
It's because you're running on Unix :-)Probably, Windows port of GCC has some subtle differences which cause this bug. I saw it on all GCC versions starting from 4.0.0
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 setdatadir to win32_GPDATADIR instead of GPDATADIR. We change Configure to set GPDATADIR to DYNDATADIR by default.
I don't quite understand how it will work, so please, do it yourself.
Index: config/get_cc
===================================================================
--- config/get_cc (revision 12049)
+++ config/get_cc (working copy)
@@ -17,6 +17,7 @@
case "$osname-$arch" in
os2-*) exe_suff=.exe; extraflag="-Zexe";;
cygwin*) exe_suff=.exe; extraflag="";;
+ mingw*) exe_suff=.exe; extraflag="";;
# On Darwin, by default, the full library search path is searched for a .dylib
# before a .a can be considered, preventing users to install their libraries
# in a simple way (e.g. the readline / Editline conflict). Override this.
@@ -147,7 +148,9 @@
# omit-frame-pointer incompatible with -pg
PRFFLAGS="-pg $OPTFLAGS"
case "$optimization" in
- full) OPTFLAGS="$OPTFLAGS -fomit-frame-pointer";;
+ full) if "$osname" ne "mingw"; then
+ OPTFLAGS="$OPTFLAGS -fomit-frame-pointer"
+ fi;;
esac
else
DBGFLAGS=${DBGFLAGS:-'-g'}
Index: config/get_graphic_lib
===================================================================
--- config/get_graphic_lib (revision 12049)
+++ config/get_graphic_lib (working copy)
@@ -58,4 +58,9 @@
esac
case $which_graphic_lib in auto) which_graphic_lib=none;; esac
+if test "$which_graphic_lib" == none; then
+ if test "$osname" == "mingw"; then
+ which_graphic_lib=win32
+ fi
+fi
echo "Hi-Res Graphics: $which_graphic_lib"
Index: config/get_modld
===================================================================
--- config/get_modld (revision 12049)
+++ config/get_modld (working copy)
@@ -6,6 +6,10 @@
if test "$static" = n; then LIBS="$LIBS $LDDYN"; fi
case $osname in
cygwin) EXTRAMODLDFLAGS="-L$libdir -lpari.dll";;
+mingw) CC=`basename $CC`
+ DLLD=`basename $DLLD`
+ EXTRAMODLDFLAGS="-lpari"
+ ;;
*) EXTRAMODLDFLAGS=`eval echo $EXTRADLLDFLAGS`;;
esac;
LIBS=$__LIBS
@@ -17,7 +21,8 @@
*) MODLD="$DLLD";
MODLDFLAGS=`echo "$DLLDFLAGS" | \
sed -e 's/,*-[^ \t-]*[ \t,=]*\\$(LIBPARI_SONAME)//' \
- -e 's/--out-implib=\$(LIBPARI_SO)\$(_A),\?//'`;;
+ -e 's/--out-implib=\$(LIBPARI_SO)\$(_A),\?//' \
+ -e 's/-Wl,[ \t]*$//'`;;
esac;
modules_build=`echo "$CC -c -o %s.o $CFLAGS $DLCFLAGS -I\"$includedir\" %s.c \
Index: config/paricfg.h.SH
===================================================================
--- config/paricfg.h.SH (revision 12049)
+++ config/paricfg.h.SH (working copy)
@@ -73,13 +73,23 @@
fi
fi
+if test -n "$unzip"; then
+ cat >> $file << EOT
+#define UNZIP "$unzip -p"
+EOT
+fi
+
if test "$osname" = "mingw"; then
cat >> $file << EOT
#undef UNIX
#define GNUZCAT
-#undef ZCAT
+#undef ZCAT
#define ZCAT "gzip.exe -dc"
+#undef UNZIP
+#define UNZIP "unzip.exe -p"
+#undef GPDATADIR
+#define GPDATADIR win32_GPDATADIR()
EOT
fi
Index: Configure
===================================================================
--- Configure (revision 12049)
+++ Configure (working copy)
@@ -36,7 +36,7 @@
. ./get_PATH
# We might need the following :
echo Looking for some tools first ...
-list='ld zcat gzip ranlib perl'
+list='ld zcat gzip unzip ranlib perl'
pathspace=`echo $PATH | sed -e "s/$dir_sep/ /g" | sed -e 's,\\\\,/,g'`
for file in $list; do
Index: src/language/es.c
===================================================================
--- src/language/es.c (revision 12049)
+++ src/language/es.c (working copy)
@@ -3348,6 +3348,31 @@
if (!dir) pari_warn(warner,"can't expand ~%s", user? user: "");
return dir;
}
+#elif defined(_WIN32)
+char *
+pari_get_homedir(const char *user)
+{
+ char *drv, *pth;
+
+ if (user && *user) {
+ pari_warn(warner,"can't expand ~%s", user ? user: "");
+ return NULL;
+ }
+
+ if (homedir)
+ return homedir;
+
+ pth = os_getenv("HOME");
+ if (pth) return pth;
+
+ if ((drv = os_getenv("HOMEDRIVE"))
+ && (pth = os_getenv("HOMEPATH")))
+ { /* looks like WinNT */
+ char *homedir = (char*)pari_malloc(strlen(pth) + strlen(drv) + 1);
+ sprintf(homedir, "%s%s",drv,pth);
+ }
+ return homedir;
+}
#else
char *
pari_get_homedir(const char *user) { return NULL; }
@@ -3588,6 +3613,21 @@
return try_pipe(cmd, mf_IN);
}
#endif
+#ifdef UNZIP
+ if ((end = strstr(name, ".zip/"))) {
+ char *cmd;
+
+ end = end + 4;
+ cmd = stackmalloc(strlen(name) + strlen(UNZIP) + 32);
+ strcpy(cmd, UNZIP);
+ strcat(cmd, " ");
+ strncat(cmd, name, (end-name));
+ strcat(cmd, " ");
+ strcat(cmd, end+1);
+ return try_pipe(cmd, mf_IN);
+ }
+#endif
+
return newfile(file, name, mf_IN);
}
@@ -3600,7 +3640,8 @@
FILE *f = fopen(s, "r");
pariFILE *pf;
- if (f) return pari_get_infile(s, f);
+ if (f || strstr(s, ".zip/"))
+ return pari_get_infile(s, f);
l = strlen(s);
name = stackmalloc(l + 3 + 1);
Index: src/systems/mingw/mingw.c
===================================================================
--- src/systems/mingw/mingw.c (revision 12049)
+++ src/systems/mingw/mingw.c (working copy)
@@ -17,6 +17,8 @@
#include <windows.h>
#include <stdio.h>
+#include <io.h>
+#include "paricfg.h"
#include "mingw.h"
static WORD
@@ -93,3 +95,24 @@
return 0;
return (sbi.srWindow.Bottom - sbi.srWindow.Top);
}
+
+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;
+#ifdef UNZIP
+ strcat(datadir, "gp.zip");
+ if( access(datadir,04) ) {
+ *(slash+1) = 0;
+ strcat(datadir, "gp-data");
+ }
+#else
+ strcat(datadir, "gp-data");
+#endif
+ }
+ return datadir;
+}
Index: src/test/dotest
===================================================================
--- src/test/dotest (revision 12049)
+++ src/test/dotest (working copy)
@@ -73,7 +73,7 @@
*) file_diff=$testname-$suf.dif
gp=$execdir/gp-$suf;;
esac
- (cat $file_in; echo 'print("Total time spent: ",gettime);') | $RUNTEST $gp -q --test > $file_test 2>&1
+ (cat $file_in; echo 'print("Total time spent: ",gettime);') | $RUNTEST $gp -q --test | sed -e 's/\r//g' > $file_test 2>&1
diff -c $file_out $file_test > $file_diff
pat=`grep "^[-+!] " $file_diff | grep -v "Total time"`
time=`${tail}1 $file_test | sed -n 's,.*Total time spent: \(.*\),\1,p'`