From 357b3d9d0b6dccbfd56ae0a466494f6c2da21901 Mon Sep 17 00:00:00 2001 From: Craig Silverstein Date: Fri, 29 Jul 2011 22:49:50 +0000 Subject: [PATCH] mingw fixes: 1) mingw needs an #include to have access to mkdir. 2) It needs to always #include port.h (this is an identical bit of code, in configure.ac, that I have in other opensource projects for mingw support.) 3) I moved some code from port.cc to port.h, so I didn't have to add logic to link in port.cc for mingw. Last change before new release! (*knock on wood*) Submitting TBR so I can get the release out today. This isn't exactly a trivial change, so I'm chary to submit TBR, but it's pretty isolated to windows and mingw, and I've tested on those platforms to make sure they compile and all tests pass. DELTA=70 (37 added, 30 deleted, 3 changed) Revision created by MOE tool push_codebase. MOE_MIGRATION=2823 git-svn-id: https://gflags.googlecode.com/svn/trunk@54 6586e3c6-dcc4-952a-343f-ff74eb82781d --- configure | 46 +++++++++++++++++++++++++-------------------- configure.ac | 9 +++++++++ src/config.h.in | 6 ++++++ src/util.h | 14 ++++++++++---- src/windows/port.cc | 23 ----------------------- src/windows/port.h | 29 +++++++++++++++++++++------- 6 files changed, 73 insertions(+), 54 deletions(-) diff --git a/configure b/configure index 073c80f..d1d2575 100755 --- a/configure +++ b/configure @@ -4469,6 +4469,12 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac +# MinGW uses autoconf, but also needs the windows shim routines +# (since it doesn't have its own support for, say, pthreads). +# This requires us to #include a special header file, and also to +# link in some windows versions of .o's instead of the unix versions. + + # Populate $host_cpu, $host_os, etc. { $as_echo "$as_me:$LINENO: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } @@ -5205,13 +5211,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:5208: $ac_compile\"" >&5) + (eval echo "\"\$as_me:5214: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:5211: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:5217: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:5214: output\"" >&5) + (eval echo "\"\$as_me:5220: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6433,7 +6439,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6436 "configure"' > conftest.$ac_ext + echo '#line 6442 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8764,11 +8770,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8767: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8773: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8771: \$? = $ac_status" >&5 + echo "$as_me:8777: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9103,11 +9109,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9106: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9112: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:9110: \$? = $ac_status" >&5 + echo "$as_me:9116: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -9208,11 +9214,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9211: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9217: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9215: \$? = $ac_status" >&5 + echo "$as_me:9221: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9263,11 +9269,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:9266: $lt_compile\"" >&5) + (eval echo "\"\$as_me:9272: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:9270: \$? = $ac_status" >&5 + echo "$as_me:9276: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12080,7 +12086,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12083 "configure" +#line 12089 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12176,7 +12182,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 12179 "configure" +#line 12185 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -14196,11 +14202,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14199: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14205: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14203: \$? = $ac_status" >&5 + echo "$as_me:14209: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14295,11 +14301,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14298: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14304: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14302: \$? = $ac_status" >&5 + echo "$as_me:14308: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14347,11 +14353,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14350: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14356: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14354: \$? = $ac_status" >&5 + echo "$as_me:14360: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized diff --git a/configure.ac b/configure.ac index 8538b28..94686c5 100644 --- a/configure.ac +++ b/configure.ac @@ -23,6 +23,15 @@ AC_PROG_CXX AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc AC_CANONICAL_HOST +# MinGW uses autoconf, but also needs the windows shim routines +# (since it doesn't have its own support for, say, pthreads). +# This requires us to #include a special header file, and also to +# link in some windows versions of .o's instead of the unix versions. +AH_BOTTOM([ +#if defined( __MINGW32__) || defined(__MINGW64__) +#include "windows/port.h" +#endif +]) # Populate $host_cpu, $host_os, etc. AC_CANONICAL_HOST case $host_os in diff --git a/src/config.h.in b/src/config.h.in index 28dfa37..5338b73 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -98,3 +98,9 @@ /* Puts following code inside the Google namespace */ #undef _START_GOOGLE_NAMESPACE_ + + +#if defined( __MINGW32__) || defined(__MINGW64__) +#include "windows/port.h" +#endif + diff --git a/src/util.h b/src/util.h index 8170c0a..f1d0016 100644 --- a/src/util.h +++ b/src/util.h @@ -227,22 +227,28 @@ class Test {}; // Tries to create the directory path as a temp-dir. If it fails, // changes path to some directory it *can* create. -inline void MakeTmpdir(std::string* path) { #if defined(__MINGW32__) +#include +inline void MakeTmpdir(std::string* path) { // I had trouble creating a directory in /tmp from mingw *path = "./gflags_unittest_testdir"; mkdir(path->c_str()); // mingw has a weird one-arg mkdir +} #elif defined(_MSC_VER) +#include +inline void MakeTmpdir(std::string* path) { char tmppath_buffer[1024]; int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer); assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer)); assert(tmppath_buffer[tmppath_len - 1] == '\\'); // API guarantees it *path = std::string(tmppath_buffer) + "gflags_unittest_testdir"; _mkdir(path->c_str()); -#else - mkdir(path->c_str(), 0755); -#endif } +#else +inline void MakeTmpdir(std::string* path) { + mkdir(path->c_str(), 0755); +} +#endif // -- string routines -------------------------------------------------------- diff --git a/src/windows/port.cc b/src/windows/port.cc index cbe1307..fb47698 100644 --- a/src/windows/port.cc +++ b/src/windows/port.cc @@ -37,7 +37,6 @@ #include #include // for strlen(), memset(), memcmp() -#include // for _putenv, etc. #include #include // for va_list, va_start, va_end #include @@ -61,25 +60,3 @@ int snprintf(char *str, size_t size, const char *format, ...) { return r; } #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */ - -void setenv(const char* name, const char* value, int) { - // In windows, it's impossible to set a variable to the empty string. - // We handle this by setting it to "0" and the NUL-ing out the \0. - // That is, we putenv("FOO=0") and then find out where in memory the - // putenv wrote "FOO=0", and change it in-place to "FOO=\0". - // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508 - static const char* const kFakeZero = "0"; - if (*value == '\0') - value = kFakeZero; - // Apparently the semantics of putenv() is that the input - // must live forever, so we leak memory here. :-( - const int nameval_len = strlen(name) + 1 + strlen(value) + 1; - char* nameval = reinterpret_cast(malloc(nameval_len)); - snprintf(nameval, nameval_len, "%s=%s", name, value); - _putenv(nameval); - if (value == kFakeZero) { - nameval[nameval_len - 2] = '\0'; // works when putenv() makes no copy - if (*getenv(name) != '\0') - *getenv(name) = '\0'; // works when putenv() copies nameval - } -} diff --git a/src/windows/port.h b/src/windows/port.h index be8eb1f..eea4eb5 100644 --- a/src/windows/port.h +++ b/src/windows/port.h @@ -40,12 +40,6 @@ #ifndef GOOGLE_GFLAGS_WINDOWS_PORT_H_ #define GOOGLE_GFLAGS_WINDOWS_PORT_H_ -// You should never include this file directly, but always include it -// from either config.h (MSVC) or mingw.h (MinGW/msys). -#if !defined(GOOGLE_GFLAGS_WINDOWS_CONFIG_H_) -# error "port.h should only be included from config.h" -#endif - #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN @@ -53,6 +47,7 @@ #endif #include #include /* for mkdir */ +#include /* for _putenv, getenv */ #include /* need this to override stdio's snprintf */ #include /* util.h uses va_copy */ #include /* for _stricmp */ @@ -70,7 +65,27 @@ extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size, #define va_copy(dst, src) (dst) = (src) #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */ -extern void GFLAGS_DLL_DECL setenv(const char* name, const char* value, int); +inline void setenv(const char* name, const char* value, int) { + // In windows, it's impossible to set a variable to the empty string. + // We handle this by setting it to "0" and the NUL-ing out the \0. + // That is, we putenv("FOO=0") and then find out where in memory the + // putenv wrote "FOO=0", and change it in-place to "FOO=\0". + // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508 + static const char* const kFakeZero = "0"; + if (*value == '\0') + value = kFakeZero; + // Apparently the semantics of putenv() is that the input + // must live forever, so we leak memory here. :-( + const int nameval_len = strlen(name) + 1 + strlen(value) + 1; + char* nameval = reinterpret_cast(malloc(nameval_len)); + snprintf(nameval, nameval_len, "%s=%s", name, value); + _putenv(nameval); + if (value == kFakeZero) { + nameval[nameval_len - 2] = '\0'; // works when putenv() makes no copy + if (*getenv(name) != '\0') + *getenv(name) = '\0'; // works when putenv() copies nameval + } +} #define strcasecmp _stricmp