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