Переглянути джерело

Merge pull request #357 from ngoossens/osx-compilation

OS X compilation
Sten Grüner 9 роки тому
батько
коміт
8a376f8728

+ 24 - 7
CMakeLists.txt

@@ -48,19 +48,30 @@ if(CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
     # binary size reduction settings
 	add_definitions(-ffunction-sections -fdata-sections -fno-stack-protector -fno-unwind-tables
                     -fno-asynchronous-unwind-tables -fno-math-errno -fmerge-all-constants -fno-ident)
-    set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--gc-sections")
-    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
-    set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default
+  if (APPLE)
+      set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-dead_strip")
+      set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
+  else()
+      set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--gc-sections")
+      set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
+  endif()
+  set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default
 	if(NOT WIN32)
      if(NOT CYGWIN)
 	    add_definitions(-fvisibility=hidden -fPIC)
-        set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none")
+      if (NOT APPLE)
+          set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none")
+      endif()
       endif()
 	endif()
     if(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "Release")
         set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s")
         set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s")
     endif()
+    if (APPLE)
+        set(CMAKE_MACOSX_RPATH 1)
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DARWIN_C_SOURCE=1")
+    endif()
 endif()
 
 # build the main library
@@ -220,7 +231,10 @@ if(EXTENSION_UDP)
 	message(STATUS "Extensions: enabling udp")
 	add_definitions(-DEXTENSION_UDP)
 	add_executable(exampleServerUDP $<TARGET_OBJECTS:open62541-object> examples/networklayer_udp.c examples/server_udp.c)
-    target_link_libraries(exampleServerUDP rt)
+  target_link_libraries(exampleServerUDP urcu-cds urcu urcu-common)
+  if (NOT APPLE)
+      target_link_libraries(exampleServerUDP rt)
+  endif()
 endif()
 
 option(EXTENSION_STATELESS "Enable stateless extension" OFF)
@@ -263,6 +277,9 @@ target_compile_definitions(open62541 PRIVATE -DUA_DYNAMIC_LINKING)
 if(WIN32)
     target_link_libraries(open62541 ws2_32) #since networklayer_tcp is linked into the amalgate
 endif()
+if(ENABLE_MULTITHREADING)
+  target_link_libraries(open62541 urcu-cds urcu urcu-common pthread)
+endif()
 
 # build language bindings for the library
 option(ENABLE_BINDING_LUA "Build Lua bindings" OFF)
@@ -294,7 +311,7 @@ if(BUILD_EXAMPLESERVER)
     if(WIN32)
         target_link_libraries(server_static ws2_32)
         target_link_libraries(server ws2_32)
-    else()
+    elseif(NOT APPLE)
         target_link_libraries(server_static rt)
         target_link_libraries(server rt)
     endif()
@@ -331,7 +348,7 @@ if(BUILD_EXAMPLECLIENT)
     if(WIN32)
         target_link_libraries(client_static ws2_32)
         target_link_libraries(client ws2_32)
-    else()
+    elseif(NOT APPLE)
         target_link_libraries(client_static rt)
         target_link_libraries(client rt)
     endif()

+ 7 - 4
examples/CMakeLists.txt

@@ -2,13 +2,16 @@ include_directories(${PROJECT_SOURCE_DIR}/include)
 
 set(LIBS open62541)
 if(NOT WIN32)
-    list(APPEND LIBS rt pthread)
+    list(APPEND LIBS pthread)
+    if (NOT APPLE)
+        list(APPEND LIBS rt)
+    endif()
 else()
     list(APPEND LIBS ws2_32)
 endif()
-if(MULTITHREADING)
+if(ENABLE_MULTITHREADING)
     list(APPEND LIBS urcu-cds urcu urcu-common)
-endif(MULTITHREADING)
+endif(ENABLE_MULTITHREADING)
 
 add_executable(server_variable server_variable.c)
 target_link_libraries(server_variable ${LIBS})
@@ -19,4 +22,4 @@ target_link_libraries(server_repeated_job ${LIBS})
 if(ENABLE_METHODCALLS)
   add_executable(server_method server_method.c)
   target_link_libraries(server_method ${LIBS})
-endif()
+endif()

+ 15 - 3
examples/networklayer_tcp.c

@@ -16,7 +16,7 @@
 # define CLOSESOCKET(S) closesocket(S)
 #else
 # include <fcntl.h>
-# include <sys/select.h> 
+# include <sys/select.h>
 # include <netinet/in.h>
 # include <netinet/tcp.h>
 # include <sys/ioctl.h>
@@ -33,6 +33,10 @@
 # include <urcu/uatomic.h>
 #endif
 
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
 /****************************/
 /* Generic Socket Functions */
 /****************************/
@@ -89,7 +93,7 @@ static UA_StatusCode socket_recv(UA_Connection *connection, UA_ByteString *respo
 		free(response->data);
         UA_ByteString_init(response);
         socket_close(connection);
-        return UA_CONNECTION_CLOSED; /* ret == 0 -> server has closed the connection */
+        return UA_STATUSCODE_BADCONNECTIONCLOSED; /* ret == 0 -> server has closed the connection */
 	} else if(ret < 0) {
         free(response->data);
         UA_ByteString_init(response);
@@ -273,7 +277,7 @@ static UA_StatusCode ServerNetworkLayerTCP_start(UA_ServerNetworkLayer *nl, UA_L
     if((layer->serversockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
         UA_LOG_WARNING((*layer->logger), UA_LOGCATEGORY_COMMUNICATION, "Error opening socket");
         return UA_STATUSCODE_BADINTERNALERROR;
-    } 
+    }
 #endif
     const struct sockaddr_in serv_addr =
         {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY,
@@ -535,6 +539,14 @@ UA_Connection ClientNetworkLayerTCP_connect(UA_ConnectionConfig localConf, char
         UA_LOG_WARNING((*logger), UA_LOGCATEGORY_COMMUNICATION, "Connection failed");
         return connection;
     }
+
+#ifdef SO_NOSIGPIPE
+    int val = 1;
+    if (setsockopt(connection.sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof(val)) < 0) {
+    UA_LOG_WARNING((*logger), UA_LOGCATEGORY_COMMUNICATION, "Couldn't set SO_NOSIGPIPE");
+    }
+#endif
+
     //socket_set_nonblocking(connection.sockfd);
     connection.write = socket_write;
     connection.recv = socket_recv;

+ 5 - 1
include/ua_config.h.in

@@ -36,7 +36,11 @@
 /* Endianness */
 #if defined(__linux__) || defined(__APPLE__)
 #  ifndef __QNX__
-# include <endian.h>
+#    if defined(__APPLE__) || defined(__MACH__)
+#     include <machine/endian.h>
+#    else
+#     include <endian.h>
+#    endif
 #  endif
 # if ( __BYTE_ORDER != __LITTLE_ENDIAN )
 #  define UA_NON_LITTLEENDIAN_ARCHITECTURE

+ 19 - 4
src/server/ua_server_worker.c

@@ -1,6 +1,11 @@
 #include "ua_util.h"
 #include "ua_server_internal.h"
 
+#if defined(__APPLE__) || defined(__MACH__)
+#include <mach/clock.h>
+#include <mach/mach.h>
+#endif
+
 /**
  * There are four types of job execution:
  *
@@ -99,7 +104,7 @@ static void dispatchJobs(UA_Server *server, UA_Job *jobs, size_t jobsSize) {
         cds_wfcq_node_init(&wln->node);
         cds_wfcq_enqueue(&server->dispatchQueue_head, &server->dispatchQueue_tail, &wln->node);
         jobsSize -= size;
-    } 
+    }
 }
 
 // throwaway struct to bring data into the worker threads
@@ -116,7 +121,7 @@ static void * workerLoop(struct workerStartData *startInfo) {
     *startInfo->workerCounter = c;
     UA_Server *server = startInfo->server;
     UA_free(startInfo);
-    
+
     pthread_mutex_t mutex; // required for the condition variable
     pthread_mutex_init(&mutex,0);
     pthread_mutex_lock(&mutex);
@@ -131,7 +136,17 @@ static void * workerLoop(struct workerStartData *startInfo) {
             UA_free(wln);
         } else {
             /* sleep until a work arrives (and wakes up all worker threads) */
-            clock_gettime(CLOCK_REALTIME, &to);
+            #if defined(__APPLE__) || defined(__MACH__) // OS X does not have clock_gettime, use clock_get_time
+              clock_serv_t cclock;
+              mach_timespec_t mts;
+              host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
+              clock_get_time(cclock, &mts);
+              mach_port_deallocate(mach_task_self(), cclock);
+              to.tv_sec = mts.tv_sec;
+              to.tv_nsec = mts.tv_nsec;
+            #else
+              clock_gettime(CLOCK_REALTIME, &to);
+            #endif
             to.tv_sec += 2;
             pthread_cond_timedwait(&server->dispatchQueue_condition, &mutex, &to);
         }
@@ -206,7 +221,7 @@ static UA_StatusCode addRepeatedJob(UA_Server *server, struct AddRepeatedJob * U
         lastTw = tempTw;
         tempTw = LIST_NEXT(lastTw, pointers);
     }
-    
+
     if(matchingTw) {
         /* append to matching entry */
         matchingTw = UA_realloc(matchingTw, sizeof(struct RepeatedJobs) +

+ 6 - 3
tests/CMakeLists.txt

@@ -8,13 +8,16 @@ find_package(Threads REQUIRED)
 
 set(LIBS ${CHECK_LIBRARIES})
 if(NOT WIN32)
-    list(APPEND LIBS rt pthread)
+  list(APPEND LIBS pthread)
+  if (NOT APPLE)
+    list(APPEND LIBS rt)
+  endif()
 else()
     list(APPEND LIBS ws2_32)
 endif()
-if(MULTITHREADING)
+if(ENABLE_MULTITHREADING)
     list(APPEND LIBS urcu-cds urcu urcu-common)
-endif(MULTITHREADING)
+endif(ENABLE_MULTITHREADING)
 
 # the unit test are built directly on the open62541 object files. so they can
 # access symbols that are hidden/not exported to the shared library