diff --git a/.devcontainer/Containerfile b/.devcontainer/Containerfile index 2f145c4a6..741183825 100644 --- a/.devcontainer/Containerfile +++ b/.devcontainer/Containerfile @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -FROM docker.io/library/ubuntu:24.04@sha256:2e863c44b718727c860746568e1d54afd13b2fa71b160f5cd9058fc436217b30 as base +FROM docker.io/library/ubuntu:26.04@sha256:513c074113a871b51a8d16ab445c88779d6452d937a164fb5cc479f32668a41d as base # Install dependencies RUN DEBIAN_FRONTEND="noninteractive" apt-get update && \ diff --git a/.github/workflows/celix_etcdlib.yml b/.github/workflows/celix_etcdlib.yml index 9648fb189..493024650 100644 --- a/.github/workflows/celix_etcdlib.yml +++ b/.github/workflows/celix_etcdlib.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 timeout-minutes: 15 steps: - name: Checkout source code diff --git a/.github/workflows/celix_promise.yml b/.github/workflows/celix_promise.yml index 7e85fee9d..0be9222ae 100644 --- a/.github/workflows/celix_promise.yml +++ b/.github/workflows/celix_promise.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 timeout-minutes: 15 steps: - name: Checkout source code diff --git a/.github/workflows/conan_create.yml b/.github/workflows/conan_create.yml index 9e4ec651c..26c355adb 100644 --- a/.github/workflows/conan_create.yml +++ b/.github/workflows/conan_create.yml @@ -17,7 +17,7 @@ env: jobs: ubuntu-build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 strategy: fail-fast: false matrix: @@ -40,7 +40,7 @@ jobs: conan profile detect -f sed -i 's/compiler.cppstd=gnu14/compiler.cppstd=gnu17/g' `conan profile path default` echo "[tool_requires]" >> `conan profile path default` - echo "cmake/3.26.4" >> `conan profile path default` + echo "cmake/4.4.3" >> `conan profile path default` - name: Conan Cache id: cache-conan uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2 @@ -93,7 +93,7 @@ jobs: run: | conan profile detect -f echo "[tool_requires]" >> `conan profile path default` - echo "cmake/3.26.4" >> `conan profile path default` + echo "cmake/4.4.3" >> `conan profile path default` - name: Conan Cache id: cache-conan uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2 diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index a4c4adae8..ee9e6f335 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -6,7 +6,7 @@ on: jobs: container-conan-build-ubuntu: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 timeout-minutes: 120 steps: - name: Checkout source code @@ -52,7 +52,7 @@ jobs: "cd /home/celixdev/workspace && \ ctest --preset conan-debug --output-on-failure -j1" build-dev-container-images: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 timeout-minutes: 120 steps: - name: Checkout source code diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 831df12ca..afbed1ce6 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -11,7 +11,7 @@ env: jobs: coverage: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 timeout-minutes: 120 steps: - name: Checkout source code @@ -26,14 +26,14 @@ jobs: conan profile detect -f --name release sed -i 's/compiler.cppstd=gnu14/compiler.cppstd=gnu17/g' `conan profile path release` echo "[tool_requires]" >> `conan profile path release` - echo "cmake/3.26.4" >> `conan profile path release` + echo "cmake/4.4.3" >> `conan profile path release` # host profile conan profile detect -f sed -i 's/build_type=Release/build_type=Debug/g' `conan profile path default` sed -i 's/compiler.cppstd=gnu14/compiler.cppstd=gnu17/g' `conan profile path default` echo "[tool_requires]" >> `conan profile path default` - echo "cmake/3.26.4" >> `conan profile path default` + echo "cmake/4.4.3" >> `conan profile path default` - name: Conan Cache id: cache-conan uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2 @@ -72,7 +72,7 @@ jobs: source generators/conanrun.sh make coverage source generators/deactivate_conanrun.sh - lcx="lcov --output-file=coverage.info " && for i in `find . -name "*.info.cleaned"`; do lcx+=" --add-tracefile=$i"; done && $lcx + lcx="lcov --output-file=coverage.info --ignore-errors inconsistent,mismatch" && for i in `find . -name "*.info.cleaned"`; do lcx+=" --add-tracefile=$i"; done && $lcx - name: Codecov uses: codecov/codecov-action@125fc84a9a348dbcf27191600683ec096ec9021c #v4.4.1 if: github.repository_owner == 'apache' diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index bb07bafd3..061c84434 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -7,7 +7,7 @@ on: jobs: latest: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 steps: - name: Checkout source code uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c #v3.3.0 diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml index 3cce6f245..2d6513893 100644 --- a/.github/workflows/fuzzing.yml +++ b/.github/workflows/fuzzing.yml @@ -8,7 +8,7 @@ on: jobs: fuzz-utils: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 timeout-minutes: 30 steps: - name: Checkout source code diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index cf4420b50..505666f2e 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -31,7 +31,7 @@ jobs: run: | conan profile detect -f echo "[tool_requires]" >> `conan profile path default` - echo "cmake/3.26.4" >> `conan profile path default` + echo "cmake/4.4.3" >> `conan profile path default` - name: Conan Cache id: cache-conan uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2 diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 42282a7d8..eb4e949af 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -16,7 +16,7 @@ env: jobs: linux-build-conan: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 strategy: fail-fast: false matrix: @@ -39,14 +39,14 @@ jobs: conan profile detect -f --name release sed -i 's/compiler.cppstd=gnu14/compiler.cppstd=gnu17/g' `conan profile path release` echo "[tool_requires]" >> `conan profile path release` - echo "cmake/3.26.4" >> `conan profile path release` + echo "cmake/4.4.3" >> `conan profile path release` # host profile conan profile detect -f sed -i 's/build_type=Release/build_type=${{ matrix.type }}/g' `conan profile path default` sed -i 's/compiler.cppstd=gnu14/compiler.cppstd=gnu17/g' `conan profile path default` echo "[tool_requires]" >> `conan profile path default` - echo "cmake/3.26.4" >> `conan profile path default` + echo "cmake/4.4.3" >> `conan profile path default` - name: Conan Cache id: cache-conan uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2 @@ -92,7 +92,7 @@ jobs: linux-build-apt: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 strategy: fail-fast: false matrix: diff --git a/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc b/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc index 4e94ff11f..6f192c6e6 100644 --- a/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc +++ b/bundles/logging/log_admin/gtest/src/LogAdminTestSuite.cc @@ -290,9 +290,10 @@ static void logSinkFunction(void *handle, celix_log_level_e level, long logServi EXPECT_STREQ("test::Log1", logServiceName); } - vfprintf(stdout, format, formatArgs); - - fprintf(stdout, "\n"); + if (format) { + vfprintf(stdout, format, formatArgs); + fprintf(stdout, "\n"); + } } TEST_F(LogBundleTestSuite, LogServiceAndSink) { diff --git a/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc b/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc index 0bf6dbcb5..a4ff350cb 100644 --- a/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc +++ b/bundles/logging/log_helper/gtest/src/LogHelperTestSuite.cc @@ -69,8 +69,10 @@ TEST_F(LogHelperTestSuite, LogToLogSvc) { logSvc.vlogDetails= [](void *handle, celix_log_level_e, const char*, const char*, int, const char *format, va_list formatArgs) { auto* c = static_cast*>(handle); c->fetch_add(1); - vfprintf(stderr, format, formatArgs); - fprintf(stderr, "\n"); + if (format) { + vfprintf(stderr, format, formatArgs); + fprintf(stderr, "\n"); + } }; auto* props = celix_properties_create(); diff --git a/bundles/remote_services/discovery_common/CMakeLists.txt b/bundles/remote_services/discovery_common/CMakeLists.txt index aa94f2fb0..e0c6176a6 100644 --- a/bundles/remote_services/discovery_common/CMakeLists.txt +++ b/bundles/remote_services/discovery_common/CMakeLists.txt @@ -29,6 +29,7 @@ if (RSA_DISCOVERY_COMMON) src/endpoint_discovery_poller.c src/endpoint_discovery_server.c ) + set_target_properties(rsa_discovery_common PROPERTIES POSITION_INDEPENDENT_CODE ON) target_include_directories(rsa_discovery_common PUBLIC include PRIVATE src ${LIBXML2_INCLUDE_DIR}) celix_target_hide_symbols(rsa_discovery_common) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 0c9acc360..58306b4bf 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -680,7 +680,7 @@ static void discoveryZeroconfWatcher_refreshWatchedServices(discovery_zeroconf_w celix_steal_ptr(svcEntry); continue; } - char *instanceNameEnd = strrchr(key, '/'); + const char *instanceNameEnd = strrchr(key, '/'); if (instanceNameEnd == NULL || instanceNameEnd-key >= DZC_MAX_SERVICE_INSTANCE_NAME_LEN) { celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service instance key, %s.", key); continue; diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c index 5c02b5bbe..f57071b07 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c @@ -474,7 +474,7 @@ static int remoteServiceAdmin_callback(struct mg_connection *conn) { // rest = myservice/call const char *rest = uri+9; - char *interfaceStart = strchr(rest, '/'); + const char *interfaceStart = strchr(rest, '/'); int pos = interfaceStart - rest; char service[pos+1]; strncpy(service, rest, pos); diff --git a/cmake/Findcivetweb.cmake b/cmake/Findcivetweb.cmake index 1488e9b3e..73a77a3f8 100644 --- a/cmake/Findcivetweb.cmake +++ b/cmake/Findcivetweb.cmake @@ -27,11 +27,26 @@ if (NOT civetweb_FOUND) set(CIVETWEB_ENABLE_WEBSOCKETS TRUE CACHE BOOL "" FORCE) set(CIVETWEB_BUILD_TESTING FALSE CACHE BOOL "" FORCE) + set(CIVETWEB_ENABLE_ASAN FALSE CACHE BOOL "" FORCE) set(BUILD_SHARED_LIBS TRUE CACHE BOOL "" FORCE) - set(CMAKE_C_FLAGS "-Wno-error") FetchContent_MakeAvailable(civetweb) if (NOT TARGET civetweb::civetweb) add_library(civetweb::civetweb ALIAS civetweb-c-library) endif () + #CivetWeb inherits the top-level -Werror/-Wall flags via CMAKE_C_FLAGS, + #which newer compilers (GCC 15+/Clang 20+) turn into hard errors. + #CivetWeb is a third-party dependency: build it without -Werror. + foreach(_civetweb_tgt civetweb-c-library civetweb-c-executable civetweb-cpp-library) + if (TARGET ${_civetweb_tgt}) + get_target_property(_civetweb_cflags ${_civetweb_tgt} COMPILE_OPTIONS) + if (_civetweb_cflags) + list(REMOVE_ITEM _civetweb_cflags "-Werror" "-Wfatal-errors") + set_target_properties(${_civetweb_tgt} PROPERTIES COMPILE_OPTIONS "${_civetweb_cflags}") + endif () + target_compile_options(${_civetweb_tgt} PRIVATE -Wno-error) + endif () + endforeach() + unset(_civetweb_tgt) + unset(_civetweb_cflags) endif() diff --git a/cmake/celix_project/CodeCoverage.cmake b/cmake/celix_project/CodeCoverage.cmake index 7615b38fc..2426fd7c3 100644 --- a/cmake/celix_project/CodeCoverage.cmake +++ b/cmake/celix_project/CodeCoverage.cmake @@ -134,8 +134,8 @@ function (setup_target_for_coverage) # Capturing lcov counters and generating report COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/coverage - COMMAND ${LCOV_PATH} --directory ${COVERAGE_SCAN_DIR} --capture --output-file ${OUTPUT_FILE} - COMMAND ${LCOV_PATH} --remove ${OUTPUT_FILE} '**/error_injector/*' '**/mock/*' '**/.conan/*' '**/test/*' '**/gtest/*' '**/tst/*' '**/celix/gen/*' '**/googletest_project/*' '**/glog/*' '/usr/*' --output-file ${OUTPUT_FILE}.cleaned + COMMAND ${LCOV_PATH} --directory ${COVERAGE_SCAN_DIR} --capture --output-file ${OUTPUT_FILE} --ignore-errors inconsistent,mismatch,empty + COMMAND ${LCOV_PATH} --remove ${OUTPUT_FILE} '**/error_injector/*' '**/mock/*' '**/.conan/*' '**/test/*' '**/gtest/*' '**/tst/*' '**/celix/gen/*' '**/googletest_project/*' '**/glog/*' '/usr/*' --output-file ${OUTPUT_FILE}.cleaned --ignore-errors unused,empty,inconsistent #test dependencies, so that test is runned DEPENDENCIES ${TEST_TARGET_NAME} diff --git a/conanfile.py b/conanfile.py index 67d465a08..56402a90e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -222,7 +222,7 @@ def build_requirements(self): if self.options.enable_testing: self.test_requires("gtest/1.17.0") if self.options.enable_ccache: - self.build_requires("ccache/4.7.4") + self.build_requires("ccache/[>=4.8 <=4.10.2]") if self.options.enable_benchmarking: self.test_requires("benchmark/[>=1.6.2]") @@ -382,7 +382,7 @@ def requirements(self): or (self.options.build_rsa_remote_service_admin_dfi and self.options.enable_testing)): self.requires("libxml2/[>=2.9.9 <3.0.0]") if self.options.build_cxx_remote_service_admin: - self.requires("rapidjson/[>=1.1.0 <2.0.0]") + self.requires("rapidjson/[>1.1.0 <2.0.0 || >=cci.20200410]") if self.options.build_http_admin or self.options.build_rsa_discovery_common \ or self.options.build_rsa_remote_service_admin_dfi: self.requires("civetweb/1.16") diff --git a/documents/building/README.md b/documents/building/README.md index c750e17b7..5e6ecdfa8 100644 --- a/documents/building/README.md +++ b/documents/building/README.md @@ -25,7 +25,7 @@ Apache Celix aims to be support a broad range of UNIX platforms. Currently, the [continuous integration build server] builds and tests Apache Celix for: -* Ubuntu Jammy Jellyfish (22.04) +* Ubuntu Resolute Raccoon (26.04) * GCC * CLang * OSX @@ -54,7 +54,7 @@ The following packages (libraries + headers) should be installed on your system: * cmake (3.19 or higher) * Conan (2 or higher) -For Ubuntu 22.04, use the following commands: +For Ubuntu 26.04, use the following commands: ```bash sudo apt-get install -yq --no-install-recommends \ build-essential \ @@ -123,6 +123,19 @@ To see a complete overview of the available build options in the recipe you can conan inspect . | grep build_ ``` +#### CMake 4 and Jansson + +When building on a system with CMake 4 or higher, the following entry is needed in your Conan host +profile (for example, `debug`): + +```ini +[buildenv] +jansson/2.14:CMAKE_POLICY_VERSION_MINIMUM=3.5 +``` + +This is needed because Jansson 2.14 is based on an older version of CMake, and this entry sets the +minimum CMake policy version only in Jansson's build environment. + #### CMake Private Linking Workaround (Conan) When using Celix via Conan, you may encounter an [issue](https://github.com/apache/celix/issues/642) where `libzip.so` is not found by the linker. This is due to a [bug in Conan](https://github.com/conan-io/conan/issues/7192). @@ -164,7 +177,7 @@ The following packages (libraries + headers) should be installed on your system: * libcurl (used in framwork for setup and (among others) in remote services -For Ubuntu 22.04, use the following commands: +For Ubuntu 26.04, use the following commands: ```bash sudo apt-get update diff --git a/libs/etcdlib/src/etcd.c b/libs/etcdlib/src/etcd.c index 37d1e4295..a4b806f65 100644 --- a/libs/etcdlib/src/etcd.c +++ b/libs/etcdlib/src/etcd.c @@ -252,7 +252,7 @@ etcd_get_recursive_values(json_t *js_root, etcdlib_key_value_callback callback, static long long etcd_get_current_index(const char *headerData) { long long index = -1; - char *indexStr = strstr(headerData, ETCD_HEADER_INDEX); + const char *indexStr = strstr(headerData, ETCD_HEADER_INDEX); indexStr += strlen(ETCD_HEADER_INDEX); if (sscanf(indexStr, "%lld\n", &index) == 1) { diff --git a/libs/framework/gtest/src/ScheduledEventTestSuite.cc b/libs/framework/gtest/src/ScheduledEventTestSuite.cc index f2dd53f55..5edbac427 100644 --- a/libs/framework/gtest/src/ScheduledEventTestSuite.cc +++ b/libs/framework/gtest/src/ScheduledEventTestSuite.cc @@ -720,8 +720,10 @@ TEST_F(ScheduledEventTestSuite, ScheduledEventTimeoutLogTest) { output = stderr; } fprintf(output, "%s: ", celix_logLevel_toString(level)); - vfprintf(output, format, args); - fprintf(output, "\n"); + if (format) { + vfprintf(output, format, args); + fprintf(output, "\n"); + } }; celix_framework_setLogCallback(fw->getCFramework(), &logCount, logCallback); diff --git a/libs/utils/src/celix_hash_map.c b/libs/utils/src/celix_hash_map.c index bf36c3093..a6d5d291e 100644 --- a/libs/utils/src/celix_hash_map.c +++ b/libs/utils/src/celix_hash_map.c @@ -171,7 +171,7 @@ celix_status_t celix_hashMap_resize(celix_hash_map_t *map) { return CELIX_SUCCESS; } - size_t newCapacity = (size_t)floor((double)map->bucketsSize * CELIX_HASHMAP_CAPACITY_INCREASE_FACTOR); + size_t newCapacity = map->bucketsSize * CELIX_HASHMAP_CAPACITY_INCREASE_FACTOR; if (map->bucketsSize > CELIX_HASHMAP_MAXIMUM_INCREASE_VALUE) { //after a certain point, only increase with CELIX_HASHMAP_MAXIMUM_INCREASE_VALUE instead of a factor newCapacity = map->bucketsSize + CELIX_HASHMAP_MAXIMUM_INCREASE_VALUE; diff --git a/libs/utils/src/celix_log_utils.c b/libs/utils/src/celix_log_utils.c index 51f4861df..238bfc622 100644 --- a/libs/utils/src/celix_log_utils.c +++ b/libs/utils/src/celix_log_utils.c @@ -86,7 +86,7 @@ void celix_logUtils_vLogToStdout(const char *logName, celix_log_level_e level, c static pthread_mutex_t globalMutex = PTHREAD_MUTEX_INITIALIZER; void celix_logUtils_vLogToStdoutDetails(const char *logName, celix_log_level_e level, const char* file, const char* function, int line, const char *format, va_list formatArgs) { - if (level == CELIX_LOG_LEVEL_DISABLED) { + if (format == NULL || level == CELIX_LOG_LEVEL_DISABLED) { //silently ignore return; }