diff --git a/qpid/cpp/CMakeLists.txt b/qpid/cpp/CMakeLists.txt index 3b1890f9769..5cdde43bae3 100644 --- a/qpid/cpp/CMakeLists.txt +++ b/qpid/cpp/CMakeLists.txt @@ -29,6 +29,8 @@ project(qpid-cpp) cmake_minimum_required(VERSION 2.6 FATAL_ERROR) if(COMMAND cmake_policy) cmake_policy(VERSION 2.6) + # Use @rpath on OSX + cmake_policy(SET CMP0042 NEW) endif(COMMAND cmake_policy) if (${CMAKE_VERSION} VERSION_LESS "2.8.0") diff --git a/qpid/cpp/INSTALL b/qpid/cpp/INSTALL index 717c9b0908b..a20b90be85c 100644 --- a/qpid/cpp/INSTALL +++ b/qpid/cpp/INSTALL @@ -158,6 +158,17 @@ the shared libraries built as part of Qpid. The mktemp package must be installed separately in order to execute the Qpid test suite. +2.5 Building on OSX +=================== +Qpid has been tested on OSX 10.10 with Clang 6.0 and Boost 1.57. Boost 1.57 requires +C++11 support. SASL support has not been tested. The cmake command line should be: + + # cmake -DBUILD_SASL=no -DBUILD_PROBES=no -DCMAKE_CXX_FLAGS="-std=c++11 -Wno-error=deprecated-declarations" .. + +Dependencies can be installed from homebrew (http://brew.sh/) using: + + # brew install cmake boost ossp-uuid pkgconfig help2man doxygen grpahviz swig boost sleepycat berkeley-db + 3. Building a Repository Working Copy ===================================== To get the source code from the subversion repository (trunk) do: diff --git a/qpid/cpp/src/CMakeLists.txt b/qpid/cpp/src/CMakeLists.txt index 3de2cc9b06a..72b2b2c3b63 100644 --- a/qpid/cpp/src/CMakeLists.txt +++ b/qpid/cpp/src/CMakeLists.txt @@ -310,16 +310,19 @@ endif (UUID_GENERATE_IN_LIBC) # These dependencies aren't found on windows if (NOT CMAKE_SYSTEM_NAME STREQUAL Windows) - # Ensure we have clock_gettime - CHECK_FUNCTION_EXISTS (clock_gettime CLOCK_GETTIME_IN_LIBC) - if (NOT CLOCK_GETTIME_IN_LIBC) - CHECK_LIBRARY_EXISTS (rt clock_gettime "" CLOCK_GETTIME_IN_RT) - if (CLOCK_GETTIME_IN_RT) - set(clock_gettime_LIB "rt") - else () - message(FATAL_ERROR "Cannot find clock_gettime()") - endif (CLOCK_GETTIME_IN_RT) - endif (NOT CLOCK_GETTIME_IN_LIBC) + # Clocks on OSX are different + if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin) + # Ensure we have clock_gettime + CHECK_FUNCTION_EXISTS (clock_gettime CLOCK_GETTIME_IN_LIBC) + if (NOT CLOCK_GETTIME_IN_LIBC) + CHECK_LIBRARY_EXISTS (rt clock_gettime "" CLOCK_GETTIME_IN_RT) + if (CLOCK_GETTIME_IN_RT) + set(clock_gettime_LIB "rt") + else () + message(FATAL_ERROR "Cannot find clock_gettime()") + endif (CLOCK_GETTIME_IN_RT) + endif (NOT CLOCK_GETTIME_IN_LIBC) + endif (NOT CMAKE_SYSTEM_NAME STREQUAL OSX) # Check for header file for dtrace static probes check_include_files(sys/sdt.h HAVE_SDT) diff --git a/qpid/cpp/src/qpid/store/CMakeLists.txt b/qpid/cpp/src/qpid/store/CMakeLists.txt index ee7894730a6..19445ecd223 100644 --- a/qpid/cpp/src/qpid/store/CMakeLists.txt +++ b/qpid/cpp/src/qpid/store/CMakeLists.txt @@ -54,8 +54,12 @@ if (CMAKE_SYSTEM_NAME STREQUAL Windows) endif (CMAKE_SYSTEM_NAME STREQUAL Windows) set_target_properties (store PROPERTIES - COMPILE_DEFINITIONS _IN_QPID_BROKER - VERSION ${qpidc_version}) + COMPILE_DEFINITIONS _IN_QPID_BROKER) +if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin) + set_target_properties (store PROPERTIES + VERSION ${qpidc_version}) +endif (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin) + install (TARGETS store # RUNTIME DESTINATION ${QPIDD_MODULE_DIR} COMPONENT ${QPID_COMPONENT_BROKER}) diff --git a/qpid/cpp/src/qpid/sys/posix/Condition.cpp b/qpid/cpp/src/qpid/sys/posix/Condition.cpp index f629e50cd73..a288f176092 100644 --- a/qpid/cpp/src/qpid/sys/posix/Condition.cpp +++ b/qpid/cpp/src/qpid/sys/posix/Condition.cpp @@ -31,7 +31,13 @@ struct ClockMonotonicAttr { ClockMonotonicAttr() { QPID_POSIX_ASSERT_THROW_IF(pthread_condattr_init(&attr)); +#ifdef __MACH__ + // OSX doesn't let you set the clock, and absolute pthread + // waits are always based on gettimeofday. Not sure what to + // do. +#else QPID_POSIX_ASSERT_THROW_IF(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)); +#endif } }; diff --git a/qpid/cpp/src/qpid/sys/posix/PosixPoller.cpp b/qpid/cpp/src/qpid/sys/posix/PosixPoller.cpp index ae839b2e20e..1158ea7a91d 100644 --- a/qpid/cpp/src/qpid/sys/posix/PosixPoller.cpp +++ b/qpid/cpp/src/qpid/sys/posix/PosixPoller.cpp @@ -681,9 +681,9 @@ void Poller::run() { // Ensure that we exit thread responsibly under all circumstances try { // Make sure we can't be interrupted by signals at a bad time - ::sigset_t ss; - ::sigfillset(&ss); - ::pthread_sigmask(SIG_SETMASK, &ss, 0); + sigset_t ss; + sigfillset(&ss); + pthread_sigmask(SIG_SETMASK, &ss, 0); ++(impl->threadCount); do { diff --git a/qpid/cpp/src/qpid/sys/posix/PrivatePosix.h b/qpid/cpp/src/qpid/sys/posix/PrivatePosix.h index 34a2022694f..c84302576ca 100644 --- a/qpid/cpp/src/qpid/sys/posix/PrivatePosix.h +++ b/qpid/cpp/src/qpid/sys/posix/PrivatePosix.h @@ -24,6 +24,10 @@ #include "qpid/sys/Time.h" +#ifdef __MACH__ +#include +#endif + struct timespec; struct timeval; struct addrinfo; @@ -34,7 +38,6 @@ namespace sys { // Private Time related implementation details struct timespec& toTimespec(struct timespec& ts, const AbsTime& t); struct timeval& toTimeval(struct timeval& tv, const Duration& t); -Duration toTime(const struct timespec& ts); // Private SocketAddress details class SocketAddress; diff --git a/qpid/cpp/src/qpid/sys/posix/Time.cpp b/qpid/cpp/src/qpid/sys/posix/Time.cpp index 10a5d944b1b..98bae352c9b 100644 --- a/qpid/cpp/src/qpid/sys/posix/Time.cpp +++ b/qpid/cpp/src/qpid/sys/posix/Time.cpp @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -32,6 +32,11 @@ #include #include +#ifdef __MACH__ +#include +#include +#endif + namespace { int64_t max_abstime() { return std::numeric_limits::max(); } } @@ -39,6 +44,16 @@ int64_t max_abstime() { return std::numeric_limits::max(); } namespace qpid { namespace sys { +#ifdef __MACH__ + inline Duration toTime(const mach_timespec_t& ts) { + return ts.tv_sec*TIME_SEC + ts.tv_nsec; + } +#else + inline Duration toTime(const struct timespec& ts) { + return ts.tv_sec*TIME_SEC + ts.tv_nsec; + } +#endif + AbsTime::AbsTime(const AbsTime& t, const Duration& d) : timepoint(d == Duration::max() ? max_abstime() : t.timepoint+d.nanosecs) {} @@ -53,9 +68,18 @@ AbsTime AbsTime::FarFuture() { } AbsTime AbsTime::now() { + AbsTime time_now; +#ifdef __MACH__ + // SYSTEM_CLOCK is like CLOCK_MONOTONIC + clock_serv_t cs; + mach_timespec_t ts; + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cs); + clock_get_time(cs, &ts); + mach_port_deallocate(mach_task_self(), cs); +#else struct timespec ts; ::clock_gettime(CLOCK_MONOTONIC, &ts); - AbsTime time_now; +#endif time_now.timepoint = toTime(ts).nanosecs; return time_now; } @@ -65,8 +89,17 @@ AbsTime AbsTime::epoch() { } Duration Duration::FromEpoch() { +#ifdef __MACH__ + // CALENDAR_CLOCK is like CLOCK_REALTIME + clock_serv_t cs; + mach_timespec_t ts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cs); + clock_get_time(cs, &ts); + mach_port_deallocate(mach_task_self(), cs); +#else struct timespec ts; ::clock_gettime(CLOCK_REALTIME, &ts); +#endif return toTime(ts).nanosecs; } @@ -84,11 +117,7 @@ struct timespec& toTimespec(struct timespec& ts, const AbsTime& a) { Duration secs = t / TIME_SEC; ts.tv_sec = (secs > TIME_T_MAX) ? TIME_T_MAX : static_cast(secs); ts.tv_nsec = static_cast(t % TIME_SEC); - return ts; -} - -Duration toTime(const struct timespec& ts) { - return ts.tv_sec*TIME_SEC + ts.tv_nsec; + return ts; } std::ostream& operator<<(std::ostream& o, const Duration& d) { @@ -144,8 +173,16 @@ void outputFormattedNow(std::ostream& o) { } void outputHiresNow(std::ostream& o) { +#ifdef __MACH__ + clock_serv_t cs; + mach_timespec_t time; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cs); + clock_get_time(cs, &time); + mach_port_deallocate(mach_task_self(), cs); +#else ::timespec time; ::clock_gettime(CLOCK_REALTIME, &time); +#endif ::time_t seconds = time.tv_sec; outputFormattedTime(o, &seconds); o << "." << std::setw(9) << std::setfill('0') << time.tv_nsec << " "; diff --git a/qpid/cpp/src/qpid/sys/regex.h b/qpid/cpp/src/qpid/sys/regex.h index 77de6a7f5c7..29653b848d0 100644 --- a/qpid/cpp/src/qpid/sys/regex.h +++ b/qpid/cpp/src/qpid/sys/regex.h @@ -19,7 +19,7 @@ * */ -#if defined(_POSIX_SOURCE) || defined(__unix__) +#if defined(_POSIX_SOURCE) || defined(__unix__) || defined(__MACH__) # include # include # include @@ -38,7 +38,7 @@ namespace qpid { namespace sys { -#if defined(_POSIX_SOURCE) || defined(__unix__) +#if defined(_POSIX_SOURCE) || defined(__unix__) || defined(__MACH__) class regex { ::regex_t re;