fixes #958 Android NDK support

To build this you will need to use the Android appropriate version
of cmake, and point it at the toolchain file that is included with
the NDK.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a0446b1..308268f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -142,6 +142,9 @@
     if (CMAKE_SYSTEM_VERSION MATCHES "Microsoft")
         add_definitions (-DNN_HAVE_WSL)
     endif()
+elseif (CMAKE_SYSTEM_NAME MATCHES "Android")
+    add_definitions (-DNN_HAVE_ANDROID)
+    add_definitions (-DNN_HAVE_LINUX)
 elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
     add_definitions (-DNN_HAVE_OSX)
 elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
@@ -248,7 +251,10 @@
     nn_check_sym (backtrace_symbols_fd execinfo.h NN_HAVE_BACKTRACE)
     nn_check_struct_member(msghdr msg_control sys/socket.h NN_HAVE_MSG_CONTROL)
     if (NN_HAVE_SEMAPHORE_RT OR NN_HAVE_SEMAPHORE_PTHREAD)
-        add_definitions (-DNN_HAVE_SEMAPHORE)
+        if (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin")
+            # macOS doesn't have unnamed semaphores
+            add_definitions (-DNN_HAVE_SEMAPHORE)
+        endif()
     endif ()
 endif ()
 
diff --git a/src/utils/sem.c b/src/utils/sem.c
index 17943d5..06a0128 100644
--- a/src/utils/sem.c
+++ b/src/utils/sem.c
@@ -24,74 +24,8 @@
 #include "err.h"
 #include "fast.h"
 
-#if defined NN_HAVE_OSX
 
-void nn_sem_init (struct nn_sem *self)
-{
-    int rc;
-
-    rc = pthread_mutex_init (&self->mutex, NULL);
-    errnum_assert (rc == 0, rc);
-    rc = pthread_cond_init (&self->cond, NULL);
-    errnum_assert (rc == 0, rc);
-    self->signaled = 0;
-}
-
-void nn_sem_term (struct nn_sem *self)
-{
-    int rc;
-
-    rc = pthread_cond_destroy (&self->cond);
-    errnum_assert (rc == 0, rc);
-    rc = pthread_mutex_destroy (&self->mutex);
-    errnum_assert (rc == 0, rc);
-}
-
-void nn_sem_post (struct nn_sem *self)
-{
-    int rc;
-
-    rc = pthread_mutex_lock (&self->mutex);
-    errnum_assert (rc == 0, rc);
-    nn_assert (self->signaled == 0);
-    self->signaled = 1;
-    rc = pthread_cond_signal (&self->cond);
-    errnum_assert (rc == 0, rc);
-    rc = pthread_mutex_unlock (&self->mutex);
-    errnum_assert (rc == 0, rc);
-}
-
-int nn_sem_wait (struct nn_sem *self)
-{
-    int rc;
-
-    /*  With OSX, semaphores are global named objects. They are not useful for
-        our use case. To get a similar object we exploit the implementation
-        detail of pthread_cond_wait() in Darwin kernel: It exits if signal is
-        caught. Note that this behaviour is not mandated by POSIX
-        and may break with future versions of Darwin. */
-    rc = pthread_mutex_lock (&self->mutex);
-    errnum_assert (rc == 0, rc);
-    if (nn_fast (self->signaled)) {
-        rc = pthread_mutex_unlock (&self->mutex);
-        errnum_assert (rc == 0, rc);
-        return 0;
-    }
-    rc = pthread_cond_wait (&self->cond, &self->mutex);
-    errnum_assert (rc == 0, rc);
-    if (nn_slow (!self->signaled)) {
-        rc = pthread_mutex_unlock (&self->mutex);
-        errnum_assert (rc == 0, rc);
-        return -EINTR;
-    }
-    self->signaled = 0;
-    rc = pthread_mutex_unlock (&self->mutex);
-    errnum_assert (rc == 0, rc);
-
-    return 0;
-}
-
-#elif defined NN_HAVE_WINDOWS
+#if defined NN_HAVE_WINDOWS
 
 void nn_sem_init (struct nn_sem *self)
 {
@@ -164,6 +98,74 @@
 }
 
 #else
-#error
+
+/*  Simulate semaphores with condition variables. */
+
+void nn_sem_init (struct nn_sem *self)
+{
+    int rc;
+
+    rc = pthread_mutex_init (&self->mutex, NULL);
+    errnum_assert (rc == 0, rc);
+    rc = pthread_cond_init (&self->cond, NULL);
+    errnum_assert (rc == 0, rc);
+    self->signaled = 0;
+}
+
+void nn_sem_term (struct nn_sem *self)
+{
+    int rc;
+
+    rc = pthread_cond_destroy (&self->cond);
+    errnum_assert (rc == 0, rc);
+    rc = pthread_mutex_destroy (&self->mutex);
+    errnum_assert (rc == 0, rc);
+}
+
+void nn_sem_post (struct nn_sem *self)
+{
+    int rc;
+
+    rc = pthread_mutex_lock (&self->mutex);
+    errnum_assert (rc == 0, rc);
+    nn_assert (self->signaled == 0);
+    self->signaled = 1;
+    rc = pthread_cond_signal (&self->cond);
+    errnum_assert (rc == 0, rc);
+    rc = pthread_mutex_unlock (&self->mutex);
+    errnum_assert (rc == 0, rc);
+}
+
+int nn_sem_wait (struct nn_sem *self)
+{
+    int rc;
+
+    /*  With OSX, semaphores are global named objects. They are not useful for
+        our use case. To get a similar object we exploit the implementation
+        detail of pthread_cond_wait() in Darwin kernel: It exits if signal is
+        caught. Note that this behaviour is not mandated by POSIX
+        and may break with future versions of Darwin. */
+    rc = pthread_mutex_lock (&self->mutex);
+    errnum_assert (rc == 0, rc);
+    if (nn_fast (self->signaled)) {
+        rc = pthread_mutex_unlock (&self->mutex);
+        errnum_assert (rc == 0, rc);
+        return 0;
+    }
+    rc = pthread_cond_wait (&self->cond, &self->mutex);
+    errnum_assert (rc == 0, rc);
+    if (nn_slow (!self->signaled)) {
+        rc = pthread_mutex_unlock (&self->mutex);
+        errnum_assert (rc == 0, rc);
+        return -EINTR;
+    }
+    self->signaled = 0;
+    rc = pthread_mutex_unlock (&self->mutex);
+    errnum_assert (rc == 0, rc);
+
+    return 0;
+}
+
+
 #endif
 
diff --git a/src/utils/sem.h b/src/utils/sem.h
index 6cfc021..34c0428 100644
--- a/src/utils/sem.h
+++ b/src/utils/sem.h
@@ -39,17 +39,7 @@
 /*  Waits till sem object becomes unlocked and locks it. */
 int nn_sem_wait (struct nn_sem *self);
 
-#if defined NN_HAVE_OSX
-
-#include <pthread.h>
-
-struct nn_sem {
-    pthread_mutex_t mutex;
-    pthread_cond_t cond;
-    int signaled;
-};
-
-#elif defined NN_HAVE_WINDOWS
+#if defined NN_HAVE_WINDOWS
 
 #include "win.h"
 
@@ -65,6 +55,16 @@
     sem_t sem;
 };
 
+#else /*  Simulate semaphore with condition variable. */
+
+#include <pthread.h>
+
+struct nn_sem {
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    int signaled;
+};
+
 #endif
 
 #endif