From: Michael McMaster Date: Thu, 18 Dec 2014 12:17:32 +0000 (+1000) Subject: Suport for cross-compiling for Windows using mingw X-Git-Tag: 1.0.4^0 X-Git-Url: http://git.codesrc.com/gitweb.cgi?a=commitdiff_plain;ds=sidebyside;p=libzipper.git Suport for cross-compiling for Windows using mingw --- diff --git a/FileReader.cc b/FileReader.cc index 054c24e..0e9972e 100644 --- a/FileReader.cc +++ b/FileReader.cc @@ -27,6 +27,8 @@ #include #include +#include "config.h" + using namespace zipper; const timeval zipper::s_now = {0,0}; @@ -40,7 +42,7 @@ public: m_fd(-1), m_closeOnExit(true) { - m_fd = ::open(filename.c_str(), O_RDONLY); + m_fd = ::open(filename.c_str(), O_RDONLY | O_BINARY); if (m_fd < 0) { diff --git a/FileWriter.cc b/FileWriter.cc index 53e7de7..77ac13f 100644 --- a/FileWriter.cc +++ b/FileWriter.cc @@ -29,6 +29,8 @@ #include #include +#include "config.h" + using namespace zipper; class FileWriter::FileWriterImpl @@ -48,7 +50,7 @@ public: m_fd = ::open( filename.c_str(), - O_WRONLY | O_TRUNC | O_CREAT, + O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, createPermissions); if (m_fd < 0) diff --git a/Makefile.am b/Makefile.am index 1127b2f..10f3677 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with libzipper. If not, see . +AUTOMAKE_OPTIONS = subdir-objects + include doxygen.am dist_noinst_SCRIPTS = \ @@ -62,6 +64,21 @@ libzipper_la_SOURCES += \ port/strerror_posix.cc endif +if !HAVE_PREAD +libzipper_la_SOURCES += \ + port/pread.c +endif + +if !HAVE_PWRITE +libzipper_la_SOURCES += \ + port/pwrite.c +endif + +if !HAVE_UTIMES +libzipper_la_SOURCES += \ + port/utimes.c +endif + # Public API headers go here, for installation to /usr/include include_HEADERS = zipper.hh diff --git a/NEWS b/NEWS index 0c5196c..957ea04 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +2014-12-18 Version 1.0.4 + - mingw support for cross-compiling for a Windows target. + 2011-10-05 Version 1.0.3 - Added Android NDK support diff --git a/VERSION b/VERSION index 21e8796..ee90284 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.3 +1.0.4 diff --git a/config.h b/config.h new file mode 100644 index 0000000..a1bffb2 --- /dev/null +++ b/config.h @@ -0,0 +1,61 @@ +// Copyright (C) 2014 Michael McMaster +// +// This file is part of libzipper. +// +// libzipper is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// libzipper is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with libzipper. If not, see . + +#ifndef zipper_config_h +#define zipper_config_h + +#include "autoconfig.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_PREAD +// Use port/pread.c +extern ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); +#endif +#ifndef HAVE_PWRITE +// Use port/pwrite.c +extern ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); +#endif + +#ifndef HAVE_UTIMES +extern int utimes(const char *filename, const struct timeval times[2]); +#endif + +// Thread un-safe alternative +#ifndef HAVE_LOCALTIME_R +#define localtime_r(timep, result) localtime( (timep) ) +#endif + +#ifdef _WIN32 + #define MKDIR(file,mode) mkdir(file) +#else + #define MKDIR(file,mode) mkdir(file,mode) + + // no automagic CR/LF conversion undr mingw + #define O_BINARY 0 +#endif + +#ifdef __cplusplus +// extern "C" +} +#endif + +#endif diff --git a/configure.ac b/configure.ac index 1ed643a..716db02 100644 --- a/configure.ac +++ b/configure.ac @@ -33,6 +33,11 @@ AM_PROG_LIBTOOL AC_FUNC_STRERROR_R AM_CONDITIONAL(HAVE_GNU_STRERROR,[test x$ac_cv_func_strerror_r_char_p = xyes]) +AC_CHECK_FUNCS([pread pwrite utimes localtime_r]) +AM_CONDITIONAL(HAVE_PREAD,[test x$ac_cv_func_pread = xyes]) +AM_CONDITIONAL(HAVE_PWRITE,[test x$ac_cv_func_pwrite = xyes]) +AM_CONDITIONAL(HAVE_UTIMES,[test x$ac_cv_func_utimes = xyes]) + DX_DOXYGEN_FEATURE([ON]) DX_HTML_FEATURE([ON]) DX_CHM_FEATURE(OFF) diff --git a/port/pread.c b/port/pread.c new file mode 100644 index 0000000..91fa344 --- /dev/null +++ b/port/pread.c @@ -0,0 +1,65 @@ +/* replacement pread function + Copyright (C) 2009-2014 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#define __libc_lseek(f,o,w) lseek (f, o, w) +#define __set_errno(Val) errno = (Val) +#define __libc_read(f,b,n) read (f, b, n) + +/* pread substitute for systems that the function, such as mingw32 and BeOS. */ +/* The following is identical to the function from glibc's + sysdeps/posix/pread.c */ + +/* Note: This implementation of pread is not multithread-safe. */ + +ssize_t +pread (int fd, void *buf, size_t nbyte, off_t offset) +{ + /* Since we must not change the file pointer preserve the value so that + we can restore it later. */ + int save_errno; + ssize_t result; + off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR); + if (old_offset == (off_t) -1) + return -1; + + /* Set to wanted position. */ + if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1) + return -1; + + /* Write out the data. */ + result = __libc_read (fd, buf, nbyte); + + /* Now we have to restore the position. If this fails we have to + return this as an error. But if the writing also failed we + return this error. */ + save_errno = errno; + if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1) + { + if (result == -1) + __set_errno (save_errno); + return -1; + } + __set_errno (save_errno); + + return result; +} diff --git a/port/pwrite.c b/port/pwrite.c new file mode 100644 index 0000000..a759204 --- /dev/null +++ b/port/pwrite.c @@ -0,0 +1,64 @@ +/* Write block to given position in file without changing file pointer. + POSIX version. + Copyright (C) 1997-1999, 2002, 2011-2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +#include + +#define __libc_lseek(f,o,w) lseek (f, o, w) +#define __set_errno(Val) errno = (Val) +#define __libc_write(f,b,n) write (f, b, n) + +/* Note: This implementation of pwrite is not multithread-safe. */ + +ssize_t +pwrite (int fd, const void *buf, size_t nbyte, off_t offset) +{ + /* Since we must not change the file pointer preserve the value so that + we can restore it later. */ + int save_errno; + ssize_t result; + off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR); + if (old_offset == (off_t) -1) + return -1; + + /* Set to wanted position. */ + if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1) + return -1; + + /* Write out the data. */ + result = __libc_write (fd, buf, nbyte); + + /* Now we have to restore the position. If this fails we have to + return this as an error. But if the writing also failed we + return this error. */ + save_errno = errno; + if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1) + { + if (result == -1) + __set_errno (save_errno); + return -1; + } + __set_errno (save_errno); + + return result; +} diff --git a/port/utimes.c b/port/utimes.c new file mode 100644 index 0000000..26cd01c --- /dev/null +++ b/port/utimes.c @@ -0,0 +1,30 @@ +// Copyright (C) 2014 Michael McMaster +// +// This file is part of libzipper. +// +// libzipper is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// libzipper is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with libzipper. If not, see . + +#include +#include +#include + +// Replacement function using the older low-resolution utime function +int utimes(const char *filename, const struct timeval times[2]) +{ + struct utimbuf buf; + buf.actime = times[0].tv_sec; + buf.modtime = times[1].tv_sec; + return utime(filename, &buf); +} + diff --git a/zip.cc b/zip.cc index 1655072..5ff84c6 100644 --- a/zip.cc +++ b/zip.cc @@ -28,6 +28,8 @@ #include #include +#include "config.h" + using namespace zipper; namespace diff --git a/zipper.cc b/zipper.cc index 52c6c1c..22e9f36 100644 --- a/zipper.cc +++ b/zipper.cc @@ -27,6 +27,8 @@ #include #include +#include "config.h" + using namespace zipper; static std::string argv0; @@ -136,7 +138,7 @@ command_extract(const std::deque& options) ++it) { builtPath << *it; - int result(mkdir(builtPath.str().c_str(), 0775)); + int result(MKDIR(builtPath.str().c_str(), 0775)); if (result != 0 && errno != EEXIST) { std::string errMsg(zipper::strerror(errno));