Skip to content

Commit

Permalink
Merge pull request #275 from ursfassler/less-boost
Browse files Browse the repository at this point in the history
Remove dependency to Boost
  • Loading branch information
ursfassler authored Dec 30, 2023
2 parents bcdf7d3 + d131ae3 commit 4d47d6c
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 285 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/run-all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
g++ \
gcovr \
git \
libboost-program-options-dev \
libboost-system-dev \
libasio-dev \
libboost-test-dev \
libtclap-dev \
make \
ninja-build \
nlohmann-json3-dev \
Expand Down
61 changes: 1 addition & 60 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ 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_ENABLE_BOOST_TEST "Enable Boost.Test framework" ON)
option(CUKE_ENABLE_EXAMPLES "Build examples" OFF)
Expand Down Expand Up @@ -111,69 +110,11 @@ endif()
# Boost
#

if(MSVC11)
# Boost 1.51 fixed a bug with MSVC11
message(STATUS "Forcing Boost 1.51+ on MSVC11")
set(BOOST_MIN_VERSION "1.51")
else()
set(BOOST_MIN_VERSION "1.46")
endif()

set(Boost_USE_STATIC_RUNTIME OFF)
set(CUKE_CORE_BOOST_LIBS system program_options)
if(CUKE_ENABLE_BOOST_TEST)
# "An external test runner utility is required to link with dynamic library" (Boost User's Guide)
set(Boost_USE_STATIC_LIBS OFF)
set(CMAKE_CXX_FLAGS "-DBOOST_TEST_DYN_LINK ${CMAKE_CXX_FLAGS}")
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS unit_test_framework)
endif()

if(CUKE_USE_STATIC_BOOST)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${CUKE_CORE_BOOST_LIBS} REQUIRED)
else()
set(CMAKE_CXX_FLAGS "-DBOOST_ALL_DYN_LINK ${CMAKE_CXX_FLAGS}")
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${CUKE_CORE_BOOST_LIBS} REQUIRED)
endif()

# Create import targets for CMake versions older than 3.5 (actually older FindBoost.cmake)
if(Boost_USE_STATIC_LIBS)
set(LIBRARY_TYPE STATIC)
else()
# Just because we don't ask for static doesn't mean we're not getting static
set(LIBRARY_TYPE UNKNOWN)
endif()
if(Boost_INCLUDE_DIRS AND NOT TARGET Boost::boost)
add_library(Boost::boost INTERFACE IMPORTED)
set_target_properties(Boost::boost PROPERTIES
"INTERFACE_INCLUDE_DIRECTORIES" "${Boost_INCLUDE_DIRS}")
endif()
if(Boost_SYSTEM_LIBRARY AND NOT TARGET Boost::system)
add_library(Boost::system ${LIBRARY_TYPE} IMPORTED)
set_target_properties(Boost::system PROPERTIES
"IMPORTED_LOCATION" "${Boost_SYSTEM_LIBRARY}"
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
)
if(Boost_USE_STATIC_LIBS)
set_target_properties(Boost::system PROPERTIES
"COMPILE_DEFINITIONS" BOOST_ERROR_CODE_HEADER_ONLY=1
)
endif()
endif()
if(Boost_PROGRAM_OPTIONS_LIBRARY AND NOT TARGET Boost::program_options)
add_library(Boost::program_options ${LIBRARY_TYPE} IMPORTED)
set_target_properties(Boost::program_options PROPERTIES
"IMPORTED_LOCATION" "${Boost_PROGRAM_OPTIONS_LIBRARY}"
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
)
endif()
if(Boost_UNIT_TEST_FRAMEWORK_LIBRARY AND NOT TARGET Boost::unit_test_framework)
add_library(Boost::unit_test_framework ${LIBRARY_TYPE} IMPORTED)
set_target_properties(Boost::unit_test_framework PROPERTIES
"IMPORTED_LOCATION" "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}"
"INTERFACE_LINK_LIBRARIES" "Boost::boost"
)
find_package(Boost 1.70 COMPONENTS unit_test_framework)
endif()

#
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ It relies on a few executables:

It relies on a few libraries:

* [Boost](http://www.boost.org/) 1.46 or later (1.51+ on Windows).
Required libraries: *system* and *program_options*.
Optional library for Boost Test driver: *test*.
* [Asio](https://think-async.com/Asio/) 1.18.1 or later.
* [Boost.Test](http://www.boost.org/) 1.70. Optional for the Boost Test driver.
* [GTest](http://code.google.com/p/googletest/) 1.6 or later.
Optional for the GTest driver. By default downloaded and built by CMake.
* [GMock](http://code.google.com/p/googlemock/) 1.6 or later.
Optional for the internal test suite. By default downloaded and built by CMake.
* [nlohmann-json](https://github.com/nlohmann/json) 3.10.5 or later.
* [Qt 4 or 5](http://qt-project.org/). Optional for the CalcQt example and QtTest driver (only Qt 5).
* [TCLAP](https://tclap.sourceforge.net/) 1.2.5 or later.

It might work with earlier versions of the libraries, but it was not tested with them.
See the [CI scripts](.github/workflows/run-all.yml) for details about dependency installation.
Expand Down
10 changes: 10 additions & 0 deletions cmake/modules/FindAsio.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
find_path(ASIO_INCLUDE_DIR asio.hpp)

if (ASIO_INCLUDE_DIR)
set(ASIO_FOUND TRUE)
else ()
set(ASIO_FOUND FALSE)
endif ()

include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Asio REQUIRED_VARS ASIO_INCLUDE_DIR)
10 changes: 10 additions & 0 deletions cmake/modules/FindTCLAP.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
find_path(TCLAP_INCLUDE_DIR tclap/CmdLine.h)

if (TCLAP_INCLUDE_DIR)
set(TCLAP_FOUND TRUE)
else ()
set(TCLAP_FOUND FALSE)
endif ()

include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCLAP REQUIRED_VARS TCLAP_INCLUDE_DIR)
29 changes: 29 additions & 0 deletions cmake/modules/GitVersion.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
function(git_get_version VERSION_VARIABLE)
find_program(GIT_EXECUTABLE git)

if(NOT GIT_EXECUTABLE)
message(FATAL_ERROR "Git not found. Please install Git and make sure it is in your system's PATH.")
endif()

execute_process(
COMMAND ${GIT_EXECUTABLE} describe --always --dirty
OUTPUT_VARIABLE VERSION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
ERROR_VARIABLE GIT_DESCRIBE_ERROR
RESULT_VARIABLE GIT_DESCRIBE_RESULT
)

if(NOT GIT_DESCRIBE_RESULT EQUAL 0)
message(FATAL_ERROR "Error running 'git describe': ${GIT_DESCRIBE_ERROR}")
endif()

string(LENGTH "${VERSION_STRING}" VERSION_STRING_LENGTH)
string(SUBSTRING "${VERSION_STRING}" 0 1 FIRST_CHARACTER)

if("${FIRST_CHARACTER}" STREQUAL "v")
string(SUBSTRING "${VERSION_STRING}" 1 ${VERSION_STRING_LENGTH} VERSION_STRING)
endif()

set(${VERSION_VARIABLE} ${VERSION_STRING} PARENT_SCOPE)
endfunction()
35 changes: 17 additions & 18 deletions include/cucumber-cpp/internal/RegistrationMacros.hpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
#ifndef CUKE_REGISTRATIONMACROS_HPP_
#define CUKE_REGISTRATIONMACROS_HPP_

#if __cplusplus >= 201103L
#define CUKE_OVERRIDE override
#else
#define CUKE_OVERRIDE
#endif

// ************************************************************************** //
// ************** OBJECT NAMING MACROS ************** //
// ************************************************************************** //

// from https://www.boost.org/doc/libs/1_84_0/boost/config/helper_macros.hpp
#define CUKE_JOIN(X, Y) CUKE_DO_JOIN(X, Y)
#define CUKE_DO_JOIN(X, Y) CUKE_DO_JOIN2(X, Y)
#define CUKE_DO_JOIN2(X, Y) X##Y

#ifndef CUKE_OBJECT_PREFIX
#define CUKE_OBJECT_PREFIX CukeObject
#endif

#ifdef __COUNTER__
#define CUKE_GEN_OBJECT_NAME_ BOOST_JOIN(CUKE_OBJECT_PREFIX, __COUNTER__)
#define CUKE_GEN_OBJECT_NAME_ CUKE_JOIN(CUKE_OBJECT_PREFIX, __COUNTER__)
#else
// Use a counter to be incremented every time cucumber-cpp is included
// in case this does not suffice (possible with multiple files only)
#define CUKE_GEN_OBJECT_NAME_ BOOST_JOIN(CUKE_OBJECT_PREFIX, __LINE__)
#define CUKE_GEN_OBJECT_NAME_ CUKE_JOIN(CUKE_OBJECT_PREFIX, __LINE__)
#endif

// ************************************************************************** //
// ************** CUKE OBJECTS ************** //
// ************************************************************************** //

#define CUKE_OBJECT_(class_name, parent_class, registration_fn, args) \
class class_name : public parent_class { \
public: \
void body() CUKE_OVERRIDE { return invokeWithArgs(*this, &class_name::bodyWithArgs); } \
void bodyWithArgs args; \
\
private: \
static const int cukeRegId; \
}; \
const int class_name ::cukeRegId = registration_fn; \
#define CUKE_OBJECT_(class_name, parent_class, registration_fn, args) \
class class_name : public parent_class { \
public: \
void body() override { return invokeWithArgs(*this, &class_name::bodyWithArgs); } \
void bodyWithArgs args; \
\
private: \
static const int cukeRegId; \
}; \
const int class_name ::cukeRegId = registration_fn; \
void class_name ::bodyWithArgs args /**/

#endif /* CUKE_REGISTRATIONMACROS_HPP_ */
35 changes: 12 additions & 23 deletions include/cucumber-cpp/internal/connectors/wire/WireServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include <string>

#include <boost/asio.hpp>
#include <asio.hpp>

namespace cucumber {
namespace internal {
Expand All @@ -29,25 +29,14 @@ class CUCUMBER_CPP_EXPORT SocketServer {

protected:
const ProtocolHandler* protocolHandler;
boost::asio::io_service ios;
asio::io_service ios;

#if BOOST_VERSION <= 106500
template<typename Protocol, typename Service>
void doListen(
boost::asio::basic_socket_acceptor<Protocol, Service>& acceptor,
const typename Protocol::endpoint& endpoint
);
template<typename Protocol, typename Service>
void doAcceptOnce(boost::asio::basic_socket_acceptor<Protocol, Service>& acceptor);
#else
template<typename Protocol>
void doListen(
boost::asio::basic_socket_acceptor<Protocol>& acceptor,
const typename Protocol::endpoint& endpoint
asio::basic_socket_acceptor<Protocol>& acceptor, const typename Protocol::endpoint& endpoint
);
template<typename Protocol>
void doAcceptOnce(boost::asio::basic_socket_acceptor<Protocol>& acceptor);
#endif
void doAcceptOnce(asio::basic_socket_acceptor<Protocol>& acceptor);
void processStream(std::iostream& stream);
};

Expand All @@ -74,24 +63,24 @@ class CUCUMBER_CPP_EXPORT TCPSocketServer : public SocketServer {
/**
* Bind and listen to a TCP port on the given endpoint
*/
void listen(const boost::asio::ip::tcp::endpoint endpoint);
void listen(const asio::ip::tcp::endpoint endpoint);

/**
* Endpoint (IP address and port number) that this server is currently
* listening on.
*
* @throw boost::system::system_error when not listening on any socket or
* @throw std::system_error when not listening on any socket or
* the endpoint cannot be determined.
*/
boost::asio::ip::tcp::endpoint listenEndpoint() const;
asio::ip::tcp::endpoint listenEndpoint() const;

void acceptOnce() override;

private:
boost::asio::ip::tcp::acceptor acceptor;
asio::ip::tcp::acceptor acceptor;
};

#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
#if defined(ASIO_HAS_LOCAL_SOCKETS)
/**
* Socket server that calls a protocol handler line by line
*/
Expand All @@ -110,17 +99,17 @@ class CUCUMBER_CPP_EXPORT UnixSocketServer : public SocketServer {
/**
* Port number that this server is currently listening on.
*
* @throw boost::system::system_error when not listening on any socket or
* @throw std::system_error when not listening on any socket or
* the endpoint cannot be determined.
*/
boost::asio::local::stream_protocol::endpoint listenEndpoint() const;
asio::local::stream_protocol::endpoint listenEndpoint() const;

void acceptOnce() override;

~UnixSocketServer() override;

private:
boost::asio::local::stream_protocol::acceptor acceptor;
asio::local::stream_protocol::acceptor acceptor;
};
#endif

Expand Down
8 changes: 1 addition & 7 deletions include/cucumber-cpp/internal/hook/HookRegistrar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
#include "../Scenario.hpp"
#include "../step/StepManager.hpp"

#include <boost/config.hpp>
#include <memory>

#include <list>

namespace cucumber {
Expand Down Expand Up @@ -102,11 +100,7 @@ class CUCUMBER_CPP_EXPORT HookRegistrar {

private:
// We're a singleton so don't allow instances
HookRegistrar()
#ifndef BOOST_NO_DELETED_FUNCTIONS
= delete
#endif
;
HookRegistrar() = delete;
};

class CUCUMBER_CPP_EXPORT StepCallChain {
Expand Down
26 changes: 3 additions & 23 deletions include/cucumber-cpp/internal/step/StepManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@
#include <stdexcept>
#include <string>
#include <vector>

#include <boost/config.hpp>
#include <memory>

#ifndef BOOST_NO_VARIADIC_TEMPLATES
#include <type_traits>
#endif
#include <type_traits>

#include <cucumber-cpp/internal/CukeExport.hpp>
#include "../Table.hpp"
Expand Down Expand Up @@ -43,10 +38,7 @@ class CUCUMBER_CPP_EXPORT MatchResult {
const match_results_type& getResultSet();
void addMatch(SingleStepMatch match);

#ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
explicit
#endif
operator bool() const;
explicit operator bool() const;

private:
match_results_type resultSet;
Expand Down Expand Up @@ -139,13 +131,6 @@ class CUCUMBER_CPP_EXPORT BasicStep {
const T getInvokeArg();
const InvokeArgs* getArgs();

#ifdef BOOST_NO_VARIADIC_TEMPLATES
// Special case for zero arguments, only thing we bother to support on C++98
template<typename Derived, typename R>
static R invokeWithArgs(Derived& that, R (Derived::*f)()) {
return (that.*f)();
}
#else
template<typename Derived, typename R, typename... Args, std::size_t... N>
static R invokeWithIndexedArgs(Derived& that, R (Derived::*f)(Args...), index_sequence<N...>) {
return (that.*f)(that.pArgs->template getInvokeArg<typename std::decay<Args>::type>(N)...);
Expand All @@ -156,7 +141,6 @@ class CUCUMBER_CPP_EXPORT BasicStep {
that.currentArgIndex = sizeof...(Args);
return invokeWithIndexedArgs(that, f, index_sequence_for<Args...>{});
}
#endif

private:
// FIXME: awful hack because of Boost::Test
Expand Down Expand Up @@ -188,11 +172,7 @@ class CUCUMBER_CPP_EXPORT StepManager {

private:
// We're a singleton so don't allow instances
StepManager()
#ifndef BOOST_NO_DELETED_FUNCTIONS
= delete
#endif
;
StepManager() = delete;
};

static inline std::string toSourceString(const char* filePath, const int line) {
Expand Down
Loading

0 comments on commit 4d47d6c

Please sign in to comment.