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); +}
