diff --git a/mingw-w64-bison/002-add-relocation-support.patch b/mingw-w64-bison/002-add-relocation-support.patch
new file mode 100644
index 0000000000..e07b157f7f
--- /dev/null
+++ b/mingw-w64-bison/002-add-relocation-support.patch
@@ -0,0 +1,359 @@
+diff -urN bison-3.0.2.orig/src/files.c bison-3.0.2/src/files.c
+--- bison-3.0.2.orig/src/files.c 2014-08-03 21:05:59.361540700 +0100
++++ bison-3.0.2/src/files.c 2014-08-03 21:07:19.351115800 +0100
+@@ -18,6 +18,7 @@
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
++
+ #include
+ #include "system.h"
+
+@@ -34,6 +35,22 @@
+ #include "getargs.h"
+ #include "gram.h"
+
++/* If you don't define this, then get_executable_path()
++ can only use argv[0] which will often not work well */
++#define IMPLEMENT_SYS_GET_EXECUTABLE_PATH
++
++#if defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH)
++#if defined(__linux__) || defined(__CYGWIN__) || defined(__MSYS__)
++/* Nothing needed, unistd.h is enough. */
++#elif defined(__APPLE__)
++#include
++#elif defined(_WIN32)
++#define WIN32_LEAN_AND_MEAN
++#include
++#include
++#endif
++#endif /* defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH) */
++
+ /* Initializing some values below (such SPEC_NAME_PREFIX to 'yy') is
+ tempting, but don't do that: for the time being our handling of the
+ %directive vs --option leaves precedence to the options by deciding
+@@ -425,3 +442,277 @@
+ }
+ free (generated_files);
+ }
++
++char *
++malloc_copy_string (char const * original)
++{
++ char * result = (char *) malloc (sizeof(char*) * strlen(original)+1);
++ if (result != NULL)
++ {
++ strcpy (result, original);
++ }
++ return result;
++}
++
++static char *
++sanitise_path(char * path)
++{
++ size_t path_size = strlen(path);
++
++ /* Replace any '\' with '/' */
++ char * path_p = path;
++ while ((path_p = strchr(path_p, '\\')) != NULL)
++ {
++ *path_p = '/';
++ }
++ /* Replace any '//' with '/' */
++ path_p = path;
++ while ((path_p = strstr(path_p, "//")) != NULL)
++ {
++ memmove(path_p, path_p + 1, path_size--);
++ }
++ return path;
++}
++
++void
++simplify_path (char * path)
++{
++ ssize_t n_toks = 1; /* in-case we need an empty initial token. */
++ ssize_t i, j;
++ size_t tok_size;
++ size_t in_size = strlen (path);
++ int it_ended_with_a_slash = (path[in_size - 1] == '/') ? 1 : 0;
++ char * result = path;
++ char * result_p = sanitise_path(result);
++
++ do
++ {
++ ++n_toks;
++ ++result_p;
++ } while ((result_p = strchr(result_p, '/')) != NULL);
++
++ result_p = result;
++ char const ** toks = (char const **) alloca (sizeof(char const*) * n_toks);
++ n_toks = 0;
++ do
++ {
++ if (result_p > result)
++ {
++ *result_p++ = '\0';
++ }
++ else if (*result_p == '/')
++ {
++ /* A leading / creates an empty initial token. */
++ toks[n_toks++] = result_p;
++ *result_p++ = '\0';
++ }
++ toks[n_toks++] = result_p;
++ } while ((result_p = strchr(result_p, '/')) != NULL);
++
++ /* Remove all non-leading '.' and any '..' we can match
++ with an earlier forward path (i.e. neither '.' nor '..') */
++ for (i = 1; i < n_toks; ++i)
++ {
++ int removals[2] = { -1, -1 };
++ if ( strcmp (toks[i], "." ) == 0)
++ {
++ removals[0] = i;
++ }
++ else if ( strcmp (toks[i], ".." ) == 0)
++ {
++ /* Search backwards for a forward path to collapse.
++ If none are found then the .. also stays. */
++ for (j = i - 1; j > -1; --j)
++ {
++ if ( strcmp (toks[j], "." )
++ && strcmp (toks[j], ".." ) )
++ {
++ removals[0] = j;
++ removals[1] = i;
++ break;
++ }
++ }
++ }
++ for (j = 0; j < 2; ++j)
++ {
++ if (removals[j] >= 0) /* Can become -2 */
++ {
++ --n_toks;
++ memmove (&toks[removals[j]], &toks[removals[j]+1], (n_toks - removals[j])*sizeof(char*));
++ --i;
++ if (!j)
++ {
++ --removals[1];
++ }
++ }
++ }
++ }
++ result_p = result;
++ for (i = 0; i < n_toks; ++i)
++ {
++ tok_size = strlen(toks[i]);
++ memcpy (result_p, toks[i], tok_size);
++ result_p += tok_size;
++ if ((!i || tok_size) && ((i < n_toks - 1) || it_ended_with_a_slash == 1))
++ {
++ *result_p = '/';
++ ++result_p;
++ }
++ }
++ *result_p = '\0';
++}
++
++char *
++get_relative_path (char const * from, char const * to)
++{
++ size_t from_size = strlen (from);
++ size_t to_size = strlen (to);
++ size_t max_size = (from_size + to_size) * 2 + 4;
++ char * common_part = (char *) alloca (max_size);
++ char * result = (char *) alloca (max_size);
++ size_t count;
++
++ /* If either alloca failed, no from was given, from is not absolute
++ or either to or from contains '.' then return a copy of to; it's
++ the best we can do in this instance (though we could call a path
++ normalization function for some of these conditions).
++ */
++ if (common_part == NULL
++ || result == NULL
++ || from == NULL
++ || from[0] != '/'
++ || strchr(to, '.') != NULL
++ || strchr(from, '.') != NULL)
++ {
++ return malloc_copy_string (to);
++ }
++
++ printf ("source : %s\n", from);
++ printf ("target : %s\n", to);
++
++ result[0] = '\0';
++
++ size_t match_size_dirsep = 0; /* The match size up to the last /. Always wind back to this - 1 */
++ size_t match_size = 0; /* The running (and final) match size. */
++ size_t largest_size = (from_size > to_size) ? from_size : to_size;
++ int to_final_is_slash = (to[to_size-1] == '/') ? 1 : 0;
++ char from_c;
++ char to_c;
++ for (match_size = 0; match_size < largest_size; ++match_size)
++ {
++ /* To simplify the logic, always pretend the strings end with '/' */
++ from_c = (match_size < from_size) ? from[match_size] : '/';
++ to_c = (match_size < to_size) ? to[match_size] : '/';
++
++ if (from_c != to_c)
++ {
++ if (from_c != '\0' || to_c != '\0')
++ {
++ match_size = match_size_dirsep;
++ }
++ break;
++ }
++ else if (from_c == '/')
++ {
++ match_size_dirsep = match_size;
++ }
++ }
++ strncpy (common_part, from, match_size);
++ common_part[match_size] = '\0';
++ from += match_size;
++ to += match_size;
++ size_t ndotdots = 0;
++ char const* from_last = from + strlen(from) - 1;
++ while ((from = strchr(from, '/')) && from != from_last)
++ {
++ ++ndotdots;
++ ++from;
++ }
++ for (count = 0; count < ndotdots; ++count)
++ {
++ strcat(result, "../");
++ }
++ if (strlen(to) > 0)
++ {
++ strcat(result, to+1);
++ }
++ /* Make sure that if to ends with '/' result does the same, and
++ vice-versa. */
++ size_t size_result = strlen(result);
++ if ((to_final_is_slash == 1)
++ && (!size_result || result[size_result-1] != '/'))
++ {
++ strcat (result, "/");
++ }
++ else if (!to_final_is_slash
++ && size_result && result[size_result-1] == '/')
++ {
++ result[size_result-1] = '\0';
++ }
++
++ return malloc_copy_string (result);
++}
++
++int
++get_executable_path(char const * argv0, char * result, ssize_t max_size)
++{
++ char * system_result = (char *) alloca (max_size);
++ ssize_t system_result_size = -1;
++ ssize_t result_size = -1;
++
++ if (system_result != NULL)
++ {
++#if defined(IMPLEMENT_SYS_GET_EXECUTABLE_PATH)
++#if defined(__linux__) || defined(__CYGWIN__) || defined(__MSYS__)
++ system_result_size = readlink("/proc/self/exe", system_result, max_size);
++#elif defined(__APPLE__)
++ uint32_t bufsize = (uint32_t)max_size;
++ if (_NSGetExecutablePath(system_result, &bufsize) == 0)
++ {
++ system_result_size = (ssize_t)bufsize;
++ }
++#elif defined(_WIN32)
++ unsigned long bufsize = (unsigned long)max_size;
++ system_result_size = GetModuleFileNameA(NULL, system_result, bufsize);
++ if (system_result_size == 0 || system_result_size == bufsize)
++ {
++ /* Error, possibly not enough space. */
++ system_result_size = -1;
++ }
++ else
++ {
++ /* Early conversion to unix slashes instead of more changes
++ everywhere else .. */
++ char * winslash;
++ system_result[system_result_size] = '\0';
++ while ((winslash = strchr (system_result, '\\')) != NULL)
++ {
++ *winslash = '/';
++ }
++ }
++#else
++#warning "Don't know how to get executable path on this system"
++#endif
++#endif
++ }
++ /* Use argv0 as a default in-case of failure */
++ if (system_result_size != -1)
++ {
++ strncpy (result, system_result, system_result_size);
++ result[system_result_size] = '\0';
++ }
++ else
++ {
++ if (argv0 != NULL)
++ {
++ strncpy (result, argv0, max_size);
++ result[max_size-1] = '\0';
++ }
++ else
++ {
++ result[0] = '\0';
++ }
++ }
++ result_size = strlen (result);
++ return result_size;
++}
+diff -urN bison-3.0.2.orig/src/files.h bison-3.0.2/src/files.h
+--- bison-3.0.2.orig/src/files.h 2014-08-03 21:05:59.367541000 +0100
++++ bison-3.0.2/src/files.h 2014-08-03 21:06:17.520579300 +0100
+@@ -77,4 +77,20 @@
+ void xfclose (FILE *ptr);
+ FILE *xfdopen (int fd, char const *mode);
+
++/* These functions are used to support relocation. On MSYS2, the native
++ bison port needs this. */
++
++/* Returns the malloc'ed string. Caller should free using free(void*) */
++extern char * malloc_copy_string (char const * original);
++
++/* Uses a host OS specific function to determine the path of the executable,
++ if IMPLEMENT_SYS_GET_EXECUTABLE_PATH is defined, otherwise uses argv0. */
++extern int get_executable_path(char const * argv0, char * result, ssize_t max_size);
++
++/* Where possible, removes occourances of '.' and 'path/..' */
++extern void simplify_path (char * path);
++
++/* mallocs and returns the path to get from from to to. Caller should free using free(void*) */
++extern char * get_relative_path (char const * from, char const * to);
++
+ #endif /* !FILES_H_ */
+diff -urN bison-3.0.2.orig/src/output.c bison-3.0.2/src/output.c
+--- bison-3.0.2.orig/src/output.c 2014-08-03 21:05:59.363540800 +0100
++++ bison-3.0.2/src/output.c 2014-08-03 21:06:17.521579400 +0100
+@@ -716,5 +716,18 @@
+ pkgdatadir (void)
+ {
+ char const *cp = getenv ("BISON_PKGDATADIR");
+- return cp ? cp : PKGDATADIR;
++ if (cp)
++ return cp;
++
++ /* Relocation support. */
++ char exe_path[PATH_MAX];
++ get_executable_path (NULL, &exe_path[0], sizeof(exe_path)/sizeof(exe_path[0]));
++ if (strrchr (exe_path, '/') != NULL)
++ {
++ strrchr (exe_path, '/')[1] = '\0';
++ }
++ char * rel_to_datadir = get_relative_path (BINDIR, PKGDATADIR);
++ strcat (exe_path, rel_to_datadir);
++ simplify_path (&exe_path[0]);
++ return malloc_copy_string (exe_path);
+ }
diff --git a/mingw-w64-bison/PKGBUILD b/mingw-w64-bison/PKGBUILD
index 420423b1b4..65a5592ab9 100644
--- a/mingw-w64-bison/PKGBUILD
+++ b/mingw-w64-bison/PKGBUILD
@@ -1,4 +1,5 @@
# Maintainer: Alexey Pavlov
+# Contributor: Ray Donnelly
_realname=bison
pkgname="${MINGW_PACKAGE_PREFIX}-${_realname}"
@@ -9,33 +10,36 @@ arch=('any')
license=('GPL3')
url="http://www.gnu.org/software/bison/bison.html"
depends=("${MINGW_PACKAGE_PREFIX}-m4")
-source=(http://ftp.gnu.org/gnu/bison/${_realname}-${pkgver}.tar.xz{,.sig}
- 001-use-gnu_printf.patch)
+source=(http://ftp.gnu.org/gnu/bison/${_realname}-${pkgver}.tar.xz
+ 001-use-gnu_printf.patch
+ 002-add-relocation-support.patch)
md5sums=('146be9ff9fbd27497f0bf2286a5a2082'
- 'SKIP'
- '817bbd1f0de3d7f2ab1287b67b267895')
+ '817bbd1f0de3d7f2ab1287b67b267895'
+ '14236b43f975e1e51e054267304e34b1')
prepare() {
cd ${srcdir}/${_realname}-${pkgver}
patch -p1 -i ${srcdir}/001-use-gnu_printf.patch
-
+ patch -p1 -i ${srcdir}/002-add-relocation-support.patch
+
#autoreconf -vfi
}
build() {
cd ${srcdir}/${_realname}-${pkgver}
- ./configure \
- --prefix=${MINGW_PREFIX} \
- --build=${MINGW_CHOST} \
- --host=${MINGW_CHOST} \
- --target=${MINGW_CHOST}
+ M4=$(cygpath -wm ${MINGW_PREFIX})/bin/m4.exe \
+ ./configure \
+ --prefix=${MINGW_PREFIX} \
+ --build=${MINGW_CHOST} \
+ --host=${MINGW_CHOST} \
+ --target=${MINGW_CHOST}
make
}
check() {
cd ${srcdir}/${_realname}-${pkgver}
- make check
+ make -j1 check
}
package() {