From 587c1b37c2f0b6d430fb13ce09326db0135b557c Mon Sep 17 00:00:00 2001 From: vladlosev Date: Fri, 20 May 2011 00:42:22 +0000 Subject: [PATCH] Adds support for building Google Mock as a shared library (DLL). --- CMakeLists.txt | 34 ++++++++++++++----- include/gmock/gmock-cardinalities.h | 12 +++---- include/gmock/gmock-matchers.h | 9 ++--- include/gmock/gmock-spec-builders.h | 22 ++++++------ include/gmock/gmock.h | 4 +-- include/gmock/internal/gmock-internal-utils.h | 10 +++--- include/gmock/internal/gmock-port.h | 12 +++---- src/gmock-cardinalities.cc | 10 +++--- src/gmock-internal-utils.cc | 11 +++--- src/gmock-matchers.cc | 7 ++-- src/gmock-spec-builders.cc | 10 +++--- src/gmock.cc | 4 +-- src/gmock_main.cc | 4 +-- test/gmock-matchers_test.cc | 2 +- 14 files changed, 86 insertions(+), 65 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3cabd161..ded9ca9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,11 +9,6 @@ # make it prominent in the GUI. option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) -# Forces BUILD_SHARED_LIBS to OFF as Google Mock currently does not support -# working in a DLL. -# TODO(vladl@google.com): Implement building gMock as a DLL. -set(BUILD_SHARED_LIBS OFF) - option(gmock_build_tests "Build all of Google Mock's own tests." OFF) # A directory to find Google Test sources. @@ -76,11 +71,16 @@ include_directories("${gmock_SOURCE_DIR}/include" # Google Mock libraries. We build them using more strict warnings than what # are used for other targets, to ensure that Google Mock can be compiled by # a user aggressive about warnings. -cxx_library(gmock "${cxx_strict}" src/gmock-all.cc) -target_link_libraries(gmock gtest) +cxx_library(gmock + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc) -cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc) -target_link_libraries(gmock_main gmock) +cxx_library(gmock_main + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc + src/gmock_main.cc) ######################################################################## # @@ -129,8 +129,10 @@ if (gmock_build_tests) cxx_library(gmock_main_no_exception "${cxx_no_exception}" "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + cxx_library(gmock_main_use_own_tuple "${cxx_use_own_tuple}" "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) @@ -143,6 +145,20 @@ if (gmock_build_tests) cxx_test_with_flags(gmock_use_own_tuple_test "${cxx_use_own_tuple}" gmock_main_use_own_tuple test/gmock-spec-builders_test.cc) + cxx_shared_library(shared_gmock_main "${cxx_default}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + # Tests that a binary can be built with Google Mock as a shared library. On + # some system configurations, it may not possible to run the binary without + # knowing more details about the system configurations. We do not try to run + # this binary. To get a more robust shared library coverage, configure with + # -DBUILD_SHARED_LIBS=ON. + cxx_executable_with_flags(shared_gmock_test_ "${cxx_default}" + shared_gmock_main test/gmock-spec-builders_test.cc) + set_target_properties(shared_gmock_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + ############################################################ # Python tests. diff --git a/include/gmock/gmock-cardinalities.h b/include/gmock/gmock-cardinalities.h index 954a86ea..759dcf8c 100644 --- a/include/gmock/gmock-cardinalities.h +++ b/include/gmock/gmock-cardinalities.h @@ -80,7 +80,7 @@ class CardinalityInterface { // be called. The implementation of Cardinality is just a linked_ptr // to const CardinalityInterface, so copying is fairly cheap. // Don't inherit from Cardinality! -class Cardinality { +class GTEST_API_ Cardinality { public: // Constructs a null cardinality. Needed for storing Cardinality // objects in STL containers. @@ -122,19 +122,19 @@ class Cardinality { }; // Creates a cardinality that allows at least n calls. -Cardinality AtLeast(int n); +GTEST_API_ Cardinality AtLeast(int n); // Creates a cardinality that allows at most n calls. -Cardinality AtMost(int n); +GTEST_API_ Cardinality AtMost(int n); // Creates a cardinality that allows any number of calls. -Cardinality AnyNumber(); +GTEST_API_ Cardinality AnyNumber(); // Creates a cardinality that allows between min and max calls. -Cardinality Between(int min, int max); +GTEST_API_ Cardinality Between(int min, int max); // Creates a cardinality that allows exactly n calls. -Cardinality Exactly(int n); +GTEST_API_ Cardinality Exactly(int n); // Creates a cardinality from its implementation. inline Cardinality MakeCardinality(const CardinalityInterface* c) { diff --git a/include/gmock/gmock-matchers.h b/include/gmock/gmock-matchers.h index c21fa515..9445bf91 100644 --- a/include/gmock/gmock-matchers.h +++ b/include/gmock/gmock-matchers.h @@ -268,7 +268,7 @@ class Matcher : public internal::MatcherBase { // instead of Eq(str) and "foo" instead of Eq("foo") when a string // matcher is expected. template <> -class Matcher +class GTEST_API_ Matcher : public internal::MatcherBase { public: Matcher() {} @@ -285,7 +285,7 @@ class Matcher }; template <> -class Matcher +class GTEST_API_ Matcher : public internal::MatcherBase { public: Matcher() {} @@ -2548,8 +2548,9 @@ class ElementsAreArrayMatcher { // 'negation' is false; otherwise returns the description of the // negation of the matcher. 'param_values' contains a list of strings // that are the print-out of the matcher's parameters. -string FormatMatcherDescription(bool negation, const char* matcher_name, - const Strings& param_values); +GTEST_API_ string FormatMatcherDescription(bool negation, + const char* matcher_name, + const Strings& param_values); } // namespace internal diff --git a/include/gmock/gmock-spec-builders.h b/include/gmock/gmock-spec-builders.h index 400d4d71..66a36e8a 100644 --- a/include/gmock/gmock-spec-builders.h +++ b/include/gmock/gmock-spec-builders.h @@ -111,7 +111,7 @@ template class FunctionMockerBase; // expectations when InSequence() is used, and thus affect which // expectation gets picked. Therefore, we sequence all mock function // calls to ensure the integrity of the mock objects' states. -GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex); +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex); // Untyped base class for ActionResultHolder. class UntypedActionResultHolderBase; @@ -119,7 +119,7 @@ class UntypedActionResultHolderBase; // Abstract base class of FunctionMockerBase. This is the // type-agnostic part of the function mocker interface. Its pure // virtual methods are implemented by FunctionMockerBase. -class UntypedFunctionMockerBase { +class GTEST_API_ UntypedFunctionMockerBase { public: UntypedFunctionMockerBase(); virtual ~UntypedFunctionMockerBase(); @@ -363,7 +363,7 @@ enum CallReaction { } // namespace internal // Utilities for manipulating mock objects. -class Mock { +class GTEST_API_ Mock { public: // The following public methods can be called concurrently. @@ -471,7 +471,7 @@ class Mock { // ExpectationBase available yet, leading to incorrect destruction // in the linked_ptr (or compilation errors if using a checking // linked_ptr). -class Expectation { +class GTEST_API_ Expectation { public: // Constructs a null object that doesn't reference any expectation. Expectation(); @@ -603,7 +603,7 @@ class ExpectationSet { // Sequence objects are used by a user to specify the relative order // in which the expectations should match. They are copyable (we rely // on the compiler-defined copy constructor and assignment operator). -class Sequence { +class GTEST_API_ Sequence { public: // Constructs an empty sequence. Sequence() : last_expectation_(new Expectation) {} @@ -644,7 +644,7 @@ class Sequence { // thread. However, for clarity of your tests we recommend you to set // up mocks in the main thread unless you have a good reason not to do // so. -class InSequence { +class GTEST_API_ InSequence { public: InSequence(); ~InSequence(); @@ -658,7 +658,7 @@ namespace internal { // Points to the implicit sequence introduced by a living InSequence // object (if any) in the current thread or NULL. -extern ThreadLocal g_gmock_implicit_sequence; +GTEST_API_ extern ThreadLocal g_gmock_implicit_sequence; // Base class for implementing expectations. // @@ -674,7 +674,7 @@ extern ThreadLocal g_gmock_implicit_sequence; // on the template argument of Expectation to the base class. // // This class is internal and mustn't be used by user code directly. -class ExpectationBase { +class GTEST_API_ ExpectationBase { public: // source_text is the EXPECT_CALL(...) source that created this Expectation. ExpectationBase(const char* file, int line, const string& source_text); @@ -1222,9 +1222,9 @@ class TypedExpectation : public ExpectationBase { // ::testing::internal and import it into ::testing. // Logs a message including file and line number information. -void LogWithLocation(testing::internal::LogSeverity severity, - const char* file, int line, - const string& message); +GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, + const char* file, int line, + const string& message); template class MockSpec { diff --git a/include/gmock/gmock.h b/include/gmock/gmock.h index ba9fa286..481e5706 100644 --- a/include/gmock/gmock.h +++ b/include/gmock/gmock.h @@ -82,11 +82,11 @@ GMOCK_DECLARE_string_(verbose); // Since Google Test is needed for Google Mock to work, this function // also initializes Google Test and parses its flags, if that hasn't // been done. -void InitGoogleMock(int* argc, char** argv); +GTEST_API_ void InitGoogleMock(int* argc, char** argv); // This overloaded version can be used in Windows programs compiled in // UNICODE mode. -void InitGoogleMock(int* argc, wchar_t** argv); +GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); } // namespace testing diff --git a/include/gmock/internal/gmock-internal-utils.h b/include/gmock/internal/gmock-internal-utils.h index f0fd8682..34131ef6 100644 --- a/include/gmock/internal/gmock-internal-utils.h +++ b/include/gmock/internal/gmock-internal-utils.h @@ -53,7 +53,7 @@ namespace internal { // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // treated as one word. For example, both "FooBar123" and // "foo_bar_123" are converted to "foo bar 123". -string ConvertIdentifierNameToWords(const char* id_name); +GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name); // PointeeOf::type is the type of a value pointed to by a // Pointer, which can be either a smart pointer or a raw pointer. The @@ -271,7 +271,7 @@ class FailureReporterInterface { }; // Returns the failure reporter used by Google Mock. -FailureReporterInterface* GetFailureReporter(); +GTEST_API_ FailureReporterInterface* GetFailureReporter(); // Asserts that condition is true; aborts the process with the given // message if condition is false. We cannot use LOG(FATAL) or CHECK() @@ -319,7 +319,7 @@ const char kErrorVerbosity[] = "error"; // Returns true iff a log with the given severity is visible according // to the --gmock_verbose flag. -bool LogIsVisible(LogSeverity severity); +GTEST_API_ bool LogIsVisible(LogSeverity severity); // Prints the given message to stdout iff 'severity' >= the level // specified by the --gmock_verbose flag. If stack_frames_to_skip >= @@ -328,7 +328,9 @@ bool LogIsVisible(LogSeverity severity); // stack_frames_to_skip is treated as 0, since we don't know which // function calls will be inlined by the compiler and need to be // conservative. -void Log(LogSeverity severity, const string& message, int stack_frames_to_skip); +GTEST_API_ void Log(LogSeverity severity, + const string& message, + int stack_frames_to_skip); // TODO(wan@google.com): group all type utilities together. diff --git a/include/gmock/internal/gmock-port.h b/include/gmock/internal/gmock-port.h index 3b9cc479..6a515d87 100644 --- a/include/gmock/internal/gmock-port.h +++ b/include/gmock/internal/gmock-port.h @@ -61,18 +61,18 @@ #define GMOCK_FLAG(name) FLAGS_gmock_##name // Macros for declaring flags. -#define GMOCK_DECLARE_bool_(name) extern bool GMOCK_FLAG(name) +#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) #define GMOCK_DECLARE_int32_(name) \ - extern ::testing::internal::Int32 GMOCK_FLAG(name) + extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) #define GMOCK_DECLARE_string_(name) \ - extern ::testing::internal::String GMOCK_FLAG(name) + extern GTEST_API_ ::testing::internal::String GMOCK_FLAG(name) // Macros for defining flags. #define GMOCK_DEFINE_bool_(name, default_val, doc) \ - bool GMOCK_FLAG(name) = (default_val) + GTEST_API_ bool GMOCK_FLAG(name) = (default_val) #define GMOCK_DEFINE_int32_(name, default_val, doc) \ - ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) + GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) #define GMOCK_DEFINE_string_(name, default_val, doc) \ - ::testing::internal::String GMOCK_FLAG(name) = (default_val) + GTEST_API_ ::testing::internal::String GMOCK_FLAG(name) = (default_val) #endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ diff --git a/src/gmock-cardinalities.cc b/src/gmock-cardinalities.cc index 1a7902b4..274f98a9 100644 --- a/src/gmock-cardinalities.cc +++ b/src/gmock-cardinalities.cc @@ -136,20 +136,20 @@ void Cardinality::DescribeActualCallCountTo(int actual_call_count, } // Creates a cardinality that allows at least n calls. -Cardinality AtLeast(int n) { return Between(n, INT_MAX); } +GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } // Creates a cardinality that allows at most n calls. -Cardinality AtMost(int n) { return Between(0, n); } +GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } // Creates a cardinality that allows any number of calls. -Cardinality AnyNumber() { return AtLeast(0); } +GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } // Creates a cardinality that allows between min and max calls. -Cardinality Between(int min, int max) { +GTEST_API_ Cardinality Between(int min, int max) { return Cardinality(new BetweenCardinalityImpl(min, max)); } // Creates a cardinality that allows exactly n calls. -Cardinality Exactly(int n) { return Between(n, n); } +GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } } // namespace testing diff --git a/src/gmock-internal-utils.cc b/src/gmock-internal-utils.cc index dd38132a..470fc447 100644 --- a/src/gmock-internal-utils.cc +++ b/src/gmock-internal-utils.cc @@ -51,7 +51,7 @@ namespace internal { // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // treated as one word. For example, both "FooBar123" and // "foo_bar_123" are converted to "foo bar 123". -string ConvertIdentifierNameToWords(const char* id_name) { +GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { string result; char prev_char = '\0'; for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { @@ -91,7 +91,7 @@ class GoogleTestFailureReporter : public FailureReporterInterface { // Returns the global failure reporter. Will create a // GoogleTestFailureReporter and return it the first time called. -FailureReporterInterface* GetFailureReporter() { +GTEST_API_ FailureReporterInterface* GetFailureReporter() { // Points to the global failure reporter used by Google Mock. gcc // guarantees that the following use of failure_reporter is // thread-safe. We may need to add additional synchronization to @@ -107,7 +107,7 @@ static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); // Returns true iff a log with the given severity is visible according // to the --gmock_verbose flag. -bool LogIsVisible(LogSeverity severity) { +GTEST_API_ bool LogIsVisible(LogSeverity severity) { if (GMOCK_FLAG(verbose) == kInfoVerbosity) { // Always show the log if --gmock_verbose=info. return true; @@ -128,8 +128,9 @@ bool LogIsVisible(LogSeverity severity) { // stack_frames_to_skip is treated as 0, since we don't know which // function calls will be inlined by the compiler and need to be // conservative. -void Log(LogSeverity severity, const string& message, - int stack_frames_to_skip) { +GTEST_API_ void Log(LogSeverity severity, + const string& message, + int stack_frames_to_skip) { if (!LogIsVisible(severity)) return; diff --git a/src/gmock-matchers.cc b/src/gmock-matchers.cc index a5e6824d..63f3859b 100644 --- a/src/gmock-matchers.cc +++ b/src/gmock-matchers.cc @@ -67,7 +67,7 @@ namespace internal { // Joins a vector of strings as if they are fields of a tuple; returns // the joined string. -string JoinAsTuple(const Strings& fields) { +GTEST_API_ string JoinAsTuple(const Strings& fields) { switch (fields.size()) { case 0: return ""; @@ -89,8 +89,9 @@ string JoinAsTuple(const Strings& fields) { // 'negation' is false; otherwise returns the description of the // negation of the matcher. 'param_values' contains a list of strings // that are the print-out of the matcher's parameters. -string FormatMatcherDescription(bool negation, const char* matcher_name, - const Strings& param_values) { +GTEST_API_ string FormatMatcherDescription(bool negation, + const char* matcher_name, + const Strings& param_values) { string result = ConvertIdentifierNameToWords(matcher_name); if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values); diff --git a/src/gmock-spec-builders.cc b/src/gmock-spec-builders.cc index aa33cc44..c192f96c 100644 --- a/src/gmock-spec-builders.cc +++ b/src/gmock-spec-builders.cc @@ -53,12 +53,12 @@ namespace internal { // Protects the mock object registry (in class Mock), all function // mockers, and all expectations. -GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); // Logs a message including file and line number information. -void LogWithLocation(testing::internal::LogSeverity severity, - const char* file, int line, - const string& message) { +GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, + const char* file, int line, + const string& message) { ::std::ostringstream s; s << file << ":" << line << ": " << message << ::std::endl; Log(severity, s.str(), 0); @@ -240,7 +240,7 @@ void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { // Points to the implicit sequence introduced by a living InSequence // object (if any) in the current thread or NULL. -ThreadLocal g_gmock_implicit_sequence; +GTEST_API_ ThreadLocal g_gmock_implicit_sequence; // Reports an uninteresting call (whose description is in msg) in the // manner specified by 'reaction'. diff --git a/src/gmock.cc b/src/gmock.cc index 700bcb2e..e06acc5c 100644 --- a/src/gmock.cc +++ b/src/gmock.cc @@ -169,13 +169,13 @@ void InitGoogleMockImpl(int* argc, CharType** argv) { // Since Google Test is needed for Google Mock to work, this function // also initializes Google Test and parses its flags, if that hasn't // been done. -void InitGoogleMock(int* argc, char** argv) { +GTEST_API_ void InitGoogleMock(int* argc, char** argv) { internal::InitGoogleMockImpl(argc, argv); } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. -void InitGoogleMock(int* argc, wchar_t** argv) { +GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) { internal::InitGoogleMockImpl(argc, argv); } diff --git a/src/gmock_main.cc b/src/gmock_main.cc index 9d8aea22..bd5be03b 100644 --- a/src/gmock_main.cc +++ b/src/gmock_main.cc @@ -41,9 +41,9 @@ #if GTEST_OS_WINDOWS_MOBILE # include // NOLINT -int _tmain(int argc, TCHAR** argv) { +GTEST_API_ int _tmain(int argc, TCHAR** argv) { #else -int main(int argc, char** argv) { +GTEST_API_ int main(int argc, char** argv) { #endif // GTEST_OS_WINDOWS_MOBILE std::cout << "Running main() from gmock_main.cc\n"; // Since Google Mock depends on Google Test, InitGoogleMock() is diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc index 9ad62c47..8f96efc2 100644 --- a/test/gmock-matchers_test.cc +++ b/test/gmock-matchers_test.cc @@ -52,7 +52,7 @@ namespace testing { namespace internal { -string JoinAsTuple(const Strings& fields); +GTEST_API_ string JoinAsTuple(const Strings& fields); } // namespace internal namespace gmock_matchers_test {