diff --git a/CMakeLists.txt b/CMakeLists.txt index cf4cbb8..5639411 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,11 @@ cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR) +if (WIN32 AND NOT CYGWIN) + set (WINDOWS 1) +else () + set (WINDOWS 0) +endif () + # ---------------------------------------------------------------------------- # includes set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -27,7 +33,12 @@ version_numbers ( # ---------------------------------------------------------------------------- # configure options option (BUILD_SHARED_LIBS "Request build of shared libraries." OFF) -set (GFLAGS_SHARED_LIBS ${BUILD_SHARED_LIBS}) + +if (WINDOWS AND BUILD_SHARED_LIBS) + set (GFLAGS_IS_A_DLL 1) +else () + set (GFLAGS_IS_A_DLL 0) +endif () option (BUILD_gflags_LIB "Request build of the multi-threaded gflags library." ON) option (BUILD_gflags_nothreads_LIB "Request build of the single-threaded gflags library." ON) @@ -91,18 +102,44 @@ if (NOT GFLAGS_INTTYPES_FORMAT) " Set GFLAGS_INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.") endif () endif () -set ("GFLAGS_INTTYPES_FORMAT_${GFLAGS_INTTYPES_FORMAT}" TRUE) +# use of special characters in strings to circumvent bug #0008226 +if ("^${GFLAGS_INTTYPES_FORMAT}$" STREQUAL "^WIN$") + set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE VC7) +endif () +if (NOT GFLAGS_INTTYPES_FORMAT MATCHES "^(C99|BSD|VC7)$") + message (FATAL_ERROR "Invalid value for GFLAGS_INTTYPES_FORMAT! Choose one of \"C99\", \"BSD\", or \"VC7\"") +endif () +set (GFLAGS_INTTYPES_FORMAT_C99 0) +set (GFLAGS_INTTYPES_FORMAT_BSD 0) +set (GFLAGS_INTTYPES_FORMAT_VC7 0) +set ("GFLAGS_INTTYPES_FORMAT_${GFLAGS_INTTYPES_FORMAT}" 1) foreach (fname IN ITEMS stdint sys/types fnmatch inttypes unistd sys/stat) string (TOUPPER "${fname}" FNAME) string (REGEX REPLACE "/" "_" FNAME "${FNAME}") - check_include_file_cxx ("${fname}.h" GFLAGS_HAVE_${FNAME}_H) + if (HAVE_${FNAME}_H) + # set by check_type_size already + set (GFLAGS_HAVE_${FNAME}_H ${HAVE_${FNAME}_H}) + else () + check_include_file_cxx ("${fname}.h" GFLAGS_HAVE_${FNAME}_H) + endif () endforeach () +if (NOT GFLAGS_HAVE_FNMATCH_H AND WINDOWS) + check_include_file_cxx ("shlwapi.h" GFLAGS_HAVE_SHLWAPI_H) +endif () +bool_to_int(GFLAGS_HAVE_STDINT_H) +bool_to_int(GFLAGS_HAVE_SYS_TYPES_H) +bool_to_int(GFLAGS_HAVE_INTTYPES_H) -foreach (fname IN ITEMS strtoll strtoq) - string (TOUPPER "${fname}" FNAME) - check_cxx_symbol_exists ("${fname}" stdlib.h GFLAGS_HAVE_${FNAME}) -endforeach () +if (MSVC) + set (GFLAGS_HAVE_strtoll FALSE) + set (GFLAGS_HAVE_strtoq FALSE) +else () + foreach (fname IN ITEMS strtoll strtoq) + string (TOUPPER "${fname}" FNAME) + check_cxx_symbol_exists ("${fname}" stdlib.h GFLAGS_HAVE_${FNAME}) + endforeach () +endif () set (CMAKE_THREAD_PREFER_PTHREAD TRUE) find_package (ThreadsCXX) @@ -137,7 +174,7 @@ set (GFLAGS_SRCS "gflags_completions.cc" ) -if (WIN32) +if (WINDOWS) list (APPEND PRIVATE_HDRS "windows_port.h") list (APPEND GFLAGS_SRCS "windows_port.cc") endif () @@ -169,18 +206,11 @@ include_directories ("${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}") set (LIB_TARGETS) if (BUILD_gflags_LIB) add_library (gflags ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS}) - if (WIN32 AND BUILD_SHARED_LIBS) - set_target_properties (gflags PROPERTIES COMPILE_DEFINITIONS GFLAGS_DLL_EXPORT) - endif () list (APPEND LIB_TARGETS gflags) endif () if (BUILD_gflags_nothreads_LIB) add_library (gflags_nothreads ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS}) - if (WIN32 AND BUILD_SHARED_LIBS) - set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS "GFLAGS_DLL_EXPORT;NO_THREADS") - else () - set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS NO_THREADS) - endif () + set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS NO_THREADS) list (APPEND LIB_TARGETS gflags_nothreads) endif () diff --git a/cmake/utils.cmake b/cmake/utils.cmake index a6799cc..ead2638 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -1,5 +1,15 @@ ## Utility CMake functions. +# ---------------------------------------------------------------------------- +## Convert boolean value to 0 or 1 +macro (bool_to_int VAR) + if (${VAR}) + set (${VAR} 1) + else () + set (${VAR} 0) + endif () +endmacro () + # ---------------------------------------------------------------------------- ## Extract version numbers from version string. function (version_numbers version major minor patch) diff --git a/src/config.h.in b/src/config.h.in index 5d16df0..bf81745 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -2,10 +2,86 @@ // Note: This header file is only used internally. It is not part of public interface! -#include "gflags_declare.h" // system checks +// Whether gflags library is shared. Used for DLL import declaration. +#define GFLAGS_IS_A_DLL @GFLAGS_IS_A_DLL@ // --------------------------------------------------------------------------- -// Additional meta-information +// System checks + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_STDINT_H + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_SYS_TYPES_H + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_INTTYPES_H + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_SYS_STAT_H + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_UNISTD_H + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_FNMATCH_H + +// Define if you have the header file (Windows 2000/XP). +#cmakedefine GFLAGS_HAVE_SHLWAPI_H + +// Define if you have the strtoll function. +#cmakedefine GFLAGS_HAVE_STRTOLL + +// Define if you have the strtoq function. +#cmakedefine GFLAGS_HAVE_STRTOQ + +// Define if you have the header file. +#cmakedefine GFLAGS_HAVE_PTHREAD + +// Define if your pthread library defines the type pthread_rwlock_t +#cmakedefine GFLAGS_HAVE_RWLOCK + +// Backwards compatibility in case users defined these macros themselves +// or allow users to use these more general macros if the gflags library +// is build as part of a user project, e.g., included as Git submodule +#if defined(HAVE_STDINT_H) && !defined(GFLAGS_HAVE_STDINT_H) +# define GFLAGS_HAVE_STDINT_H +#endif +#if defined(HAVE_SYS_TYPES_H) && !defined(GFLAGS_HAVE_SYS_TYPES_H) +# define GFLAGS_HAVE_SYS_TYPES_H +#endif +#if defined(HAVE_INTTYPES_H) && !defined(GFLAGS_HAVE_INTTYPES_H) +# define GFLAGS_HAVE_INTTYPES_H +#endif +#if defined(HAVE_SYS_STAT_H) && !defined(GFLAGS_HAVE_SYS_STAT_H) +# define GFLAGS_HAVE_SYS_STAT_H +#endif +#if defined(HAVE_UNISTD_H) && !defined(GFLAGS_HAVE_UNISTD_H) +# define GFLAGS_HAVE_UNISTD_H +#endif +#if defined(HAVE_FNMATCH_H) && !defined(GFLAGS_HAVE_FNMATCH_H) +# define GFLAGS_HAVE_FNMATCH_H +#endif +#if defined(HAVE_STRTOLL) && !defined(GFLAGS_HAVE_STRTOLL) +# define GFLAGS_HAVE_STRTOLL +#endif +#if defined(HAVE_STRTOLQ) && !defined(GFLAGS_HAVE_STRTOLQ) +# define GFLAGS_HAVE_STRTOLQ +#endif +#if defined(HAVE_PTHREAD) && !defined(GFLAGS_HAVE_PTHREAD) +# define GFLAGS_HAVE_PTHREAD +#endif +#if defined(HAVE_RWLOCK) && !defined(GFLAGS_HAVE_RWLOCK) +# define GFLAGS_HAVE_RWLOCK +#endif + +// gcc requires this to get PRId64, etc. +#if defined(GFLAGS_HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS) +# define __STDC_FORMAT_MACROS 1 +#endif + +// --------------------------------------------------------------------------- +// Package information // Name of package. #define PACKAGE @PROJECT_NAME@ @@ -30,10 +106,42 @@ // --------------------------------------------------------------------------- // Path separator -#define PATH_SEPARATOR '/' +#ifndef PATH_SEPARATOR +# if _WIN32 +# define PATH_SEPARATOR '\\' +# else +# define PATH_SEPARATOR '/' +# endif +#endif // --------------------------------------------------------------------------- -// Windows port +// Windows + +// Always export symbols when compiling a shared library as this file is only +// included by internal modules when building the gflags library itself. +// The gflags_declare.h header file will set it to import these symbols otherwise. +#ifndef GFLAGS_DLL_DECL +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) +# define GFLAGS_DLL_DECL __declspec(dllexport) +# else +# define GFLAGS_DLL_DECL +# endif +#endif +// Flags defined by the gflags library itself must be exported +#ifndef GFLAGS_DLL_DEFINE_FLAG +# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL +#endif + #ifdef _WIN32 +// The unittests import the symbols of the shared gflags library +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) +# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) +# endif # include "windows_port.h" #endif + +// Export of STL class instantiations -- no extern keyword to not trigger a warning +// \sa http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958 +#if GFLAGS_IS_A_DLL && defined(_MSC_VER) && _MSC_VER >= 1100 +# define GFLAGS_EXTERN_STL +#endif \ No newline at end of file diff --git a/src/gflags.cc b/src/gflags.cc index 7033876..dc1616d 100644 --- a/src/gflags.cc +++ b/src/gflags.cc @@ -93,8 +93,11 @@ #include #include #include -#ifdef GFLAGS_HAVE_FNMATCH_H +#if defined(GFLAGS_HAVE_FNMATCH_H) # include +#elif defined(GFLAGS_HAVE_SHLWAPI_H) +# include +# pragma comment(lib, "shlwapi.lib") #endif #include // For va_list and related operations #include @@ -109,12 +112,6 @@ #include "mutex.h" #include "util.h" -// Export the following flags only if the gflags library is a DLL -#ifndef GFLAGS_SHARED_LIBS -# undef GFLAGS_DLL_DEFINE_FLAG -# define GFLAGS_DLL_DEFINE_FLAG -#endif - // Special flags, type 1: the 'recursive' flags. They set another flag's val. DEFINE_string(flagfile, "", "load flags from file"); DEFINE_string(fromenv, "", "set flags from the environment" @@ -1310,13 +1307,12 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked( // We try matching both against the full argv0 and basename(argv0) if (glob == ProgramInvocationName() // small optimization || glob == ProgramInvocationShortName() -#ifdef GFLAGS_HAVE_FNMATCH_H - || fnmatch(glob.c_str(), - ProgramInvocationName(), - FNM_PATHNAME) == 0 - || fnmatch(glob.c_str(), - ProgramInvocationShortName(), - FNM_PATHNAME) == 0 +#if defined(GFLAGS_HAVE_FNMATCH_H) + || fnmatch(glob.c_str(), ProgramInvocationName(), FNM_PATHNAME) == 0 + || fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0 +#elif defined(GFLAGS_HAVE_SHLWAPI_H) + || PathMatchSpec(glob.c_str(), ProgramInvocationName()) + || PathMatchSpec(glob.c_str(), ProgramInvocationShortName()) #endif ) { flags_are_relevant = true; diff --git a/src/gflags.h b/src/gflags.h index 41f53d9..550eca2 100644 --- a/src/gflags.h +++ b/src/gflags.h @@ -84,11 +84,13 @@ #include "gflags_declare.h" // IWYU pragma: export -// Export/import STL instantiations used as data members of exported classes -// \sa http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958 -#ifdef GFLAGS_EXTERN_STL - GFLAGS_EXTERN_STL template class GFLAGS_DLL_DECL std::allocator; - GFLAGS_EXTERN_STL template class GFLAGS_DLL_DECL std::basic_string; +// We always want to export variables defined in user code +#ifndef GFLAGS_DLL_DEFINE_FLAG +# ifdef _MSC_VER +# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport) +# else +# define GFLAGS_DLL_DEFINE_FLAG +# endif #endif @@ -124,19 +126,12 @@ namespace GFLAGS_NAMESPACE { // Returns true if successfully registered, false if not (because the // first argument doesn't point to a command-line flag, or because a // validator is already registered for this flag). -extern bool RegisterFlagValidator(const bool* flag, - bool (*validate_fn)(const char*, bool)); -extern bool RegisterFlagValidator(const int32* flag, - bool (*validate_fn)(const char*, int32)); -extern bool RegisterFlagValidator(const int64* flag, - bool (*validate_fn)(const char*, int64)); -extern bool RegisterFlagValidator(const uint64* flag, - bool (*validate_fn)(const char*, uint64)); -extern bool RegisterFlagValidator(const double* flag, - bool (*validate_fn)(const char*, double)); -extern bool RegisterFlagValidator(const std::string* flag, - bool (*validate_fn)(const char*, - const std::string&)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&)); // Convenience macro for the registration of a flag validator #define DEFINE_validator(name, validator) \ @@ -154,7 +149,12 @@ extern bool RegisterFlagValidator(const std::string* flag, // In addition to accessing flags, you can also access argv[0] (the program // name) and argv (the entire commandline), which we sock away a copy of. // These variables are static, so you should only set them once. - +#ifdef _MSC_VER +# pragma warning(push) +// The solution offered at http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958 +// is not really desireable as we don't want to explicitly instantiate/export any STL types +# pragma warning(disable: 4251) +#endif struct GFLAGS_DLL_DECL CommandLineFlagInfo { std::string name; // the name of the flag std::string type; // the type of the flag: int32, etc @@ -162,46 +162,49 @@ struct GFLAGS_DLL_DECL CommandLineFlagInfo { std::string current_value; // the current value, as a string std::string default_value; // the default value, as a string std::string filename; // 'cleaned' version of filename holding the flag - bool has_validator_fn; // true if RegisterFlagValidator called on this flag - bool is_default; // true if the flag has the default value and - // has not been set explicitly from the cmdline - // or via SetCommandLineOption - const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo) + bool has_validator_fn; // true if RegisterFlagValidator called on this flag + bool is_default; // true if the flag has the default value and + // has not been set explicitly from the cmdline + // or via SetCommandLineOption + const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo) }; +#ifdef _MSC_VER +# pragma warning(pop) +#endif // Using this inside of a validator is a recipe for a deadlock. // TODO(user) Fix locking when validators are running, to make it safe to // call validators during ParseAllFlags. // Also make sure then to uncomment the corresponding unit test in // gflags_unittest.sh -extern void GetAllFlags(std::vector* OUTPUT); +extern GFLAGS_DLL_DECL void GetAllFlags(std::vector* OUTPUT); // These two are actually defined in gflags_reporting.cc. -extern void ShowUsageWithFlags(const char *argv0); // what --help does -extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); +extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does +extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); // Create a descriptive string for a flag. // Goes to some trouble to make pretty line breaks. -extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag); +extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag); // Thread-hostile; meant to be called before any threads are spawned. -extern void SetArgv(int argc, const char** argv); +extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv); // The following functions are thread-safe as long as SetArgv() is // only called before any threads start. -extern const std::vector& GetArgvs(); -extern const char* GetArgv(); // all of argv as a string -extern const char* GetArgv0(); // only argv0 -extern uint32 GetArgvSum(); // simple checksum of argv -extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set -extern const char* ProgramInvocationShortName(); // basename(argv0) +extern GFLAGS_DLL_DECL const std::vector& GetArgvs(); +extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string +extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0 +extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv +extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set +extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0) // ProgramUsage() is thread-safe as long as SetUsageMessage() is only // called before any threads start. -extern const char* ProgramUsage(); // string set by SetUsageMessage() +extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage() // VersionString() is thread-safe as long as SetVersionString() is only // called before any threads start. -extern const char* VersionString(); // string set by SetVersionString() +extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString() @@ -215,17 +218,16 @@ extern const char* VersionString(); // string set by SetVersionString() // Return true iff the flagname was found. // OUTPUT is set to the flag's value, or unchanged if we return false. -extern bool GetCommandLineOption(const char* name, std::string* OUTPUT); +extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT); // Return true iff the flagname was found. OUTPUT is set to the flag's // CommandLineFlagInfo or unchanged if we return false. -extern bool GetCommandLineFlagInfo(const char* name, - CommandLineFlagInfo* OUTPUT); +extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT); // Return the CommandLineFlagInfo of the flagname. exit() if name not found. // Example usage, to check if a flag's value is currently the default value: // if (GetCommandLineFlagInfoOrDie("foo").is_default) ... -extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); +extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); enum GFLAGS_DLL_DECL FlagSettingMode { // update the flag's value (can call this multiple times). @@ -247,9 +249,8 @@ enum GFLAGS_DLL_DECL FlagSettingMode { // non-empty else. // SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) -extern std::string SetCommandLineOption(const char* name, const char* value); -extern std::string SetCommandLineOptionWithMode(const char* name, const char* value, - FlagSettingMode set_mode); +extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value); +extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode); // -------------------------------------------------------------------- @@ -297,17 +298,17 @@ GFLAGS_ATTRIBUTE_UNUSED; // Some deprecated or hopefully-soon-to-be-deprecated functions. // This is often used for logging. TODO(csilvers): figure out a better way -extern std::string CommandlineFlagsIntoString(); +extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString(); // Usually where this is used, a FlagSaver should be used instead. -extern bool ReadFlagsFromString(const std::string& flagfilecontents, - const char* prog_name, - bool errors_are_fatal); // uses SET_FLAGS_VALUE +extern GFLAGS_DLL_DECL +bool ReadFlagsFromString(const std::string& flagfilecontents, + const char* prog_name, + bool errors_are_fatal); // uses SET_FLAGS_VALUE // These let you manually implement --flagfile functionality. // DEPRECATED. -extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); -extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, - bool errors_are_fatal); // uses SET_FLAGS_VALUE +extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); +extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE // -------------------------------------------------------------------- @@ -318,12 +319,12 @@ extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name // Otherwise, return the value. NOTE: for booleans, for true use // 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'. -extern bool BoolFromEnv(const char *varname, bool defval); -extern int32 Int32FromEnv(const char *varname, int32 defval); -extern int64 Int64FromEnv(const char *varname, int64 defval); -extern uint64 Uint64FromEnv(const char *varname, uint64 defval); -extern double DoubleFromEnv(const char *varname, double defval); -extern const char *StringFromEnv(const char *varname, const char *defval); +extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval); +extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval); +extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval); +extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval); +extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval); +extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval); // -------------------------------------------------------------------- @@ -335,12 +336,12 @@ extern const char *StringFromEnv(const char *varname, const char *defval); // SetUsageMessage(usage); // Do not include commandline flags in the usage: we do that for you! // Thread-hostile; meant to be called before any threads are spawned. -extern void SetUsageMessage(const std::string& usage); +extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage); // Sets the version string, which is emitted with --version. // For instance: SetVersionString("1.3"); // Thread-hostile; meant to be called before any threads are spawned. -extern void SetVersionString(const std::string& version); +extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version); // Looks for flags in argv and parses them. Rearranges argv to put @@ -350,7 +351,7 @@ extern void SetVersionString(const std::string& version); // of the first non-flag argument. // See top-of-file for more details on this function. #ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. -extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags); +extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags); #endif @@ -364,18 +365,18 @@ extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags); // defined more than once in the command line or flag file, the last // definition is used. Returns the index (into argv) of the first // non-flag argument. (If remove_flags is true, will always return 1.) -extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, - bool remove_flags); +extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags); + // This is actually defined in gflags_reporting.cc. // This function is misnamed (it also handles --version, etc.), but // it's too late to change that now. :-( -extern void HandleCommandLineHelpFlags(); // in gflags_reporting.cc +extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc // Allow command line reparsing. Disables the error normally // generated when an unknown flag is found, since it may be found in a // later parse. Thread-hostile; meant to be called before any threads // are spawned. -extern void AllowCommandLineReparsing(); +extern GFLAGS_DLL_DECL void AllowCommandLineReparsing(); // Reparse the flags that have not yet been recognized. Only flags // registered since the last parse will be recognized. Any flag value @@ -383,7 +384,7 @@ extern void AllowCommandLineReparsing(); // separate command line argument that follows the flag argument. // Intended for handling flags from dynamically loaded libraries, // since their flags are not registered until they are loaded. -extern void ReparseCommandLineNonHelpFlags(); +extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags(); // Clean up memory allocated by flags. This is only needed to reduce // the quantity of "potentially leaked" reports emitted by memory @@ -394,7 +395,7 @@ extern void ReparseCommandLineNonHelpFlags(); // called will have unexpected consequences. This is not safe to run // when multiple threads might be running: the function is // thread-hostile. -extern void ShutDownCommandLineFlags(); +extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags(); // -------------------------------------------------------------------- @@ -425,7 +426,7 @@ extern void ShutDownCommandLineFlags(); // directly. The idea is that DEFINE puts the flag in the weird // namespace, and DECLARE imports the flag from there into the current // namespace. The net result is to force people to use DECLARE to get -// access to a flag, rather than saying "extern bool FLAGS_whatever;" +// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;" // or some such instead. We want this so we can put extra // functionality (like sanity-checking) in DECLARE if we want, and // make sure it is picked up everywhere. @@ -446,7 +447,7 @@ class GFLAGS_DLL_DECL FlagRegisterer { // binary file. This can reduce the size of the resulting binary // somewhat, and may also be useful for security reasons. -extern const char kStrippedFlagHelp[]; +extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[]; } // namespace GFLAGS_NAMESPACE @@ -561,7 +562,7 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot, clstring* const FLAGS_no##name = ::fLS:: \ dont_pass0toDEFINE_string(s_##name[0].s, \ val); \ - static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ + static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \ diff --git a/src/gflags_declare.h.in b/src/gflags_declare.h.in index a9b7b6a..91ceb51 100644 --- a/src/gflags_declare.h.in +++ b/src/gflags_declare.h.in @@ -47,9 +47,6 @@ #define GFLAGS_VERSION_MINOR @PACKAGE_VERSION_MINOR@ ///< Minor version number. #define GFLAGS_VERSION_PATCH @PACKAGE_VERSION_PATCH@ ///< Version patch number. -// Whether gflags library is shared. Used for DLL import declaration. -#cmakedefine GFLAGS_SHARED_LIBS - // --------------------------------------------------------------------------- // Namespace for gflags symbols. #define GFLAGS_NAMESPACE @GFLAGS_NAMESPACE@ @@ -60,148 +57,49 @@ // --------------------------------------------------------------------------- // Windows DLL import/export. + +// We always want to import the symbols of the gflags library #ifndef GFLAGS_DLL_DECL -# if defined(_MSC_VER) && defined(GFLAGS_SHARED_LIBS) -# ifdef GFLAGS_DLL_EXPORT -# define GFLAGS_DLL_DECL __declspec(dllexport) -# else -# define GFLAGS_DLL_DECL __declspec(dllimport) -# endif +# if @GFLAGS_IS_A_DLL@ && defined(_MSC_VER) +# define GFLAGS_DLL_DECL __declspec(dllimport) # else # define GFLAGS_DLL_DECL # endif #endif -// By default, we always want to export defined variables, assuming -// that the DEFINE_FLAG macros are used within shared modules. -#ifndef GFLAGS_DLL_DEFINE_FLAG -# if defined(_MSC_VER) -# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport) -# else -# define GFLAGS_DLL_DEFINE_FLAG -# endif -#endif - -// By default, we always want to export defined variables, assuming -// that the DECLARE_FLAG macros are used within shared modules. +// We always want to import variables declared in user code #ifndef GFLAGS_DLL_DECLARE_FLAG -# if defined(_MSC_VER) +# ifdef _MSC_VER # define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport) # else # define GFLAGS_DLL_DECLARE_FLAG # endif #endif -// Export/import of STL class instantiations -// \sa http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958 -#if defined(GFLAGS_SHARED_LIBS) && defined(_MSC_VER) && _MSC_VER >= 1100 -# ifdef GFLAGS_DLL_EXPORT -# define GFLAGS_EXTERN_STL -# else -# define GFLAGS_EXTERN_STL extern -# endif -#endif - -// --------------------------------------------------------------------------- -// Available system headers - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_STDINT_H - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_SYS_TYPES_H - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_INTTYPES_H - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_SYS_STAT_H - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_UNISTD_H - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_FNMATCH_H - -// Define if you have the strtoll function. -#cmakedefine GFLAGS_HAVE_STRTOLL - -// Define if you have the strtoq function. -#cmakedefine GFLAGS_HAVE_STRTOQ - -// Define if you have the header file. -#cmakedefine GFLAGS_HAVE_PTHREAD - -// Define if your pthread library defines the type pthread_rwlock_t -#cmakedefine GFLAGS_HAVE_RWLOCK - -// Backwards compatibility in case users defined these macros themselves -// or allow users to use these more general macros if the gflags library -// is build as part of a user project, e.g., included as Git submodule -#if defined(HAVE_STDINT_H) && !defined(GFLAGS_HAVE_STDINT_H) -# define GFLAGS_HAVE_STDINT_H -#endif -#if defined(HAVE_SYS_TYPES_H) && !defined(GFLAGS_HAVE_SYS_TYPES_H) -# define GFLAGS_HAVE_SYS_TYPES_H -#endif -#if defined(HAVE_INTTYPES_H) && !defined(GFLAGS_HAVE_INTTYPES_H) -# define GFLAGS_HAVE_INTTYPES_H -#endif -#if defined(HAVE_SYS_STAT_H) && !defined(GFLAGS_HAVE_SYS_STAT_H) -# define GFLAGS_HAVE_SYS_STAT_H -#endif -#if defined(HAVE_UNISTD_H) && !defined(GFLAGS_HAVE_UNISTD_H) -# define GFLAGS_HAVE_UNISTD_H -#endif -#if defined(HAVE_FNMATCH_H) && !defined(GFLAGS_HAVE_FNMATCH_H) -# define GFLAGS_HAVE_FNMATCH_H -#endif -#if defined(HAVE_STRTOLL) && !defined(GFLAGS_HAVE_STRTOLL) -# define GFLAGS_HAVE_STRTOLL -#endif -#if defined(HAVE_STRTOLQ) && !defined(GFLAGS_HAVE_STRTOLQ) -# define GFLAGS_HAVE_STRTOLQ -#endif -#if defined(HAVE_PTHREAD) && !defined(GFLAGS_HAVE_PTHREAD) -# define GFLAGS_HAVE_PTHREAD -#endif -#if defined(HAVE_RWLOCK) && !defined(GFLAGS_HAVE_RWLOCK) -# define GFLAGS_HAVE_RWLOCK -#endif - -// gcc requires this to get PRId64, etc. -#if defined(GFLAGS_HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS) -# define __STDC_FORMAT_MACROS 1 -#endif - // --------------------------------------------------------------------------- // Flag types #include -#if defined(GFLAGS_HAVE_STDINT_H) +#if @GFLAGS_HAVE_STDINT_H@ # include // the normal place uint32_t is defined -#elif defined(GFLAGS_HAVE_SYS_TYPES_H) +#elif @GFLAGS_HAVE_SYS_TYPES_H@ # include // the normal place u_int32_t is defined -#elif defined(GFLAGS_HAVE_INTTYPES_H) +#elif @GFLAGS_HAVE_INTTYPES_H@ # include // a third place for uint32_t or u_int32_t #endif -#cmakedefine GFLAGS_INTTYPES_FORMAT_C99 -#cmakedefine GFLAGS_INTTYPES_FORMAT_BSD -#cmakedefine GFLAGS_INTTYPES_FORMAT_VC7 - namespace GFLAGS_NAMESPACE { -#if defined(GFLAGS_INTTYPES_FORMAT_C99) +#if @GFLAGS_INTTYPES_FORMAT_C99@ // C99 typedef int32_t int32; typedef uint32_t uint32; typedef int64_t int64; typedef uint64_t uint64; -#elif defined(GFLAGS_INTTYPES_FORMAT_BSD) +#elif @GFLAGS_INTTYPES_FORMAT_BSD@ // BSD typedef int32_t int32; typedef u_int32_t uint32; typedef int64_t int64; typedef u_int64_t uint64; -#elif defined(GFLAGS_INTTYPES_FORMAT_VC7) // Windows +#elif @GFLAGS_INTTYPES_FORMAT_VC7@ // Windows typedef __int32 int32; typedef unsigned __int32 uint32; typedef __int64 int64; diff --git a/src/gflags_reporting.cc b/src/gflags_reporting.cc index a33c553..9cc41a7 100644 --- a/src/gflags_reporting.cc +++ b/src/gflags_reporting.cc @@ -246,7 +246,7 @@ static bool FileMatchesSubstring(const string& filename, // the string to be at the beginning of a directory component. // That should match the first directory component as well, so // we allow '/foo' to match a filename of 'foo'. - if (!target->empty() && (*target)[0] == '/' && + if (!target->empty() && (*target)[0] == PATH_SEPARATOR && strncmp(filename.c_str(), target->c_str() + 1, strlen(target->c_str() + 1)) == 0) return true; @@ -352,7 +352,8 @@ static void ShowVersion() { static void AppendPrognameStrings(vector* substrings, const char* progname) { - string r("/"); + string r(""); + r += PATH_SEPARATOR; r += progname; substrings->push_back(r + "."); substrings->push_back(r + "-main."); @@ -387,7 +388,7 @@ void HandleCommandLineHelpFlags() { gflags_exitfunc(1); } else if (!FLAGS_helpon.empty()) { - string restrict = "/" + FLAGS_helpon + "."; + string restrict = PATH_SEPARATOR + FLAGS_helpon + "."; ShowUsageWithFlagsRestrict(progname, restrict.c_str()); gflags_exitfunc(1); @@ -409,7 +410,7 @@ void HandleCommandLineHelpFlags() { ++flag) { if (!FileMatchesSubstring(flag->filename, substrings)) continue; - const string package = Dirname(flag->filename) + "/"; + const string package = Dirname(flag->filename) + PATH_SEPARATOR; if (package != last_package) { ShowUsageWithFlagsRestrict(progname, package.c_str()); VLOG(7) << "Found package: " << package; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 67e2e0c..3f7f17e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,9 +2,9 @@ # ---------------------------------------------------------------------------- # output directories -set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/bin") -set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/lib") -set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/lib") +set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") +set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") # set working directory of test commands set (GFLAGS_FLAGFILES_DIR "${CMAKE_CURRENT_SOURCE_DIR}") @@ -15,139 +15,134 @@ include_directories ("${CMAKE_CURRENT_SOURCE_DIR}") link_libraries (gflags_nothreads) # ---------------------------------------------------------------------------- -# STRIP_FLAG_HELP: check with "strings" that help text is not in binary -if (UNIX AND NOT CYGWIN) - add_executable (strip_flags gflags_strip_flags_test.cc) - add_test ( - NAME strip_flags - COMMAND /bin/bash "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.sh" - "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/strip_flags" - ) -endif () +# STRIP_FLAG_HELP +add_executable (gflags_strip_flags_test gflags_strip_flags_test.cc) +# Make sure the --help output doesn't print the stripped text. +add_gflags_test (strip_flags_help 1 "" "This text should be stripped out" gflags_strip_flags_test --help) +# Make sure the stripped text isn't in the binary at all. +add_test ( + NAME strip_flags_binary + COMMAND "${CMAKE_COMMAND}" "-DBINARY=$" + -P "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.cmake" +) # ---------------------------------------------------------------------------- # unit tests configure_file (gflags_unittest.cc gflags_unittest-main.cc COPYONLY) configure_file (gflags_unittest.cc gflags_unittest_main.cc COPYONLY) -add_executable (unittest gflags_unittest.cc) -add_executable (unittest2 gflags_unittest-main.cc) -add_executable (unittest3 gflags_unittest_main.cc) +add_executable (gflags_unittest gflags_unittest.cc) +add_executable (gflags_unittest-main gflags_unittest-main.cc) +add_executable (gflags_unittest_main gflags_unittest_main.cc) -if (UNIX) - set (SLASH "/") -else () +if (WIN32 AND NOT CYGWIN) set (SLASH "\\\\") +else () + set (SLASH "/") endif () -# First, just make sure the unittest works as-is -add_gflags_test(unittest 0 "" "" unittest) +# First, just make sure the gflags_unittest works as-is +add_gflags_test(unittest 0 "" "" gflags_unittest) # --help should show all flags, including flags from gflags_reporting -add_gflags_test(help-reporting 1 "${SLASH}gflags_reporting.cc" "" unittest --help) +add_gflags_test(help-reporting 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --help) # Make sure that --help prints even very long helpstrings. -add_gflags_test(long-helpstring 1 "end of a long helpstring" "" unittest --help) +add_gflags_test(long-helpstring 1 "end of a long helpstring" "" gflags_unittest --help) # Make sure --help reflects flag changes made before flag-parsing -add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" "" unittest --help) -add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" "" unittest --help) +add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" "" gflags_unittest --help) +add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" "" gflags_unittest --help) # And on the command-line, too -add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" "" unittest --changeable_string_var 2 --help) +add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" "" gflags_unittest --changeable_string_var 2 --help) # --nohelp and --help=false should be as if we didn't say anything -add_gflags_test(nohelp 0 "PASS" "" unittest --nohelp) -add_gflags_test(help=false 0 "PASS" "" unittest --help=false) +add_gflags_test(nohelp 0 "PASS" "" gflags_unittest --nohelp) +add_gflags_test(help=false 0 "PASS" "" gflags_unittest --help=false) # --helpfull is the same as help -add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc" "" unittest --helpfull) +add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helpfull) -# --helpshort should show only flags from the unittest itself -add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags_reporting.cc" unittest --helpshort) +# --helpshort should show only flags from the gflags_unittest itself +add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest --helpshort) -# --helpshort should show the tldflag we created in the unittest dir -add_gflags_test(helpshort-tldflag1 1 "tldflag1" "${SLASH}google.cc" unittest --helpshort) -add_gflags_test(helpshort-tldflag2 1 "tldflag2" "${SLASH}google.cc" unittest --helpshort) +# --helpshort should show the tldflag we created in the gflags_unittest dir +add_gflags_test(helpshort-tldflag1 1 "tldflag1" "${SLASH}google.cc:" gflags_unittest --helpshort) +add_gflags_test(helpshort-tldflag2 1 "tldflag2" "${SLASH}google.cc:" gflags_unittest --helpshort) # --helpshort should work if the main source file is suffixed with [_-]main -add_gflags_test(helpshort-main 1 "${SLASH}gflags_unittest-main.cc" "${SLASH}gflags_reporting.cc" unittest2 --helpshort) -add_gflags_test(helpshort_main 1 "${SLASH}gflags_unittest_main.cc" "${SLASH}gflags_reporting.cc" unittest3 --helpshort) +add_gflags_test(helpshort-main 1 "${SLASH}gflags_unittest-main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest-main --helpshort) +add_gflags_test(helpshort_main 1 "${SLASH}gflags_unittest_main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest_main --helpshort) # --helpon needs an argument -add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" "" unittest --helpon) - -if (BUILD_SHARED_LIBS) - # --helpon argument indicates what file we'll show args from - # TODO(andreas): This test fails. Why is there no help for the gflags module ? - add_gflags_test(helpon=gflags 1 "${SLASH}gflags.cc" "${SLASH}gflags_unittest.cc" unittest --helpon=gflags) - # another way of specifying the argument - # TODO(andreas): This test fails. Why is there no help for the gflags module ? - add_gflags_test(helpon_gflags 1 "${SLASH}gflags.cc" "${SLASH}gflags_unittest.cc" unittest --helpon gflags) -endif () - +add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" "" gflags_unittest --helpon) +# --helpon argument indicates what file we'll show args from +add_gflags_test(helpon=gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpon=gflags) +# another way of specifying the argument +add_gflags_test(helpon_gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpon gflags) # test another argument -add_gflags_test(helpon=gflags_unittest 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags.cc" unittest --helpon=gflags_unittest) +add_gflags_test(helpon=gflags_unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:" gflags_unittest --helpon=gflags_unittest) # helpmatch is like helpon but takes substrings -add_gflags_test(helpmatch_reporting 1 "${SLASH}gflags_reporting.cc" "${SLASH}gflags_unittest.cc" unittest -helpmatch reporting) -add_gflags_test(helpmatch=unittest 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags.cc:" unittest -helpmatch=unittest) +add_gflags_test(helpmatch_reporting 1 "${SLASH}gflags_reporting.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpmatch reporting) +add_gflags_test(helpmatch=unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:" gflags_unittest -helpmatch=unittest) # if no flags are found with helpmatch or helpon, suggest --help -add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "${SLASH}gflags_unittest.cc" unittest -helpmatch=nosuchsubstring) -add_gflags_test(helpon=nosuchmodule 1 "No modules matched" "${SLASH}gflags_unittest.cc" unittest -helpon=nosuchmodule) +add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpmatch=nosuchsubstring) +add_gflags_test(helpon=nosuchmodule 1 "No modules matched" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpon=nosuchmodule) # helppackage shows all the flags in the same dir as this unittest # --help should show all flags, including flags from google.cc -add_gflags_test(helppackage 1 "${SLASH}gflags_reporting.cc" "" unittest --helppackage) +add_gflags_test(helppackage 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helppackage) # xml! -add_gflags_test(helpxml 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags_unittest.cc:" unittest --helpxml) +add_gflags_test(helpxml 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpxml) # just print the version info and exit -add_gflags_test(version-1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --version) -add_gflags_test(version-2 0 "version test_version" "${SLASH}gflags_unittest.cc" unittest --version) +add_gflags_test(version-1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --version) +add_gflags_test(version-2 0 "version test_version" "${SLASH}gflags_unittest.cc:" gflags_unittest --version) # --undefok is a fun flag... -add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" "" unittest --undefok= --foo --unused_bool) -add_gflags_test(undefok-2 0 "PASS" "" unittest --undefok=foo --foo --unused_bool) +add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok= --foo --unused_bool) +add_gflags_test(undefok-2 0 "PASS" "" gflags_unittest --undefok=foo --foo --unused_bool) # If you say foo is ok to be undefined, we'll accept --nofoo as well -add_gflags_test(undefok-3 0 "PASS" "" unittest --undefok=foo --nofoo --unused_bool) +add_gflags_test(undefok-3 0 "PASS" "" gflags_unittest --undefok=foo --nofoo --unused_bool) # It's ok if the foo is in the middle -add_gflags_test(undefok-4 0 "PASS" "" unittest --undefok=fee,fi,foo,fum --foo --unused_bool) +add_gflags_test(undefok-4 0 "PASS" "" gflags_unittest --undefok=fee,fi,foo,fum --foo --unused_bool) # But the spelling has to be just right... -add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" "" unittest --undefok=fo --foo --unused_bool) -add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" "" unittest --undefok=foot --foo --unused_bool) +add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok=fo --foo --unused_bool) +add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok=foot --foo --unused_bool) # See if we can successfully load our flags from the flagfile -add_gflags_test(flagfile.1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest "--flagfile=flagfile.1") -add_gflags_test(flagfile.2 0 "PASS" "" unittest "--flagfile=flagfile.2") -add_gflags_test(flagfile.3 0 "PASS" "" unittest "--flagfile=flagfile.3") +add_gflags_test(flagfile.1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest "--flagfile=flagfile.1") +add_gflags_test(flagfile.2 0 "PASS" "" gflags_unittest "--flagfile=flagfile.2") +add_gflags_test(flagfile.3 0 "PASS" "" gflags_unittest "--flagfile=flagfile.3") # Also try to load flags from the environment -add_gflags_test(fromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --fromenv=version) -add_gflags_test(tryfromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --tryfromenv=version) -add_gflags_test(fromenv=help 0 "PASS" "" unittest --fromenv=help) -add_gflags_test(tryfromenv=help 0 "PASS" "" unittest --tryfromenv=help) -add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" unittest --fromenv=helpfull) -add_gflags_test(tryfromenv=helpfull 0 "PASS" "" unittest --tryfromenv=helpfull) -add_gflags_test(tryfromenv=undefok 0 "PASS" "" unittest --tryfromenv=undefok --foo) -add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" unittest --tryfromenv=weirdo) -add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --tryfromenv=test_bool,version,unused_bool) -add_gflags_test(fromenv=test_bool 1 "not found in environment" "" unittest --fromenv=test_bool) -add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" "" unittest --fromenv=test_bool,ok) +add_gflags_test(fromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --fromenv=version) +add_gflags_test(tryfromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=version) +add_gflags_test(fromenv=help 0 "PASS" "" gflags_unittest --fromenv=help) +add_gflags_test(tryfromenv=help 0 "PASS" "" gflags_unittest --tryfromenv=help) +add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" gflags_unittest --fromenv=helpfull) +add_gflags_test(tryfromenv=helpfull 0 "PASS" "" gflags_unittest --tryfromenv=helpfull) +add_gflags_test(tryfromenv=undefok 0 "PASS" "" gflags_unittest --tryfromenv=undefok --foo) +add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" gflags_unittest --tryfromenv=weirdo) +add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=test_bool,version,unused_bool) +add_gflags_test(fromenv=test_bool 1 "not found in environment" "" gflags_unittest --fromenv=test_bool) +add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" "" gflags_unittest --fromenv=test_bool,ok) # Here, the --version overrides the fromenv -add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --fromenv=test_bool,version,ok) +add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --fromenv=test_bool,version,ok) # Make sure -- by itself stops argv processing -add_gflags_test(dashdash 0 "PASS" "" unittest -- --help) +add_gflags_test(dashdash 0 "PASS" "" gflags_unittest -- --help) # And we should die if the flag value doesn't pass the validator -add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" unittest --always_fail) +add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" gflags_unittest --always_fail) # And if locking in validators fails # TODO(andreas): Worked on Windows 7 Release configuration, but causes # debugger abort() intervention in case of Debug configuration. -#add_gflags_test(deadlock_if_cant_lock 0 "PASS" "" unittest --deadlock_if_cant_lock) +#add_gflags_test(deadlock_if_cant_lock 0 "PASS" "" gflags_unittest --deadlock_if_cant_lock) # ---------------------------------------------------------------------------- # (negative) compilation tests @@ -159,15 +154,15 @@ if (BUILD_NEGATIVE_COMPILATION_TESTS) endif () set (SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}/nc") configure_file (gflags_nc.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" @ONLY) - macro (add_nc_test name) + macro (add_gflags_nc_test name) add_test ( NAME nc_${name} COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" ${name} ) endmacro () - add_nc_test (sanity) - add_nc_test (swapped_args) - add_nc_test (int_instead_of_bool) - add_nc_test (bool_in_quotes) - add_nc_test (define_string_with_0) + add_gflags_nc_test (sanity) + add_gflags_nc_test (swapped_args) + add_gflags_nc_test (int_instead_of_bool) + add_gflags_nc_test (bool_in_quotes) + add_gflags_nc_test (define_string_with_0) endif () \ No newline at end of file diff --git a/test/config_for_unittests.h b/test/config_for_unittests.h index ac0df4c..914571b 100644 --- a/test/config_for_unittests.h +++ b/test/config_for_unittests.h @@ -55,9 +55,25 @@ #include "config.h" -#undef GFLAGS_DLL_DECL -#ifdef GFLAGS_DLL_DECL_FOR_UNITTESTS -# define GFLAGS_DLL_DECL GFLAGS_DLL_DECL_FOR_UNITTESTS -#else -# define GFLAGS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use "" +#ifdef GFLAGS_DLL_DECL +# undef GFLAGS_DLL_DECL #endif +#ifdef GFLAGS_DLL_DEFINE_FLAG +# undef GFLAGS_DLL_DEFINE_FLAG +#endif +#ifdef GFLAGS_DLL_DECLARE_FLAG +# undef GFLAGS_DLL_DECLARE_FLAG +#endif + +#ifdef GFLAGS_DLL_DECL_FOR_UNITTESTS +# define GFLAGS_DLL_DECL GFLAGS_DLL_DECL_FOR_UNITTESTS +#else +# define GFLAGS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use "" +#endif + +// Import flags defined by gflags.cc +#if GFLAGS_IS_A_DLL && defined(_MSC_VER) +# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport) +#else +# define GFLAGS_DLL_DECLARE_FLAG +#endif \ No newline at end of file diff --git a/test/gflags_strip_flags_test.cmake b/test/gflags_strip_flags_test.cmake new file mode 100644 index 0000000..bd419c4 --- /dev/null +++ b/test/gflags_strip_flags_test.cmake @@ -0,0 +1,7 @@ +if (NOT BINARY) + message (FATAl_ERROR "BINARY file to check not specified!") +endif () +file (STRINGS "${BINARY}" strings REGEX "This text should be stripped out") +if (strings) + message (FATAL_ERROR "Text not stripped from binary like it should be: ${BINARY}") +endif () \ No newline at end of file diff --git a/test/gflags_strip_flags_test.sh b/test/gflags_strip_flags_test.sh deleted file mode 100755 index 9ebb457..0000000 --- a/test/gflags_strip_flags_test.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2011, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# --- -# Author: csilvers@google.com (Craig Silverstein) - -if [ -z "$1" ]; then - echo "USAGE: $0 " - exit 1 -fi -BINARY="$1" - -# Make sure the binary exists... -if ! "$BINARY" >/dev/null 2>/dev/null -then - echo "Cannot run binary $BINARY" - exit 1 -fi - -# Make sure the --help output doesn't print the stripped text. -if "$BINARY" --help | grep "This text should be stripped out" >/dev/null 2>&1 -then - echo "Text not stripped from --help like it should be: $BINARY" - exit 1 -fi - -# Make sure the stripped text isn't in the binary at all. -if strings --help >/dev/null 2>&1 # make sure the binary exists -then - # Unfortunately, for us, libtool can replace executables with a - # shell script that does some work before calling the 'real' - # executable under a different name. We need the 'real' - # executable name to run 'strings' on it, so we construct this - # binary to print the real name (argv[0]) on stdout when run. - REAL_BINARY=`"$BINARY"` - # On cygwin, we may need to add a '.exe' extension by hand. - [ -f "$REAL_BINARY.exe" ] && REAL_BINARY="$REAL_BINARY.exe" - if strings "$REAL_BINARY" | grep "This text should be stripped" >/dev/null 2>&1 - then - echo "Text not stripped from binary like it should be: $BINARY" - exit 1 - fi - - # Let's also do a sanity check to make sure strings is working properly - if ! strings "$REAL_BINARY" | grep "Usage message" >/dev/null 2>&1 - then - echo "Usage text not found in binary like it should be: $BINARY" - exit 1 - fi -fi - -echo "PASS" diff --git a/test/gflags_unittest.cc b/test/gflags_unittest.cc index cdcb600..cff9b7c 100644 --- a/test/gflags_unittest.cc +++ b/test/gflags_unittest.cc @@ -35,11 +35,6 @@ #include "config_for_unittests.h" #include -#ifndef GFLAGS_SHARED_LIBS -# undef GFLAGS_DLL_DECLARE_FLAG -# define GFLAGS_DLL_DECLARE_FLAG -#endif - #include // for isinf() and isnan() #include #include