diff --git a/CMakeLists.txt b/CMakeLists.txt index 561b50dc..01fff601 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,13 @@ cmake_minimum_required(VERSION 3.1) +if(NOT CMAKE_VERSION VERSION_LESS "3.3") + # Don't ignore visibility related properties for non-SHARED targets + cmake_policy(SET CMP0063 NEW) +endif() + project(Cucumber-Cpp) +option(BUILD_SHARED_LIBS "Generate shared libraries" OFF) option(CUKE_USE_STATIC_BOOST "Statically link Boost (except boost::test)" ${WIN32}) option(CUKE_USE_STATIC_GTEST "Statically link Google Test" ON) option(CUKE_DISABLE_BOOST_TEST "Disable boost:test" OFF) @@ -311,6 +317,8 @@ else() ${ARGN} ${CUKE_FEATURES_DIR} ${USES_TERMINAL} + # Execute in same directory as where DLLs appear on Windows + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src ) endfunction(add_feature_target) diff --git a/appveyor.yml b/appveyor.yml index 443d315d..0d1ce95e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -41,7 +41,7 @@ install: build_script: - cmake -E make_directory build -- cmake -E chdir build cmake -G "%CMAKE_GENERATOR%" -DCUKE_ENABLE_EXAMPLES=ON -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_INCLUDEDIR="%BOOST_INCLUDEDIR%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DCMAKE_PREFIX_PATH="%QT_DIR%" .. +- cmake -E chdir build cmake -G "%CMAKE_GENERATOR%" -DCUKE_ENABLE_EXAMPLES=ON -DBUILD_SHARED_LIBS=ON -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_INCLUDEDIR="%BOOST_INCLUDEDIR%" -DBOOST_LIBRARYDIR="%BOOST_LIBRARYDIR%" -DCMAKE_PREFIX_PATH="%QT_DIR%" .. - cmake --build build test_script: diff --git a/cmake/modules/FindGMock.cmake b/cmake/modules/FindGMock.cmake index 4ca15de0..8d732424 100644 --- a/cmake/modules/FindGMock.cmake +++ b/cmake/modules/FindGMock.cmake @@ -260,6 +260,15 @@ if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) if(GTEST_USE_STATIC_LIBS) set(GTEST_CMAKE_ARGS -Dgtest_force_shared_crt:BOOL=ON -DBUILD_SHARED_LIBS=OFF) + if(BUILD_SHARED_LIBS) + list(APPEND GTEST_CMAKE_ARGS + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -Dgtest_hide_internal_symbols=ON + -DCMAKE_CXX_VISIBILITY_PRESET=hidden + -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON + -DCMAKE_POLICY_DEFAULT_CMP0063=NEW + ) + endif() set(GTEST_LIBRARY_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) else() set(GTEST_CMAKE_ARGS -DBUILD_SHARED_LIBS=ON) diff --git a/examples/Calc/CMakeLists.txt b/examples/Calc/CMakeLists.txt index 3641aec6..14f85f53 100644 --- a/examples/Calc/CMakeLists.txt +++ b/examples/Calc/CMakeLists.txt @@ -1,6 +1,6 @@ project(Calc) -add_library(Calc src/Calculator) +add_library(Calc STATIC src/Calculator) target_include_directories(Calc INTERFACE src) if(TARGET GTest::GTest) diff --git a/examples/CalcQt/CMakeLists.txt b/examples/CalcQt/CMakeLists.txt index 66139cee..1b3dd1a1 100644 --- a/examples/CalcQt/CMakeLists.txt +++ b/examples/CalcQt/CMakeLists.txt @@ -1,7 +1,7 @@ project(CalcQt) if(TARGET Qt::Core AND TARGET Qt::Gui AND TARGET Qt::Widgets AND TARGET Qt::Test) - add_library(libcalcqt src/CalculatorWidget.cpp src/CalculatorWidget.h) + add_library(libcalcqt STATIC src/CalculatorWidget.cpp src/CalculatorWidget.h) set_target_properties(libcalcqt PROPERTIES AUTOMOC ON) target_include_directories(libcalcqt INTERFACE src) target_link_libraries(libcalcqt diff --git a/include/cucumber-cpp/internal/ContextManager.hpp b/include/cucumber-cpp/internal/ContextManager.hpp index 62633256..154ca48d 100644 --- a/include/cucumber-cpp/internal/ContextManager.hpp +++ b/include/cucumber-cpp/internal/ContextManager.hpp @@ -1,6 +1,8 @@ #ifndef CUKE_CONTEXTMANAGER_HPP_ #define CUKE_CONTEXTMANAGER_HPP_ +#include + #include #include @@ -13,7 +15,7 @@ namespace internal { typedef std::vector > contexts_type; -class ContextManager { +class CUCUMBER_CPP_EXPORT ContextManager { public: void purgeContexts(); template boost::weak_ptr addContext(); diff --git a/include/cucumber-cpp/internal/CukeCommands.hpp b/include/cucumber-cpp/internal/CukeCommands.hpp index 7721d056..994bba2d 100644 --- a/include/cucumber-cpp/internal/CukeCommands.hpp +++ b/include/cucumber-cpp/internal/CukeCommands.hpp @@ -2,6 +2,7 @@ #define CUKE_CUKECOMMANDS_HPP_ #include "ContextManager.hpp" +#include #include "Scenario.hpp" #include "Table.hpp" #include "step/StepManager.hpp" @@ -20,7 +21,7 @@ using boost::shared_ptr; /** * Legacy class to be removed when feature #31 is complete, substituted by CukeEngineImpl. */ -class CukeCommands { +class CUCUMBER_CPP_EXPORT CukeCommands { public: CukeCommands(); virtual ~CukeCommands(); diff --git a/include/cucumber-cpp/internal/CukeEngine.hpp b/include/cucumber-cpp/internal/CukeEngine.hpp index dc9b971e..9f5fa7f2 100644 --- a/include/cucumber-cpp/internal/CukeEngine.hpp +++ b/include/cucumber-cpp/internal/CukeEngine.hpp @@ -7,16 +7,18 @@ #include +#include + namespace cucumber { namespace internal { -class StepMatchArg { +class CUCUMBER_CPP_EXPORT StepMatchArg { public: std::string value; std::ptrdiff_t position; }; -class StepMatch { +class CUCUMBER_CPP_EXPORT StepMatch { public: std::string id; std::vector args; @@ -24,7 +26,7 @@ class StepMatch { std::string regexp; }; -class InvokeException { +class CUCUMBER_CPP_EXPORT InvokeException { private: const std::string message; @@ -37,7 +39,7 @@ class InvokeException { virtual ~InvokeException() {} }; -class InvokeFailureException : public InvokeException { +class CUCUMBER_CPP_EXPORT InvokeFailureException : public InvokeException { private: const std::string exceptionType; @@ -48,7 +50,7 @@ class InvokeFailureException : public InvokeException { const std::string getExceptionType() const; }; -class PendingStepException : public InvokeException { +class CUCUMBER_CPP_EXPORT PendingStepException : public InvokeException { public: PendingStepException(const std::string & message); PendingStepException(const PendingStepException &rhs); @@ -96,7 +98,8 @@ class CukeEngine { */ virtual std::string snippetText(const std::string & keyword, const std::string & name, const std::string & multilineArgClass) const = 0; - virtual ~CukeEngine() {} + CUCUMBER_CPP_EXPORT CukeEngine(); + CUCUMBER_CPP_EXPORT virtual ~CukeEngine(); }; } diff --git a/include/cucumber-cpp/internal/CukeEngineImpl.hpp b/include/cucumber-cpp/internal/CukeEngineImpl.hpp index aaa67a9b..c53f736d 100644 --- a/include/cucumber-cpp/internal/CukeEngineImpl.hpp +++ b/include/cucumber-cpp/internal/CukeEngineImpl.hpp @@ -2,6 +2,7 @@ #define CUKE_CUKEENGINE_IMPL_HPP_ #include "CukeEngine.hpp" +#include #include "CukeCommands.hpp" namespace cucumber { @@ -13,7 +14,7 @@ namespace internal { * Currently it is a wrapper around CukeCommands. It will have its own * implementation when feature #31 is complete. */ -class CukeEngineImpl : public CukeEngine { +class CUCUMBER_CPP_EXPORT CukeEngineImpl : public CukeEngine { private: CukeCommands cukeCommands; diff --git a/include/cucumber-cpp/internal/Table.hpp b/include/cucumber-cpp/internal/Table.hpp index 9f6e9600..a7a70bdb 100644 --- a/include/cucumber-cpp/internal/Table.hpp +++ b/include/cucumber-cpp/internal/Table.hpp @@ -1,6 +1,8 @@ #ifndef CUKE_TABLE_HPP_ #define CUKE_TABLE_HPP_ +#include + #include #include #include @@ -9,7 +11,7 @@ namespace cucumber { namespace internal { -class Table { +class CUCUMBER_CPP_EXPORT Table { private: typedef std::vector basic_type; public: diff --git a/include/cucumber-cpp/internal/connectors/wire/WireProtocol.hpp b/include/cucumber-cpp/internal/connectors/wire/WireProtocol.hpp index 6432d297..9aec4d4e 100644 --- a/include/cucumber-cpp/internal/connectors/wire/WireProtocol.hpp +++ b/include/cucumber-cpp/internal/connectors/wire/WireProtocol.hpp @@ -1,8 +1,10 @@ #ifndef CUKE_WIREPROTOCOL_HPP_ #define CUKE_WIREPROTOCOL_HPP_ +#include #include "ProtocolHandler.hpp" #include "../../CukeEngine.hpp" + #include namespace cucumber { @@ -14,7 +16,7 @@ namespace internal { class WireResponseVisitor; -class WireResponse { +class CUCUMBER_CPP_EXPORT WireResponse { public: WireResponse() {}; @@ -23,12 +25,12 @@ class WireResponse { virtual ~WireResponse() {}; }; -class SuccessResponse : public WireResponse { +class CUCUMBER_CPP_EXPORT SuccessResponse : public WireResponse { public: void accept(WireResponseVisitor& visitor) const; }; -class FailureResponse : public WireResponse { +class CUCUMBER_CPP_EXPORT FailureResponse : public WireResponse { private: const std::string message, exceptionType; @@ -41,7 +43,7 @@ class FailureResponse : public WireResponse { void accept(WireResponseVisitor& visitor) const; }; -class PendingResponse : public WireResponse { +class CUCUMBER_CPP_EXPORT PendingResponse : public WireResponse { private: const std::string message; @@ -53,7 +55,7 @@ class PendingResponse : public WireResponse { void accept(WireResponseVisitor& visitor) const; }; -class StepMatchesResponse : public WireResponse { +class CUCUMBER_CPP_EXPORT StepMatchesResponse : public WireResponse { private: const std::vector matchingSteps; @@ -64,7 +66,7 @@ class StepMatchesResponse : public WireResponse { void accept(WireResponseVisitor& visitor) const; }; -class SnippetTextResponse : public WireResponse { +class CUCUMBER_CPP_EXPORT SnippetTextResponse : public WireResponse { private: const std::string stepSnippet; @@ -76,7 +78,7 @@ class SnippetTextResponse : public WireResponse { void accept(WireResponseVisitor& visitor) const; }; -class WireResponseVisitor { +class CUCUMBER_CPP_EXPORT WireResponseVisitor { public: virtual void visit(const SuccessResponse& response) = 0; virtual void visit(const FailureResponse& response) = 0; @@ -91,7 +93,7 @@ class WireResponseVisitor { /** * Wire protocol request command. */ -class WireCommand { +class CUCUMBER_CPP_EXPORT WireCommand { public: /** * Runs the command on the provided engine @@ -105,7 +107,7 @@ class WireCommand { virtual ~WireCommand() {}; }; -class WireMessageCodecException : public std::exception { +class CUCUMBER_CPP_EXPORT WireMessageCodecException : public std::exception { private: const char *description; @@ -123,7 +125,7 @@ class WireMessageCodecException : public std::exception { /** * Transforms wire messages into commands and responses to messages. */ -class WireMessageCodec { +class CUCUMBER_CPP_EXPORT WireMessageCodec { public: /** * Decodes a wire message into a command. @@ -151,7 +153,7 @@ class WireMessageCodec { /** * WireMessageCodec implementation with JsonSpirit. */ -class JsonSpiritWireMessageCodec : public WireMessageCodec { +class CUCUMBER_CPP_EXPORT JsonSpiritWireMessageCodec : public WireMessageCodec { public: JsonSpiritWireMessageCodec(); boost::shared_ptr decode(const std::string &request) const; @@ -162,7 +164,7 @@ class JsonSpiritWireMessageCodec : public WireMessageCodec { * Wire protocol handler, delegating JSON encoding and decoding to a * codec object and running commands on a provided engine instance. */ -class WireProtocolHandler : public ProtocolHandler { +class CUCUMBER_CPP_EXPORT WireProtocolHandler : public ProtocolHandler { private: const WireMessageCodec& codec; CukeEngine& engine; diff --git a/include/cucumber-cpp/internal/connectors/wire/WireServer.hpp b/include/cucumber-cpp/internal/connectors/wire/WireServer.hpp index 5bbbdfbe..78b32c9c 100644 --- a/include/cucumber-cpp/internal/connectors/wire/WireServer.hpp +++ b/include/cucumber-cpp/internal/connectors/wire/WireServer.hpp @@ -1,6 +1,7 @@ #ifndef CUKE_WIRESERVER_HPP_ #define CUKE_WIRESERVER_HPP_ +#include #include "ProtocolHandler.hpp" #include @@ -13,7 +14,7 @@ namespace internal { /** * Socket server that calls a protocol handler line by line */ -class SocketServer { +class CUCUMBER_CPP_EXPORT SocketServer { public: /** * Constructor for DI @@ -49,7 +50,7 @@ class SocketServer { /** * Socket server that calls a protocol handler line by line */ -class TCPSocketServer : public SocketServer { +class CUCUMBER_CPP_EXPORT TCPSocketServer : public SocketServer { public: /** * Type definition for TCP port @@ -90,7 +91,7 @@ class TCPSocketServer : public SocketServer { /** * Socket server that calls a protocol handler line by line */ -class UnixSocketServer : public SocketServer { +class CUCUMBER_CPP_EXPORT UnixSocketServer : public SocketServer { public: /** * Constructor for DI diff --git a/include/cucumber-cpp/internal/drivers/BoostDriver.hpp b/include/cucumber-cpp/internal/drivers/BoostDriver.hpp index 387a4427..8482ebcc 100644 --- a/include/cucumber-cpp/internal/drivers/BoostDriver.hpp +++ b/include/cucumber-cpp/internal/drivers/BoostDriver.hpp @@ -2,13 +2,14 @@ #define CUKE_BOOSTDRIVER_HPP_ #include "../step/StepManager.hpp" +#include namespace cucumber { namespace internal { class CukeBoostLogInterceptor; -class BoostStep : public BasicStep { +class CUCUMBER_CPP_EXPORT BoostStep : public BasicStep { protected: const InvokeResult invokeStepBody(); diff --git a/include/cucumber-cpp/internal/drivers/GTestDriver.hpp b/include/cucumber-cpp/internal/drivers/GTestDriver.hpp index 926c63ba..7b4a3f24 100644 --- a/include/cucumber-cpp/internal/drivers/GTestDriver.hpp +++ b/include/cucumber-cpp/internal/drivers/GTestDriver.hpp @@ -1,6 +1,7 @@ #ifndef CUKE_GTESTDRIVER_HPP_ #define CUKE_GTESTDRIVER_HPP_ +#include #include "../step/StepManager.hpp" #include @@ -8,7 +9,7 @@ namespace cucumber { namespace internal { -class GTestStep : public BasicStep { +class CUCUMBER_CPP_EXPORT GTestStep : public BasicStep { protected: const InvokeResult invokeStepBody(); diff --git a/include/cucumber-cpp/internal/drivers/GenericDriver.hpp b/include/cucumber-cpp/internal/drivers/GenericDriver.hpp index 32e99283..e7fc7e20 100644 --- a/include/cucumber-cpp/internal/drivers/GenericDriver.hpp +++ b/include/cucumber-cpp/internal/drivers/GenericDriver.hpp @@ -2,11 +2,12 @@ #define CUKE_GENERICDRIVER_HPP_ #include "../step/StepManager.hpp" +#include namespace cucumber { namespace internal { -class GenericStep : public BasicStep { +class CUCUMBER_CPP_EXPORT GenericStep : public BasicStep { protected: virtual const InvokeResult invokeStepBody(); }; diff --git a/include/cucumber-cpp/internal/drivers/QtTestDriver.hpp b/include/cucumber-cpp/internal/drivers/QtTestDriver.hpp index 94e3ab22..ca433a7c 100644 --- a/include/cucumber-cpp/internal/drivers/QtTestDriver.hpp +++ b/include/cucumber-cpp/internal/drivers/QtTestDriver.hpp @@ -2,12 +2,13 @@ #define CUKE_QTTESTDRIVER_HPP_ #include "../step/StepManager.hpp" +#include #include namespace cucumber { namespace internal { -class QtTestStep : public BasicStep { +class CUCUMBER_CPP_EXPORT QtTestStep : public BasicStep { friend class QtTestObject; public: diff --git a/include/cucumber-cpp/internal/hook/HookRegistrar.hpp b/include/cucumber-cpp/internal/hook/HookRegistrar.hpp index c065da87..61d6a605 100644 --- a/include/cucumber-cpp/internal/hook/HookRegistrar.hpp +++ b/include/cucumber-cpp/internal/hook/HookRegistrar.hpp @@ -1,6 +1,7 @@ #ifndef CUKE_HOOKREGISTRAR_HPP_ #define CUKE_HOOKREGISTRAR_HPP_ +#include #include "Tag.hpp" #include "../Scenario.hpp" #include "../step/StepManager.hpp" @@ -14,12 +15,12 @@ namespace cucumber { namespace internal { -class CallableStep { +class CUCUMBER_CPP_EXPORT CallableStep { public: virtual void call() = 0; }; -class Hook { +class CUCUMBER_CPP_EXPORT Hook { public: void setTags(const std::string &csvTagNotation); virtual void invokeHook(Scenario *scenario, CallableStep *step); @@ -36,10 +37,9 @@ class Hook { AndTagExpression tagExpression; }; -class BeforeHook : public Hook { -}; +class CUCUMBER_CPP_EXPORT BeforeHook : public Hook {}; -class AroundStepHook : public Hook { +class CUCUMBER_CPP_EXPORT AroundStepHook : public Hook { public: virtual void invokeHook(Scenario *scenario, CallableStep *step); virtual void skipHook(); @@ -47,24 +47,20 @@ class AroundStepHook : public Hook { CallableStep *step; }; -class AfterStepHook : public Hook { -}; +class CUCUMBER_CPP_EXPORT AfterStepHook : public Hook {}; -class AfterHook : public Hook { -}; +class CUCUMBER_CPP_EXPORT AfterHook : public Hook {}; -class UnconditionalHook : public Hook { +class CUCUMBER_CPP_EXPORT UnconditionalHook : public Hook { public: virtual void invokeHook(Scenario *scenario, CallableStep *step); }; -class BeforeAllHook : public UnconditionalHook { -}; +class CUCUMBER_CPP_EXPORT BeforeAllHook : public UnconditionalHook {}; -class AfterAllHook : public UnconditionalHook { -}; +class CUCUMBER_CPP_EXPORT AfterAllHook : public UnconditionalHook {}; -class HookRegistrar { +class CUCUMBER_CPP_EXPORT HookRegistrar { public: typedef std::list< boost::shared_ptr > hook_list_type; typedef std::list< boost::shared_ptr > aroundhook_list_type; @@ -107,8 +103,7 @@ class HookRegistrar { ; }; - -class StepCallChain { +class CUCUMBER_CPP_EXPORT StepCallChain { public: StepCallChain(Scenario *scenario, const StepInfo* stepInfo, const InvokeArgs *pStepArgs, HookRegistrar::aroundhook_list_type &aroundHooks); InvokeResult exec(); @@ -125,7 +120,7 @@ class StepCallChain { InvokeResult result; }; -class CallableStepChain : public CallableStep { +class CUCUMBER_CPP_EXPORT CallableStepChain : public CallableStep { public: CallableStepChain(StepCallChain *scc); void call(); diff --git a/include/cucumber-cpp/internal/hook/Tag.hpp b/include/cucumber-cpp/internal/hook/Tag.hpp index d74da418..d0855ac0 100644 --- a/include/cucumber-cpp/internal/hook/Tag.hpp +++ b/include/cucumber-cpp/internal/hook/Tag.hpp @@ -4,12 +4,13 @@ #include #include +#include #include "../utils/Regex.hpp" namespace cucumber { namespace internal { -class TagExpression { +class CUCUMBER_CPP_EXPORT TagExpression { public: typedef std::vector tag_list; @@ -17,7 +18,7 @@ class TagExpression { virtual bool matches(const tag_list &tags) const = 0; }; -class OrTagExpression : public TagExpression { +class CUCUMBER_CPP_EXPORT OrTagExpression : public TagExpression { public: OrTagExpression(const std::string &csvTagNotation); bool matches(const tag_list &tags) const; @@ -30,7 +31,7 @@ class OrTagExpression : public TagExpression { static Regex & csvTagNotationRegex(); }; -class AndTagExpression : public TagExpression { +class CUCUMBER_CPP_EXPORT AndTagExpression : public TagExpression { public: AndTagExpression(); AndTagExpression(const std::string &csvTagNotation); diff --git a/include/cucumber-cpp/internal/step/StepManager.hpp b/include/cucumber-cpp/internal/step/StepManager.hpp index b93a7c6f..457ee899 100644 --- a/include/cucumber-cpp/internal/step/StepManager.hpp +++ b/include/cucumber-cpp/internal/step/StepManager.hpp @@ -16,6 +16,7 @@ #include #endif +#include #include "../Table.hpp" #include "../utils/IndexSequence.hpp" #include "../utils/Regex.hpp" @@ -27,7 +28,7 @@ typedef unsigned int step_id_type; class StepInfo; -class SingleStepMatch { +class CUCUMBER_CPP_EXPORT SingleStepMatch { public: typedef RegexMatch::submatches_type submatches_type; @@ -37,8 +38,7 @@ class SingleStepMatch { submatches_type submatches; }; - -class MatchResult { +class CUCUMBER_CPP_EXPORT MatchResult { public: typedef std::vector match_results_type; @@ -54,8 +54,7 @@ class MatchResult { match_results_type resultSet; }; - -class InvokeArgs { +class CUCUMBER_CPP_EXPORT InvokeArgs { typedef std::vector args_type; public: typedef args_type::size_type size_type; @@ -78,7 +77,7 @@ enum InvokeResultType { PENDING }; -class InvokeResult { +class CUCUMBER_CPP_EXPORT InvokeResult { private: InvokeResultType type; std::string description; @@ -100,8 +99,7 @@ class InvokeResult { const std::string &getDescription() const; }; - -class StepInfo : public boost::enable_shared_from_this { +class CUCUMBER_CPP_EXPORT StepInfo : public boost::enable_shared_from_this { public: StepInfo(const std::string &stepMatcher, const std::string source); SingleStepMatch matches(const std::string &stepDescription) const; @@ -115,8 +113,7 @@ class StepInfo : public boost::enable_shared_from_this { StepInfo& operator=(const StepInfo& other); }; - -class BasicStep { +class CUCUMBER_CPP_EXPORT BasicStep { public: InvokeResult invoke(const InvokeArgs *pArgs); @@ -174,8 +171,7 @@ class StepInvoker : public StepInfo { InvokeResult invokeStep(const InvokeArgs *args) const; }; - -class StepManager { +class CUCUMBER_CPP_EXPORT StepManager { protected: typedef std::map > steps_type; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4691cb2f..8b842654 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,5 @@ +include(GenerateExportHeader) + set(CUKE_SOURCES drivers/GenericDriver.cpp ContextManager.cpp @@ -23,6 +25,7 @@ endif() if(TARGET Boost::unit_test_framework) list(APPEND CUKE_EXTRA_PRIVATE_LIBRARIES Boost::unit_test_framework) list(APPEND CUKE_SOURCES drivers/BoostDriver.cpp) + list(APPEND CUKE_DEP_LIBRARIES ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) endif() if(TARGET Qt::Test) @@ -41,14 +44,36 @@ if(CMAKE_EXTRA_GENERATOR OR MSVC_IDE) list(APPEND CUKE_SOURCES ${CUKE_HEADERS}) endif() -add_library(cucumber-cpp-nomain STATIC ${CUKE_SOURCES}) -add_library(cucumber-cpp STATIC ${CUKE_SOURCES} main.cpp) +# Library for unit tests relying on internals +add_library(cucumber-cpp-internal STATIC ${CUKE_SOURCES}) + +add_library(cucumber-cpp-nomain ${CUKE_SOURCES}) +add_library(cucumber-cpp ${CUKE_SOURCES} main.cpp) + +set_target_properties( + cucumber-cpp-internal + cucumber-cpp + cucumber-cpp-nomain + PROPERTIES + DEFINE_SYMBOL cucumber_cpp_EXPORTS + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON +) + +generate_export_header(cucumber-cpp + EXPORT_FILE_NAME "cucumber-cpp/internal/CukeExport.hpp" +) foreach(TARGET + cucumber-cpp-internal cucumber-cpp-nomain cucumber-cpp ) - target_include_directories(${TARGET} PUBLIC ${CMAKE_SOURCE_DIR}/include) + target_include_directories(${TARGET} + PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/include + ) target_link_libraries(${TARGET} PUBLIC Boost::boost @@ -60,6 +85,11 @@ foreach(TARGET json_spirit.header ${CUKE_EXTRA_PRIVATE_LIBRARIES} ) + # Don't export or import symbols for statically linked libraries + get_property(type TARGET ${TARGET} PROPERTY TYPE) + if(NOT "${type}" MATCHES "^(SHARED|MODULE)_LIBRARY$") + target_compile_definitions(${TARGET} PUBLIC CUCUMBER_CPP_STATIC_DEFINE) + endif() if(MINGW) target_link_libraries(${TARGET} PRIVATE diff --git a/src/CukeEngine.cpp b/src/CukeEngine.cpp index b9b52d7f..6d021f2d 100644 --- a/src/CukeEngine.cpp +++ b/src/CukeEngine.cpp @@ -39,5 +39,8 @@ PendingStepException::PendingStepException(const PendingStepException &rhs) : InvokeException(rhs) { } +CukeEngine::CukeEngine() {} + +CukeEngine::~CukeEngine() {} } } diff --git a/src/main.cpp b/src/main.cpp index 35af8308..226696e8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -39,7 +40,7 @@ void acceptWireProtocol(const std::string& host, int port, const std::string& un } -int main(int argc, char **argv) { +int CUCUMBER_CPP_EXPORT main(int argc, char** argv) { using boost::program_options::value; boost::program_options::options_description optionDescription("Allowed options"); optionDescription.add_options() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a51e736e..f1335081 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ function(cuke_add_driver_test TEST_FILE) get_filename_component(TEST_NAME ${TEST_FILE} NAME) message(STATUS "Adding " ${TEST_NAME}) add_executable(${TEST_NAME} ${TEST_FILE}.cpp) - target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-nomain ${ARGN}) + target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-internal ${ARGN}) add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME}) endfunction() @@ -11,7 +11,7 @@ if(TARGET GMock::Main) get_filename_component(TEST_NAME ${TEST_FILE} NAME) message(STATUS "Adding " ${TEST_NAME}) add_executable(${TEST_NAME} ${TEST_FILE}.cpp) - target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-nomain ${ARGN} GMock::Main) + target_link_libraries(${TEST_NAME} PRIVATE cucumber-cpp-internal ${ARGN} GMock::Main) gtest_add_tests(${TEST_NAME} "" ${TEST_FILE}.cpp) # Run all tests in executable at once too. This ensures that the used fixtures get tested # properly too. Additionally gather the output in jUnit compatible output for CI. diff --git a/travis.sh b/travis.sh index cc139602..840bf7f4 100755 --- a/travis.sh +++ b/travis.sh @@ -57,6 +57,7 @@ cmake -E make_directory build cmake -E chdir build cmake \ -G Ninja \ -DCUKE_ENABLE_EXAMPLES=on \ + -DBUILD_SHARED_LIBS=ON \ ${CMAKE_PREFIX_PATH:+"-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"} \ ${COVERALLS_SERVICE_NAME:+"-DCMAKE_BUILD_TYPE=Debug"} \ ${COVERALLS_SERVICE_NAME:+"-DCMAKE_CXX_FLAGS='--coverage'"} \