diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 00000000..0c5cdf24 --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,21 @@ +# GitHub Actions for genCMPClient +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) Siemens AG, 2021-2025 + +name: Windows + +on: push +jobs: + cmake: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - name: cmake + run: | + mkdir build + cd build + $env:GENCMP_NO_SECUTILS=1; cmake .. + cmake --build . --config Release + + + diff --git a/CMakeLists.txt b/CMakeLists.txt index 2414f2a3..98472c7a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,16 @@ if(NOT DEFINED GENCMPCLIENT_VERSION) endif() message(STATUS "generic CMP client version " ${GENCMPCLIENT_VERSION}) +# Option to build shared or static library (default: SHARED) +option(BUILD_STATIC_LIBS "Build static libraries instead of shared" OFF) +if(BUILD_STATIC_LIBS) + set(GENCMP_LIB_TYPE STATIC) + message(STATUS "Building STATIC library") +else() + set(GENCMP_LIB_TYPE SHARED) + message(STATUS "Building SHARED library") +endif() + # set(CMAKE_VERBOSE_MAKEFILE ON) # set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # needed for sonarCloud scanner when using CMake @@ -133,15 +143,36 @@ if(NOT TARGET OpenSSL::Crypto) # not already done by superordinate module endif() endif() message(STATUS "using OpenSSL library ${OPENSSL_CRYPTO_LIBRARY}, ${OPENSSL_SSL_LIBRARY}") -if(NOT EXISTS "${OPENSSL_CRYPTO_LIBRARY}") - message(FATAL_ERROR "OpenSSL crypto library file does not exist: ${OPENSSL_CRYPTO_LIBRARY}") +# Handle cases where OPENSSL_CRYPTO_LIBRARY contains both debug and optimized versions +if(OPENSSL_CRYPTO_LIBRARY MATCHES "optimized|debug") + # Extract the actual library paths from the optimized/debug list + string(REGEX REPLACE ".*optimized;([^;]+).*" "\\1" OPENSSL_CRYPTO_LIB_RELEASE "${OPENSSL_CRYPTO_LIBRARY}") + string(REGEX REPLACE ".*debug;([^;]+).*" "\\1" OPENSSL_CRYPTO_LIB_DEBUG "${OPENSSL_CRYPTO_LIBRARY}") + + # Check if at least one version exists + set(CRYPTO_LIB_EXISTS FALSE) + if(DEFINED OPENSSL_CRYPTO_LIB_RELEASE AND EXISTS "${OPENSSL_CRYPTO_LIB_RELEASE}") + set(CRYPTO_LIB_EXISTS TRUE) + endif() + if(DEFINED OPENSSL_CRYPTO_LIB_DEBUG AND EXISTS "${OPENSSL_CRYPTO_LIB_DEBUG}") + set(CRYPTO_LIB_EXISTS TRUE) + endif() + + if(NOT CRYPTO_LIB_EXISTS) + message(FATAL_ERROR "Neither OpenSSL crypto library exists: ${OPENSSL_CRYPTO_LIBRARY}") + endif() +else() + # Single library path case + if(NOT EXISTS "${OPENSSL_CRYPTO_LIBRARY}") + message(FATAL_ERROR "OpenSSL crypto library file does not exist: ${OPENSSL_CRYPTO_LIBRARY}") + endif() endif() # workaround for using local OpenSSL builds by default expecting that # its dynamic libs have been installed in ./${LIB} when using the libs # see for binaries dynamically linked to OpenSSL the output of ${LDD} if(CMAKE_SYSTEM_NAME MATCHES "Windows") - set(USERS "^(\w:)?\\Users\\") + set(USERS "^([a-zA-Z]:)?\\\\Users\\\\") set(LIB "bin") else() set(USERS "^/(home|Users)/") @@ -208,13 +239,22 @@ endif() add_compile_definitions(DEBUG_UNUSED) add_compile_definitions(PEDANTIC) -add_compile_options(-pedantic) # -Werror is enabled only for development and CI, using Makefile_v1 without NDEBUG -add_compile_options( - -Wall -Woverflow -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wswitch - -Wsign-compare -Wformat -Wtype-limits -Wundef -Wconversion -Wunused-parameter) -add_compile_options(-Wno-c99-extensions -Wno-language-extension-token -Wno-declaration-after-statement -Wno-expansion-to-defined) -if(NOT DEFINED GENCMP_NO_SECUTILS) - add_compile_options(-Wno-sign-conversion -Wno-shorten-64-to-32 -Wno-shadow) + +if(MSVC) + # MSVC compiler flags + add_compile_options(/W4) # High warning level + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) + if(NOT DEFINED GENCMP_NO_SECUTILS) + message(FATAL_ERROR "Windows build is not (yet) supported for libSecUtils") + endif() +else() + # GCC/Clang compiler flags + add_compile_options(-pedantic) # -Werror is enabled only for development and CI, using Makefile_v1 without NDEBUG + add_compile_options( + -Wall -Woverflow -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wswitch + -Wsign-compare -Wformat -Wtype-limits -Wundef -Wconversion -Wunused-parameter) + add_compile_options(-Wno-c99-extensions -Wno-language-extension-token -Wno-declaration-after-statement -Wno-expansion-to-defined) + endif() # TODO maybe clean up code and re-enable property # set_property(TARGET ${LIBGENCMP_NAME} PROPERTY C_STANDARD 90) @@ -223,7 +263,7 @@ endif() # target_compile_features(${LIBGENCMP_NAME} PRIVATE c_std_90) # target_compile_features(cmpClient PRIVATE c_std_90) -add_library(${LIBGENCMP_NAME} SHARED +add_library(${LIBGENCMP_NAME} ${GENCMP_LIB_TYPE} "${PROJECT_SOURCE_DIR}/.github/workflows/build.yml" ${SRC_DIR}/genericCMPClient.c ) diff --git a/README.md b/README.md index 70a73acd..1b69902e 100644 --- a/README.md +++ b/README.md @@ -453,6 +453,35 @@ It is also possible to statically link with `libcmp.a`, by setting `STATIC_LIBCM For further details on optional environment variables, see the [`Makefile_v1`](Makefile_v1) and [`Makefile_src`](Makefile_src). +### Choosing between shared and static library + +When using CMake, by default a **shared library** (`.so` on Linux, `.dylib` on macOS, `.dll` on Windows) is built. + +To build a **static library** instead (`.a` on Linux/macOS, `.lib` on Windows), use the CMake option `-DBUILD_STATIC_LIBS=ON`: + +```bash +cmake -DBUILD_STATIC_LIBS=ON . +make +``` + +This will produce a static library (`libgencmp.a` or `gencmp.lib`) instead of a shared library. + +#### Examples: + +**Building shared library (default):** +```bash +cmake . +make +# Produces: libgencmp.so.2.0 (Linux), libgencmp.dylib (macOS), or gencmp.dll (Windows) +``` + +**Building static library:** +```bash +cmake -DBUILD_STATIC_LIBS=ON . +make +# Produces: libgencmp.a (Linux/macOS) or gencmp.lib (Windows) +``` + ## Building Build the software with diff --git a/src/genericCMPClient_util.c b/src/genericCMPClient_util.c index 4b7cc976..80dd452f 100644 --- a/src/genericCMPClient_util.c +++ b/src/genericCMPClient_util.c @@ -38,10 +38,27 @@ void UTIL_cleanse_free(OPTIONAL char *str) /* log.c: */ -#include +#ifdef _WIN32 + /* Windows doesn't have syslog, so we'll use Windows Event Log or just disable syslog */ + #define LOG_EMERG 0 + #define LOG_ALERT 1 + #define LOG_CRIT 2 + #define LOG_ERR 3 + #define LOG_WARNING 4 + #define LOG_NOTICE 5 + #define LOG_INFO 6 + #define LOG_DEBUG 7 + static void syslog(int priority, const char *format, ...) { + /* Stub implementation for Windows - could be enhanced to use Windows Event Log */ + (void)priority; + (void)format; + } +#else + #include +#endif -static const char *const GENCMP_NAME = "genCMPClient"; -static const size_t loc_len = 256; +#define GENCMP_NAME "genCMPClient" +#define loc_len 256 /*!< these variables are shared between threads */ static LOG_cb_t LOG_fn = 0;