From 478a80caa0cf072d73e268d0bea46428b328943c Mon Sep 17 00:00:00 2001 From: Date: Mon, 18 Feb 2013 10:56:53 +0000 Subject: [PATCH] Attempt to improve mingw-w64 support - Set -Isrc/windows for mingw - Check existence of sigaction, pread, and pwrite - Provide alternative implementation of pread and pwrite - Eliminate symlink code for OS_WINDOWS - Don't check /proc/self/fd if the OS isn't linux - Don't use MSVC specific declarations in port.h for mingw git-svn-id: https://google-glog.googlecode.com/svn/trunk@135 eb4d4688-79bd-11dd-afb4-1d65580434c0 --- Makefile.am | 6 ++- Makefile.in | 9 +++- configure | 71 ++++++++++++++++++++++++++++++- configure.ac | 18 +++++++- src/config.h.in | 9 ++++ src/googletest.h | 2 +- src/logging.cc | 39 ++++++++++++++++- src/signalhandler.cc | 9 ++++ src/utilities.cc | 3 ++ src/windows/config.h | 115 --------------------------------------------------- src/windows/port.h | 4 ++ 11 files changed, 162 insertions(+), 123 deletions(-) diff --git a/Makefile.am b/Makefile.am index cff3352..b598fa3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,7 +51,8 @@ lib_LTLIBRARIES = # The libraries libglog depends on. COMMON_LIBS = $(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS) # Compile switches for our unittest. -TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) $(AM_CXXFLAGS) +TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) \ + $(MINGW_CFLAGS) $(AM_CXXFLAGS) # Libraries for our unittest. TEST_LIBS = $(GTEST_LIBS) $(GMOCK_LIBS) $(GFLAGS_LIBS) @@ -195,7 +196,8 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) \ src/base/commandlineflags.h src/googletest.h nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS) -libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(AM_CXXFLAGS) -DNDEBUG +libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(MINGW_CFLAGS) \ + $(AM_CXXFLAGS) -DNDEBUG libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_LDFLAGS) libglog_la_LIBADD = $(COMMON_LIBS) diff --git a/Makefile.in b/Makefile.in index 17856a8..a4ee668 100644 --- a/Makefile.in +++ b/Makefile.in @@ -382,6 +382,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ +MINGW_CFLAGS = @MINGW_CFLAGS@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ @@ -499,7 +500,9 @@ lib_LTLIBRARIES = libglog.la # The libraries libglog depends on. COMMON_LIBS = $(PTHREAD_LIBS) $(GFLAGS_LIBS) $(UNWIND_LIBS) # Compile switches for our unittest. -TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) $(AM_CXXFLAGS) +TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS) $(GFLAGS_CFLAGS) \ + $(MINGW_CFLAGS) $(AM_CXXFLAGS) + # Libraries for our unittest. TEST_LIBS = $(GTEST_LIBS) $(GMOCK_LIBS) $(GFLAGS_LIBS) TESTS_ENVIRONMENT = @@ -606,7 +609,9 @@ libglog_la_SOURCES = $(gloginclude_HEADERS) \ src/base/commandlineflags.h src/googletest.h nodist_libglog_la_SOURCES = $(nodist_gloginclude_HEADERS) -libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(AM_CXXFLAGS) -DNDEBUG +libglog_la_CXXFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_CFLAGS) $(MINGW_CFLAGS) \ + $(AM_CXXFLAGS) -DNDEBUG + libglog_la_LDFLAGS = $(PTRHEAD_CFLAGS) $(GFLAGS_LDFLAGS) libglog_la_LIBADD = $(COMMON_LIBS) WINDOWS_PROJECTS = google-glog.sln vsprojects/libglog/libglog.vcproj \ diff --git a/configure b/configure index 6a77d35..6b74fce 100755 --- a/configure +++ b/configure @@ -619,6 +619,7 @@ LIBOBJS GMOCK_LIBS GTEST_LIBS GFLAGS_LIBS +MINGW_CFLAGS GMOCK_CFLAGS GTEST_CFLAGS GFLAGS_CFLAGS @@ -15706,6 +15707,18 @@ fi done +ac_fn_cxx_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" +if test "x$ac_cv_header_windows_h" = xyes; then : + ac_cv_have_windows_h=1 +else + ac_cv_have_windows_h=0 +fi + + +if test x"$ac_cv_have_windows_h" = x"1"; then + MINGW_CFLAGS=-Isrc/windows +fi + # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -15771,6 +15784,13 @@ $as_echo "#define HAVE_SIGALTSTACK 1" >>confdefs.h fi +ac_fn_cxx_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" +if test "x$ac_cv_func_sigaction" = xyes; then : + +$as_echo "#define HAVE_SIGACTION 1" >>confdefs.h + +fi + ac_fn_cxx_check_func "$LINENO" "dladdr" "ac_cv_func_dladdr" if test "x$ac_cv_func_dladdr" = xyes; then : @@ -15785,6 +15805,20 @@ $as_echo "#define HAVE_FCNTL 1" >>confdefs.h fi +ac_fn_cxx_check_func "$LINENO" "pread" "ac_cv_func_pread" +if test "x$ac_cv_func_pread" = xyes; then : + +$as_echo "#define HAVE_PREAD 1" >>confdefs.h + +fi + +ac_fn_cxx_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite" +if test "x$ac_cv_func_pwrite" = xyes; then : + +$as_echo "#define HAVE_PWRITE 1" >>confdefs.h + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__" >&5 @@ -16650,7 +16684,41 @@ $as_echo "no" >&6; } fi -if test x"$GTEST_CONFIG" = "xyes"; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgtest" >&5 +$as_echo_n "checking for main in -lgtest... " >&6; } +if ${ac_cv_lib_gtest_main+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgtest $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_gtest_main=yes +else + ac_cv_lib_gtest_main=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gtest_main" >&5 +$as_echo "$ac_cv_lib_gtest_main" >&6; } +if test "x$ac_cv_lib_gtest_main" = xyes; then : + have_gtest_lib="yes" +fi + +if test x"$GTEST_CONFIG" = "xyes" -a x"$have_gtest_lib" = "xyes"; then GTEST_CFLAGS=`gtest-config --cppflags --cxxflags` GTEST_LIBS=`gtest-config --ldflags --libs` @@ -17180,6 +17248,7 @@ _ACEOF + # Write generated configuration file ac_config_files="$ac_config_files Makefile src/glog/logging.h src/glog/raw_logging.h src/glog/vlog_is_on.h src/glog/stl_logging.h" diff --git a/configure.ac b/configure.ac index 8b458fa..a07c562 100644 --- a/configure.ac +++ b/configure.ac @@ -47,6 +47,11 @@ AC_CHECK_HEADERS(glob.h) # For backtrace with gcc. AC_CHECK_HEADERS(unwind.h) +AC_CHECK_HEADER(windows.h, ac_cv_have_windows_h=1, ac_cv_have_windows_h=0) +if test x"$ac_cv_have_windows_h" = x"1"; then + MINGW_CFLAGS=-Isrc/windows +fi + AC_CHECK_SIZEOF(void *) # These are the types I need. We look for them in either stdint.h, @@ -58,12 +63,21 @@ AC_CHECK_TYPE(__uint16, ac_cv_have___uint16=1, ac_cv_have___uint16=0) AC_CHECK_FUNC(sigaltstack, AC_DEFINE(HAVE_SIGALTSTACK, 1, [Define if you have the `sigaltstack' function])) +AC_CHECK_FUNC(sigaction, + AC_DEFINE(HAVE_SIGACTION, 1, + [Define if you have the 'sigaction' function])) AC_CHECK_FUNC(dladdr, AC_DEFINE(HAVE_DLADDR, 1, [Define if you have the `dladdr' function])) AC_CHECK_FUNC(fcntl, AC_DEFINE(HAVE_FCNTL, 1, [Define if you have the `fcntl' function])) +AC_CHECK_FUNC(pread, + AC_DEFINE(HAVE_PREAD, 1, + [Define if you have the 'pread' function])) +AC_CHECK_FUNC(pwrite, + AC_DEFINE(HAVE_PWRITE, 1, + [Define if you have the 'pwrite' function])) AX_C___ATTRIBUTE__ # We only care about these two attributes. @@ -139,7 +153,8 @@ LIBS="$SAVE_LIBS" # once the m4 macro of Google Mocking becomes ready. # Check if there is Google Test library installed. AC_CHECK_PROG(GTEST_CONFIG, gtest-config, "yes") -if test x"$GTEST_CONFIG" = "xyes"; then +AC_CHECK_LIB(gtest, main, have_gtest_lib="yes") +if test x"$GTEST_CONFIG" = "xyes" -a x"$have_gtest_lib" = "xyes"; then GTEST_CFLAGS=`gtest-config --cppflags --cxxflags` GTEST_LIBS=`gtest-config --ldflags --libs` AC_DEFINE(HAVE_LIB_GTEST, 1, [define if you have google gtest library]) @@ -211,6 +226,7 @@ AC_SUBST(ac_cv_have_libgflags) AC_SUBST(GFLAGS_CFLAGS) AC_SUBST(GTEST_CFLAGS) AC_SUBST(GMOCK_CFLAGS) +AC_SUBST(MINGW_CFLAGS) AC_SUBST(GFLAGS_LIBS) AC_SUBST(GTEST_LIBS) AC_SUBST(GMOCK_LIBS) diff --git a/src/config.h.in b/src/config.h.in index 0c5e8b0..8190f23 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -48,15 +48,24 @@ /* define if the compiler implements namespaces */ #undef HAVE_NAMESPACES +/* Define if you have the 'pread' function */ +#undef HAVE_PREAD + /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_PWD_H +/* Define if you have the 'pwrite' function */ +#undef HAVE_PWRITE + /* define if the compiler implements pthread_rwlock_* */ #undef HAVE_RWLOCK +/* Define if you have the 'sigaction' function */ +#undef HAVE_SIGACTION + /* Define if you have the `sigaltstack' function */ #undef HAVE_SIGALTSTACK diff --git a/src/googletest.h b/src/googletest.h index b3e26c4..21e4f64 100644 --- a/src/googletest.h +++ b/src/googletest.h @@ -81,7 +81,7 @@ static inline string GetTempDir() { #endif } -#ifdef OS_WINDOWS +#if defined(OS_WINDOWS) && defined(_MSC_VER) // The test will run in glog/vsproject/ // (e.g., glog/vsproject/logging_unittest). static const char TEST_SRC_DIR[] = "../.."; diff --git a/src/logging.cc b/src/logging.cc index ec334a9..12330b0 100644 --- a/src/logging.cc +++ b/src/logging.cc @@ -179,6 +179,38 @@ GLOG_DEFINE_string(log_backtrace_at, "", // TODO(hamaji): consider windows #define PATH_SEPARATOR '/' +#ifndef HAVE_PREAD +static ssize_t pread(int fd, void* buf, size_t count, off_t offset) { + off_t orig_offset = lseek(fd, 0, SEEK_CUR); + if (orig_offset == (off_t)-1) + return -1; + if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) + return -1; + ssize_t len = read(fd, buf, count); + if (len < 0) + return len; + if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return len; +} +#endif // !HAVE_PREAD + +#ifndef HAVE_PWRITE +static ssize_t pwrite(int fd, void* buf, size_t count, off_t offset) { + off_t orig_offset = lseek(fd, 0, SEEK_CUR); + if (orig_offset == (off_t)-1) + return -1; + if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) + return -1; + ssize_t len = write(fd, buf, count); + if (len < 0) + return len; + if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return len; +} +#endif // !HAVE_PWRITE + static void GetHostName(string* hostname) { #if defined(HAVE_SYS_UTSNAME_H) struct utsname buf; @@ -887,8 +919,10 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) { linkpath += linkname; unlink(linkpath.c_str()); // delete old one if it exists +#if defined(OS_WINDOWS) + // TODO(hamaji): Create lnk file on Windows? +#elif defined(HAVE_UNISTD_H) // We must have unistd.h. -#ifdef HAVE_UNISTD_H // Make the symlink be relative (in the same dir) so that if the // entire log directory gets relocated the link is still valid. const char *linkdest = slash ? (slash + 1) : filename; @@ -1824,8 +1858,11 @@ void TruncateLogFile(const char *path, int64 limit, int64 keep) { int64 read_offset, write_offset; // Don't follow symlinks unless they're our own fd symlinks in /proc int flags = O_RDWR; + // TODO(hamaji): Support other environments. +#ifdef OS_LINUX const char *procfd_prefix = "/proc/self/fd/"; if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; +#endif int fd = open(path, flags); if (fd == -1) { diff --git a/src/signalhandler.cc b/src/signalhandler.cc index d6c203b..cccd800 100644 --- a/src/signalhandler.cc +++ b/src/signalhandler.cc @@ -48,6 +48,9 @@ _START_GOOGLE_NAMESPACE_ +// TOOD(hamaji): Use signal instead of sigaction? +#ifdef HAVE_SIGACTION + namespace { // We'll install the failure signal handler for these signals. We could @@ -330,7 +333,10 @@ void FailureSignalHandler(int signal_number, } // namespace +#endif // HAVE_SIGACTION + void InstallFailureSignalHandler() { +#ifdef HAVE_SIGACTION // Build the sigaction struct. struct sigaction sig_action; memset(&sig_action, 0, sizeof(sig_action)); @@ -341,10 +347,13 @@ void InstallFailureSignalHandler() { for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL)); } +#endif // HAVE_SIGACTION } void InstallFailureWriter(void (*writer)(const char* data, int size)) { +#ifdef HAVE_SIGACTION g_failure_writer = writer; +#endif // HAVE_SIGACTION } _END_GOOGLE_NAMESPACE_ diff --git a/src/utilities.cc b/src/utilities.cc index a6d1961..f31c7c7 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -136,6 +136,8 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { static void DumpStackTraceAndExit() { DumpStackTrace(1, DebugWriteToStderr, NULL); + // TOOD(hamaji): Use signal instead of sigaction? +#ifdef HAVE_SIGACTION // Set the default signal handler for SIGABRT, to avoid invoking our // own signal handler installed by InstallFailedSignalHandler(). struct sigaction sig_action; @@ -143,6 +145,7 @@ static void DumpStackTraceAndExit() { sigemptyset(&sig_action.sa_mask); sig_action.sa_handler = SIG_DFL; sigaction(SIGABRT, &sig_action, NULL); +#endif // HAVE_SIGACTION abort(); } diff --git a/src/windows/config.h b/src/windows/config.h index 114762e..2d23fb0 100755 --- a/src/windows/config.h +++ b/src/windows/config.h @@ -3,121 +3,6 @@ /* Namespace for Google classes */ #define GOOGLE_NAMESPACE google -/* Define if you have the `dladdr' function */ -#undef HAVE_DLADDR - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXECINFO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUNWIND_H - -/* define if you have google gflags library */ -#undef HAVE_LIB_GFLAGS - -/* define if you have libunwind */ -#undef HAVE_LIB_UNWIND - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* define if the compiler implements pthread_rwlock_* */ -#undef HAVE_RWLOCK - -/* Define if you have the `sigaltstack' function */ -#undef HAVE_SIGALTSTACK - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* define if the compiler supports using expression for operator */ -#undef HAVE_USING_OPERATOR - -/* define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* define if your compiler has __builtin_expect */ -#undef HAVE___BUILTIN_EXPECT - -/* define if your compiler has __sync_val_compare_and_swap */ -#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#undef PC_FROM_UCONTEXT - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#undef STL_NAMESPACE - -/* Version number of package */ -#undef VERSION - /* Stops putting the code inside the Google namespace */ #define _END_GOOGLE_NAMESPACE_ } diff --git a/src/windows/port.h b/src/windows/port.h index c9be748..24d7677 100755 --- a/src/windows/port.h +++ b/src/windows/port.h @@ -62,6 +62,8 @@ * used by both C and C++ code, so we put all the C++ together. */ +#ifdef _MSC_VER + /* 4244: otherwise we get problems when substracting two size_t's to an int * 4251: it's complaining about a private struct I've chosen not to dllexport * 4355: we use this in a constructor, but we do it safely @@ -127,6 +129,8 @@ extern int safe_vsnprintf(char *str, size_t size, typedef int pid_t; #define getpid _getpid +#endif // _MSC_VER + // ----------------------------------- THREADS typedef DWORD pthread_t; typedef DWORD pthread_key_t; -- 2.7.4