This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/769-libuv-package-and-thread-header
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 2127aeb544a4ace1363de1127577a409b048251c
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sun Jan 18 19:48:12 2026 +0100

    gh-769: Add libuv dep, update ci workflows and add smoke test
---
 .devcontainer/Containerfile                     |  1 +
 .github/workflows/macos.yml                     |  2 +-
 .github/workflows/ubuntu.yml                    |  1 +
 cmake/Modules/Findlibuv.cmake                   | 61 +++++++++++++++++++++++
 conanfile.py                                    |  4 ++
 misc/experimental/CMakeLists.txt                |  1 +
 misc/experimental/{ => libuv}/CMakeLists.txt    | 17 +++++--
 misc/experimental/libuv/src/libuv_smoke_test.cc | 64 +++++++++++++++++++++++++
 8 files changed, 146 insertions(+), 5 deletions(-)

diff --git a/.devcontainer/Containerfile b/.devcontainer/Containerfile
index 622f1fd2b..cc2b2f8ca 100644
--- a/.devcontainer/Containerfile
+++ b/.devcontainer/Containerfile
@@ -68,6 +68,7 @@ RUN DEBIAN_FRONTEND="noninteractive" sudo apt-get update && \
         libjansson-dev \
         libxml2-dev \
         libzip-dev \
+        libuv1-dev \
         rapidjson-dev \
         uuid-dev && \
     sudo apt-get clean
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index eceb860b5..f8279ae81 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -80,7 +80,7 @@ jobs:
         uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c #v3.3.0
       - name: Install dependencies
         run: |
-          brew install lcov jansson rapidjson libzip ccache ninja [email protected] 
google-benchmark
+          brew install lcov jansson rapidjson libzip ccache ninja [email protected] 
google-benchmark libuv
       - name: Prepare ccache timestamp
         id: ccache_cache_timestamp
         run: |
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index dc0964f4a..f2a0e5147 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -123,6 +123,7 @@ jobs:
           libjansson-dev \
           libcurl4-openssl-dev \
           libbenchmark-dev \
+          libuv1-dev \
           default-jdk \
           cmake \
           libffi-dev \
diff --git a/cmake/Modules/Findlibuv.cmake b/cmake/Modules/Findlibuv.cmake
new file mode 100644
index 000000000..4c71e79f6
--- /dev/null
+++ b/cmake/Modules/Findlibuv.cmake
@@ -0,0 +1,61 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# 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
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# - Try to find libuv
+#      Once done this will define
+#  libuv_FOUND - System has libuv
+#  LIBUV_INCLUDE_DIR - The libuv include directory
+#  LIBUV_LIBRARY - The libuv library
+#  uv - Imported target for libuv
+
+find_package(libuv CONFIG QUIET)
+
+if (NOT libuv_FOUND)
+    find_package(PkgConfig QUIET)
+    if (PkgConfig_FOUND)
+        pkg_check_modules(LIBUV QUIET libuv)
+    endif ()
+endif ()
+
+if (NOT libuv_FOUND)
+    find_path(LIBUV_INCLUDE_DIR
+        NAMES uv.h
+        HINTS ${LIBUV_INCLUDEDIR} ${LIBUV_INCLUDE_DIRS}
+    )
+
+    find_library(LIBUV_LIBRARY
+        NAMES uv libuv
+        HINTS ${LIBUV_LIBDIR} ${LIBUV_LIBRARY_DIRS}
+    )
+
+    include(FindPackageHandleStandardArgs)
+    find_package_handle_standard_args(libuv DEFAULT_MSG LIBUV_LIBRARY 
LIBUV_INCLUDE_DIR)
+    mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARY)
+endif ()
+
+if (libuv_FOUND AND NOT TARGET libuv::uv AND TARGET libuv::libuv)
+    #Note: libuv cmake config possible defines libuv::libuv target
+    #      and conan libuv package defines uv target
+    #      so create an alias target uv for consistency
+    add_library(libuv::uv ALIAS libuv::libuv)
+elseif (libuv_FOUND AND NOT TARGET libuv::uv AND LIBUV_LIBRARY AND 
LIBUV_INCLUDE_DIR)
+    add_library(libuv::uv SHARED IMPORTED)
+    set_target_properties(libuv::uv PROPERTIES
+        IMPORTED_LOCATION "${LIBUV_LIBRARY}"
+        INTERFACE_INCLUDE_DIRECTORIES "${LIBUV_INCLUDE_DIR}"
+    )
+endif ()
diff --git a/conanfile.py b/conanfile.py
index bb1c63907..bf4925354 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -336,6 +336,8 @@ class CelixConan(ConanFile):
             self.options['mosquitto'].shared = True
             if self.options.enable_testing:
                 self.options['mosquitto'].broker = True
+        if self.options.build_experimental:
+            self.options['libuv'].shared = True
 
     def requirements(self):
         if self.options.build_utils:
@@ -370,6 +372,8 @@ class CelixConan(ConanFile):
         self.requires("zlib/1.3.1", override=True)
         if self.options.build_event_admin_remote_provider_mqtt:
             self.requires("mosquitto/[>=2.0.3 <3.0.0]")
+        if self.options.build_experimental:
+            self.requires("libuv/[>=1.49.2 <2.0.0]")
         self.validate()
 
     def generate(self):
diff --git a/misc/experimental/CMakeLists.txt b/misc/experimental/CMakeLists.txt
index f4de02bf2..51307cb0a 100644
--- a/misc/experimental/CMakeLists.txt
+++ b/misc/experimental/CMakeLists.txt
@@ -18,5 +18,6 @@
 celix_subproject(EXPERIMENTAL "Options to enable building the experimental - 
non stable - bundles/libraries. " OFF)
 if (EXPERIMENTAL)
     add_subdirectory(bundles)
+    add_subdirectory(libuv)
     add_subdirectory(rust)
 endif ()
diff --git a/misc/experimental/CMakeLists.txt 
b/misc/experimental/libuv/CMakeLists.txt
similarity index 63%
copy from misc/experimental/CMakeLists.txt
copy to misc/experimental/libuv/CMakeLists.txt
index f4de02bf2..02b35ecf7 100644
--- a/misc/experimental/CMakeLists.txt
+++ b/misc/experimental/libuv/CMakeLists.txt
@@ -15,8 +15,17 @@
 # specific language governing permissions and limitations
 # under the License.
 
-celix_subproject(EXPERIMENTAL "Options to enable building the experimental - 
non stable - bundles/libraries. " OFF)
-if (EXPERIMENTAL)
-    add_subdirectory(bundles)
-    add_subdirectory(rust)
+find_package(libuv REQUIRED)
+
+if (NOT TARGET libuv::uv AND TARGET uv)
+    #Note: conan libuv package 1.49.2 defines uv target, but 1.51.0 defines 
lubuv::uv target
+    add_library(libuv::uv ALIAS uv)
+endif ()
+
+if (ENABLE_TESTING)
+    add_executable(libuv_smoke_test
+        src/libuv_smoke_test.cc
+    )
+    target_link_libraries(libuv_smoke_test PRIVATE libuv::uv GTest::gtest 
GTest::gtest_main)
+    add_test(NAME libuv_smoke_test COMMAND libuv_smoke_test)
 endif ()
diff --git a/misc/experimental/libuv/src/libuv_smoke_test.cc 
b/misc/experimental/libuv/src/libuv_smoke_test.cc
new file mode 100644
index 000000000..820d7d0c1
--- /dev/null
+++ b/misc/experimental/libuv/src/libuv_smoke_test.cc
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * 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
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <uv.h>
+
+TEST(LibuvSmokeTest, CanInitAndCloseLoopTest) {
+    uv_loop_t loop;
+    EXPECT_EQ(0, uv_loop_init(&loop));
+    EXPECT_EQ(0, uv_loop_close(&loop));
+}
+
+namespace {
+struct ThreadState {
+    uv_mutex_t mutex;
+    uv_cond_t cond;
+    bool ready;
+};
+
+void threadMain(void* data) {
+    auto* state = static_cast<ThreadState*>(data);
+    uv_mutex_lock(&state->mutex);
+    state->ready = true;
+    uv_cond_signal(&state->cond);
+    uv_mutex_unlock(&state->mutex);
+}
+} // namespace
+
+TEST(LibuvSmokeTest, CanUseThreadMutexAndConditionTest) {
+    ThreadState state{};
+    state.ready = false;
+
+    ASSERT_EQ(0, uv_mutex_init(&state.mutex));
+    ASSERT_EQ(0, uv_cond_init(&state.cond));
+
+    uv_thread_t thread;
+    ASSERT_EQ(0, uv_thread_create(&thread, threadMain, &state));
+
+    uv_mutex_lock(&state.mutex);
+    while (!state.ready) {
+        uv_cond_wait(&state.cond, &state.mutex);
+    }
+    uv_mutex_unlock(&state.mutex);
+
+    EXPECT_EQ(0, uv_thread_join(&thread));
+    uv_cond_destroy(&state.cond);
+    uv_mutex_destroy(&state.mutex);
+}

Reply via email to