Skip to content

Commit

Permalink
This allows libcppa to compile and run on windows using g++ and MingW.
Browse files Browse the repository at this point in the history
The examples and tests run. Remaining problems:
1. middleman_event_handler::update runs into "cannot erase " << ptr << " (no such element)" on disconnect of a remote actor.
2. chat example client crashes in windows on connect
backtrace just prints addresses.
added execinfo_windows.h for missing execinfo.h in mingw
uuid from disk partition now implemented.
  • Loading branch information
ajac committed Mar 5, 2014
1 parent a4f6045 commit 5727f72
Show file tree
Hide file tree
Showing 23 changed files with 1,295 additions and 322 deletions.
30 changes: 26 additions & 4 deletions CMakeLists.txt
Expand Up @@ -39,6 +39,10 @@ if (CMAKE_CXX_FLAGS)
else (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED false)
set(CMAKE_CXX_FLAGS "-std=c++11 -Wextra -Wall -pedantic")
if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32")
include (GenerateExportHeader)
endif(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
Expand All @@ -57,7 +61,7 @@ endif (HAVE_VALGRIND_H)
# check for g++ >= 4.7 or clang++ > = 3.2
try_run(ProgramResult
CompilationSucceeded
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/get_compiler_version.cpp
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/get_compiler_version.cpp
RUN_OUTPUT_VARIABLE CompilerVersion)
if (NOT CompilationSucceeded OR NOT ProgramResult EQUAL 0)
message(FATAL_ERROR "Cannot determine compiler version")
Expand Down Expand Up @@ -111,6 +115,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(LIBCPPA_PLATFORM_SRC src/middleman_event_handler_epoll.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBCPPA_PLATFORM_SRC src/middleman_event_handler_poll.cpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Window")
set(LIBCPPA_PLATFORM_SRC src/middleman_event_handler_poll.cpp src/backtrace.cpp)
else ()
message(FATAL_ERROR "This platform is not supported by libcppa")
endif()
Expand All @@ -123,7 +129,8 @@ file(GLOB LIBCPPA_HDRS "cppa/*.hpp"
"cppa/io/*.hpp"
"cppa/opencl/*.hpp"
"cppa/qtsupport/*.hpp"
"cppa/util/*.hpp")
"cppa/util/*.hpp"
"cppa/windows/*.hpp")

# list cpp files including platform-dependent files
set(LIBCPPA_SRC
Expand Down Expand Up @@ -199,6 +206,7 @@ set(LIBCPPA_SRC
src/serializer.cpp
src/shared_spinlock.cpp
src/singleton_manager.cpp
src/socketpair.cpp
src/string_serialization.cpp
src/sync_request_bouncer.cpp
src/thread_pool_scheduler.cpp
Expand All @@ -223,6 +231,9 @@ if (APPLE)
# -pthread is ignored on MacOSX
elseif (UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
elseif (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
set(LD_FLAGS "ws2_32 -liphlpapi")
endif ()

if (ENABLE_OPENCL)
Expand All @@ -237,6 +248,13 @@ if (ENABLE_OPENCL)
add_definitions(-DCPPA_OPENCL)
endif (ENABLE_OPENCL)

if (MINGW)
set(LIBCPPA_SRC
${LIBCPPA_SRC}
src/windows/windows_tcp.cpp)
endif (MINGW)


if (DISABLE_MEM_MANAGEMENT)
add_definitions(-DCPPA_DISABLE_MEM_MANAGEMENT)
endif (DISABLE_MEM_MANAGEMENT)
Expand Down Expand Up @@ -285,7 +303,7 @@ if (DISABLE_CONTEXT_SWITCHING)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCPPA_DISABLE_CONTEXT_SWITCHING")
endif ()

# bulid shared library if not comiling static only
# build shared library if not compiling static only
if (NOT "${CPPA_BUILD_STATIC_ONLY}" STREQUAL "yes")
add_library(libcppa SHARED ${LIBCPPA_SRC} ${LIBCPPA_HDRS})
target_link_libraries(libcppa ${LD_FLAGS})
Expand All @@ -296,7 +314,9 @@ if (NOT "${CPPA_BUILD_STATIC_ONLY}" STREQUAL "yes")
SOVERSION ${LIBRARY_SOVERSION}
VERSION ${LIBRARY_VERSION}
OUTPUT_NAME cppa)
install(TARGETS libcppa LIBRARY DESTINATION lib)
if(NOT MINGW)
install(TARGETS libcppa LIBRARY DESTINATION lib)
endif()
endif ()

# build static library only if --build-static or --build-static-only was set
Expand Down Expand Up @@ -338,6 +358,8 @@ else ()
#set (CPPA_LIBRARY -L${LIBRARY_OUTPUT_PATH} -lcppa)
elseif (UNIX)
set (CPPA_LIBRARY ${LIBRARY_OUTPUT_PATH}/libcppa.so)
elseif (MINGW)
set (CPPA_LIBRARY ${LIBRARY_OUTPUT_PATH}/libcppa.dll)
else ()
message (SEND_FATAL "Host platform not supported ...")
endif ()
Expand Down
261 changes: 138 additions & 123 deletions cppa/config.hpp
@@ -1,123 +1,138 @@
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/


#ifndef CPPA_CONFIG_HPP
#define CPPA_CONFIG_HPP

#if defined(__clang__)
# define CPPA_CLANG
# define CPPA_DEPRECATED __attribute__((__deprecated__))
#elif defined(__GNUC__)
# define CPPA_GCC
# define CPPA_DEPRECATED __attribute__((__deprecated__))
#elif defined(_MSC_VER)
# define CPPA_DEPRECATED __declspec(deprecated)
#else
# define CPPA_DEPRECATED
#endif

#if defined(__APPLE__)
# define CPPA_MACOS
# ifndef _GLIBCXX_HAS_GTHREADS
# define _GLIBCXX_HAS_GTHREADS
# endif
#elif defined(__linux__)
# define CPPA_LINUX
# include <linux/version.h>
# if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
# define CPPA_POLL_IMPL
# endif
#elif defined(WIN32)
# define CPPA_WINDOWS
#else
# error Plattform and/or compiler not supportet
#endif

#include <memory>
#include <cstdio>
#include <cstdlib>

#ifdef CPPA_DEBUG_MODE
#include <execinfo.h>

#define CPPA_REQUIRE__(stmt, file, line) \
printf("%s:%u: requirement failed '%s'\n", file, line, stmt); \
{ \
void *array[10]; \
size_t size = backtrace(array, 10); \
backtrace_symbols_fd(array, size, 2); \
} \
abort()
#define CPPA_REQUIRE(stmt) \
if ((stmt) == false) { \
CPPA_REQUIRE__(#stmt, __FILE__, __LINE__); \
}((void) 0)
#else // CPPA_DEBUG_MODE
#define CPPA_REQUIRE(unused) static_cast<void>(0)
#endif // CPPA_DEBUG_MODE

#define CPPA_CRITICAL__(error, file, line) { \
printf("%s:%u: critical error: '%s'\n", file, line, error); \
exit(7); \
} ((void) 0)

#define CPPA_CRITICAL(error) CPPA_CRITICAL__(error, __FILE__, __LINE__)

#ifdef CPPA_WINDOWS
#else
# include <unistd.h>
#endif

namespace cppa {

/**
* @brief An alternative for the 'missing' @p std::make_unqiue.
*/
template<typename T, typename... Args>
std::unique_ptr<T> create_unique(Args&&... args) {
return std::unique_ptr<T>{new T(std::forward<Args>(args)...)};
}

#ifdef CPPA_WINDOWS
typedef SOCKET native_socket_type;
typedef const char* socket_send_ptr;
typedef char* socket_recv_ptr;
constexpr SOCKET invalid_socket = INVALID_SOCKET;
#else
typedef int native_socket_type;
typedef const void* socket_send_ptr;
typedef void* socket_recv_ptr;
constexpr int invalid_socket = -1;
inline void closesocket(native_socket_type fd) { close(fd); }
#endif

} // namespace cppa

#endif // CPPA_CONFIG_HPP
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/


#ifndef CPPA_CONFIG_HPP
#define CPPA_CONFIG_HPP

#if defined(__clang__)
# define CPPA_CLANG
# define CPPA_DEPRECATED __attribute__((__deprecated__))
#elif defined(__GNUC__)
# define CPPA_GCC
# define CPPA_DEPRECATED __attribute__((__deprecated__))
#elif defined(_MSC_VER)
# define CPPA_DEPRECATED __declspec(deprecated)
#else
# define CPPA_DEPRECATED
#endif

#if defined(__APPLE__)
# define CPPA_MACOS
# ifndef _GLIBCXX_HAS_GTHREADS
# define _GLIBCXX_HAS_GTHREADS
# endif
#elif defined(__linux__)
# define CPPA_LINUX
# include <linux/version.h>
# if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
# define CPPA_POLL_IMPL
# endif
#elif defined(WIN32)
# define CPPA_WINDOWS
#else
# error Plattform and/or compiler not supportet
#endif

#include <memory>
#include <cstdio>
#include <cstdlib>

#ifdef CPPA_DEBUG_MODE

#ifdef CPPA_WINDOWS
#include <cppa/execinfo_windows.h>
#else
#include <execinfo.h>
#endif

#define CPPA_REQUIRE__(stmt, file, line) \
printf("%s:%u: requirement failed '%s'\n", file, line, stmt); \
{ \
void *array[10]; \
size_t size = backtrace(array, 10); \
backtrace_symbols_fd(array, size, 2); \
} \
abort()
#define CPPA_REQUIRE(stmt) \
if ((stmt) == false) { \
CPPA_REQUIRE__(#stmt, __FILE__, __LINE__); \
}((void) 0)
#else // CPPA_DEBUG_MODE
#define CPPA_REQUIRE(unused) static_cast<void>(0)
#endif // CPPA_DEBUG_MODE

#define CPPA_CRITICAL__(error, file, line) { \
printf("%s:%u: critical error: '%s'\n", file, line, error); \
exit(7); \
} ((void) 0)

#define CPPA_CRITICAL(error) CPPA_CRITICAL__(error, __FILE__, __LINE__)

#ifdef CPPA_WINDOWS
# include <w32api.h>
#undef _WIN32_WINNT
#undef WINVER
#define _WIN32_WINNT WindowsVista
#define WINVER WindowsVista
# include <ws2tcpip.h>
# include <winsock2.h>
#undef interface
// remove interface which is defined in rpc.h in files included by windows.h
// as it clashes with name used in own code
#else
# include <unistd.h>
#endif

namespace cppa {

/**
* @brief An alternative for the 'missing' @p std::make_unqiue.
*/
template<typename T, typename... Args>
std::unique_ptr<T> create_unique(Args&&... args) {
return std::unique_ptr<T>{new T(std::forward<Args>(args)...)};
}

#ifdef CPPA_WINDOWS
typedef SOCKET native_socket_type;
typedef const char* socket_send_ptr;
typedef char* socket_recv_ptr;
constexpr SOCKET invalid_socket = INVALID_SOCKET;
#else
typedef int native_socket_type;
typedef const void* socket_send_ptr;
typedef void* socket_recv_ptr;
constexpr int invalid_socket = -1;
inline void closesocket(native_socket_type fd) { close(fd); }
#endif

} // namespace cppa

#endif // CPPA_CONFIG_HPP
26 changes: 26 additions & 0 deletions cppa/detail/fd_util.hpp
Expand Up @@ -66,6 +66,32 @@ void handle_read_result(ssize_t result, bool is_nonblocking_io);

#else

// throws ios_base::failure and adds errno failure if @p add_errno_failure
void throw_io_failure(const char* what, bool add_errno_failure = true);

// returns true if fd is nonblocking
// throws @p ios_base::failure on error
bool nonblocking(native_socket_type fd);

// sets fd to nonblocking if <tt>set_nonblocking == true</tt>
// or to blocking if <tt>set_nonblocking == false</tt>
// throws @p ios_base::failure on error
void nonblocking(native_socket_type fd, bool new_value);

// returns true if fd is nodelay socket
// throws @p ios_base::failure on error
bool tcp_nodelay(native_socket_type fd);

// returns true if fd is nodelay socket
// throws @p ios_base::failure on error
void tcp_nodelay(native_socket_type fd, bool new_value);

// reads @p result and @p errno and throws @p ios_base::failure on error
void handle_write_result(ssize_t result, bool is_nonblocking_io);

// reads @p result and @p errno and throws @p ios_base::failure on error
void handle_read_result(ssize_t result, bool is_nonblocking_io);

#endif

} } } // namespace cppa::detail::fd_util
Expand Down

0 comments on commit 5727f72

Please sign in to comment.