diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 396a6d5..7c8c34e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -99,7 +99,7 @@ jobs: run: sudo apt-get install -y protobuf-compiler libprotobuf-dev libprotoc-dev - name: Install Mac dependencies if: startsWith(matrix.os, 'macos') - run: brew install protobuf + run: brew install protobuf abseil - name: Run cmake tests run: | mkdir build-cmake/bin @@ -117,30 +117,55 @@ jobs: name: "MSVC CMake (${{ matrix.build-type }}, DLL: ${{ matrix.shared-lib }})" runs-on: windows-latest env: - PROTOBUF_VERSION: 3.15.6 + PROTOBUF_VERSION: 24.3 + ABSEIL_VERSION: "20230802.0" steps: - uses: actions/checkout@v2 - uses: ilammy/msvc-dev-cmd@v1 + with: + arch: amd64 - uses: actions/cache@v2 - id: cache + id: protobuf-cache with: path: ~/protobuf-bin key: ${{ env.PROTOBUF_VERSION }}-${{ matrix.shared-lib }}-${{ matrix.build-type}} - - name: Build and install protobuf - if: steps.cache.outputs.cache-hit != 'true' + - uses: actions/cache@v2 + id: abseil-cache + with: + path: ~/abseil-bin + key: ${{ env.ABSEIL_VERSION }}-${{ matrix.shared-lib }}-${{ matrix.build-type}} + - name: Build and install abseil + if: steps.abseil-cache.outputs.cache-hit != 'true' run: | cd ~ - C:\msys64\usr\bin\wget.exe https://github.com/protocolbuffers/protobuf/releases/download/v${{ env.PROTOBUF_VERSION }}/protobuf-cpp-${{ env.PROTOBUF_VERSION }}.zip - 7z x protobuf-cpp-${{ env.PROTOBUF_VERSION }}.zip - cd ~/protobuf-${{ env.PROTOBUF_VERSION }}/cmake && mkdir build && cd build - cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=~/protobuf-bin -Dprotobuf_BUILD_SHARED_LIBS=${{ matrix.shared-lib }} .. + git clone --depth=1 https://github.com/abseil/abseil-cpp.git -b ${{ env.ABSEIL_VERSION }} abseil + cd ~/abseil && mkdir build && cd build + cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_INSTALL_PREFIX=~/abseil-bin -DBUILD_SHARED_LIBS=${{ matrix.shared-lib }} -DABSL_PROPAGATE_CXX_STD=ON -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded${{ matrix.build-type == 'Debug' && 'Debug' || '' }}${{ matrix.shared-lib == 'ON' && 'DLL' || '' }} -DCMAKE_CXX_STANDARD=17 .. + nmake + nmake install + - name: Build and install utf8 compression algorithm + if: matrix.shared-lib == 'OFF' + run: | + cd ~ + git clone --depth=1 https://github.com/protocolbuffers/utf8_range.git utf8_range + cd ~/utf8_range && mkdir build && cd build + cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_INSTALL_PREFIX=~/utf8_range-bin -DCMAKE_CXX_STANDARD=17 -Dutf8_range_ENABLE_TESTS=OFF -DBUILD_SHARED_LIBS=OFF -Dabsl_ROOT=~/abseil-bin -DCMAKE_POLICY_DEFAULT_CMP0074=NEW -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_MSVC_RUNTIME_LIBRARY='MultiThreaded${{ matrix.build-type == 'Debug' && 'Debug' || '' }}' .. + nmake + nmake install + - name: Build and install protobuf + if: steps.protobuf-cache.outputs.cache-hit != 'true' + run: | + cd ~ + git clone --depth=1 https://github.com/protocolbuffers/protobuf.git -b v${{ env.PROTOBUF_VERSION }} protobuf + cd ~/protobuf && mkdir build && cd build + cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=~/protobuf-bin -Dprotobuf_BUILD_SHARED_LIBS=${{ matrix.shared-lib }} -DCMAKE_CXX_STANDARD=17 -Dprotobuf_BUILD_EXAMPLES=OFF -Dprotobuf_ABSL_PROVIDER=package -Dabsl_ROOT=~/abseil-bin -DABSL_PROPAGATE_CXX_STD=ON .. nmake nmake install - name: Run cmake tests run: | mkdir build-cmake/bin cd build-cmake/bin - cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DBUILD_TESTS=ON -DCMAKE_PREFIX_PATH=~/protobuf-bin -DCMAKE_INSTALL_PREFIX=protobuf-c-bin -DBUILD_SHARED_LIBS=${{ matrix.shared-lib }} .. + cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DBUILD_TESTS=ON -DCMAKE_INSTALL_PREFIX=~/protobuf-c-bin -DBUILD_SHARED_LIBS=${{ matrix.shared-lib }} -DProtobuf_ROOT="~/protobuf-bin" -Dabsl_ROOT="~/abseil-bin" -Dutf8_range_ROOT="~/utf8_range-bin" .. nmake nmake test nmake install diff --git a/build-cmake/CMakeLists.txt b/build-cmake/CMakeLists.txt index 6dbf193..1e7695c 100644 --- a/build-cmake/CMakeLists.txt +++ b/build-cmake/CMakeLists.txt @@ -5,8 +5,36 @@ SET(PACKAGE_URL https://github.com/protobuf-c/protobuf-c) SET(PACKAGE_DESCRIPTION "Protocol Buffers implementation in C") CMAKE_MINIMUM_REQUIRED(VERSION 3.10 FATAL_ERROR) +cmake_policy(SET CMP0074 NEW) +cmake_policy(SET CMP0091 NEW) +cmake_policy(SET CMP0112 NEW) -PROJECT(protobuf-c) +PROJECT(protobuf-c C CXX) + +if (MSVC AND NOT BUILD_SHARED_LIBS) + SET(Protobuf_USE_STATIC_LIBS ON) +endif (MSVC AND NOT BUILD_SHARED_LIBS) + +FIND_PACKAGE(Protobuf REQUIRED) +file(REAL_PATH "${PROTOBUF_INCLUDE_DIR}" PROTOBUF_INCLUDE_DIR) +INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) + +find_package(absl CONFIG) + +# for static protobuf libraries include the dependencies +if (Protobuf_USE_STATIC_LIBS) + get_property(protobuf_ABSL_USED_TARGETS DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" PROPERTY IMPORTED_TARGETS) + list(FILTER protobuf_ABSL_USED_TARGETS INCLUDE REGEX "absl::") + + find_package(utf8_range CONFIG) + + set(protobuf_UTF8_USED_TARGETS + $ + $ + ) +elseif(WIN32) + set(protobuf_ABSL_USED_TARGETS $) +endif() #options option(BUILD_PROTOC "Build protoc-gen-c" ON) @@ -37,6 +65,12 @@ if(MSVC) # using Visual Studio C++ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4267 /wd4244") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4244") + + # Allow matching protobuf runtime dependency + if(NOT BUILD_SHARED_LIBS) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif(NOT BUILD_SHARED_LIBS) + ENDIF() get_filename_component(MAIN_DIR ${CMAKE_CURRENT_SOURCE_DIR} PATH) @@ -58,6 +92,8 @@ target_include_directories(protobuf-c IF (MSVC AND BUILD_SHARED_LIBS) TARGET_COMPILE_DEFINITIONS(protobuf-c PRIVATE -DPROTOBUF_C_EXPORT) ENDIF (MSVC AND BUILD_SHARED_LIBS) +target_link_libraries(protobuf-c ${protobuf_ABSL_USED_TARGETS} ${protobuf_UTF8_USED_TARGETS}) +target_compile_features(protobuf-c PRIVATE cxx_std_17) INCLUDE_DIRECTORIES(${MAIN_DIR}) INCLUDE_DIRECTORIES(${MAIN_DIR}/protobuf-c) @@ -65,13 +101,6 @@ INCLUDE_DIRECTORIES(${MAIN_DIR}/protobuf-c) IF(BUILD_PROTOC) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # for generated files -if (MSVC AND NOT BUILD_SHARED_LIBS) - SET(Protobuf_USE_STATIC_LIBS ON) -endif (MSVC AND NOT BUILD_SHARED_LIBS) - -FIND_PACKAGE(Protobuf REQUIRED) -INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR}) - ENDIF() if (MSVC AND NOT BUILD_SHARED_LIBS) @@ -91,21 +120,61 @@ if (MSVC AND NOT BUILD_SHARED_LIBS) endforeach(flag_var) endif (MSVC AND NOT BUILD_SHARED_LIBS) +if(WIN32) + # Modify the environment to hint protoc where the plugin is + # prepend to PATH because github host runners have abseil dll pre-installed. + # Use %PATH% instead of actually inserting it. On Github runners the PATH is so long + # it makes the NMake generated commands to fail. + set(OS_PATH_VARIABLE "$\\;%PATH%") + + if(BUILD_SHARED_LIBS) + set(OS_PATH_VARIABLE "$\\;${OS_PATH_VARIABLE}") + if (TARGET absl::abseil_dll) + set(OS_PATH_VARIABLE "$\\;${OS_PATH_VARIABLE}") + endif() + endif() + +else(WIN32) + + set(OS_PATH_VARIABLE "$ENV{PATH}" ) + set(OS_PATH_VARIABLE "$:${OS_PATH_VARIABLE}") + +endif(WIN32) + IF(BUILD_PROTOC) SET(CMAKE_CXX_STANDARD 17) SET(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_CXX_EXTENSIONS OFF) -ADD_CUSTOM_COMMAND(OUTPUT protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I${PROTOBUF_INCLUDE_DIR} -I${MAIN_DIR} ${MAIN_DIR}/protobuf-c/protobuf-c.proto) -FILE(GLOB PROTOC_GEN_C_SRC ${MAIN_DIR}/protoc-c/*.h ${MAIN_DIR}/protoc-c/*.cc ) -ADD_EXECUTABLE(protoc-gen-c ${PROTOC_GEN_C_SRC} protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h) + +add_custom_target(protoc-generated-files + COMMAND ${CMAKE_COMMAND} -E env PATH="${OS_PATH_VARIABLE}" -- ${PROTOBUF_PROTOC_EXECUTABLE} + --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I${PROTOBUF_INCLUDE_DIR} + -I${MAIN_DIR} ${MAIN_DIR}/protobuf-c/protobuf-c.proto + COMMENT Running protoc on ${MAIN_DIR}/protobuf-c/protobuf-c.proto + BYPRODUCTS protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h + SOURCES ${MAIN_DIR}/protobuf-c/protobuf-c.proto +) + +file(GLOB PROTOC_GEN_C_SRC ${MAIN_DIR}/protoc-c/*.h ${MAIN_DIR}/protoc-c/*.cc ) +add_executable(protoc-gen-c + ${PROTOC_GEN_C_SRC} + ${CMAKE_CURRENT_BINARY_DIR}/protobuf-c/protobuf-c.pb.cc + ${CMAKE_CURRENT_BINARY_DIR}/protobuf-c/protobuf-c.pb.h +) +add_dependencies(protoc-gen-c protoc-generated-files) target_include_directories(protoc-gen-c PUBLIC $ $ ) -target_link_libraries(protoc-gen-c protobuf::libprotoc protobuf::libprotobuf) +target_link_libraries(protoc-gen-c + protobuf::libprotoc + protobuf::libprotobuf + ${protobuf_ABSL_USED_TARGETS} + ${protobuf_UTF8_USED_TARGETS} +) + +target_compile_features(protoc-gen-c PRIVATE cxx_std_17) IF (MSVC AND BUILD_SHARED_LIBS) TARGET_COMPILE_DEFINITIONS(protoc-gen-c PRIVATE -DPROTOBUF_USE_DLLS) @@ -115,13 +184,13 @@ IF (MSVC AND BUILD_SHARED_LIBS) ENDIF (MSVC AND BUILD_SHARED_LIBS) FUNCTION(GENERATE_TEST_SOURCES PROTO_FILE SRC HDR) - ADD_CUSTOM_COMMAND(OUTPUT ${SRC} ${HDR} - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} - ARGS --plugin=$ -I${MAIN_DIR} ${PROTO_FILE} --c_out=${CMAKE_CURRENT_BINARY_DIR} - DEPENDS protoc-gen-c) + ADD_CUSTOM_COMMAND(OUTPUT ${SRC} ${HDR} + COMMAND ${CMAKE_COMMAND} + ARGS -E env PATH="${OS_PATH_VARIABLE}" -- ${PROTOBUF_PROTOC_EXECUTABLE} + --plugin=$ -I${MAIN_DIR} ${PROTO_FILE} --c_out=${CMAKE_CURRENT_BINARY_DIR} + DEPENDS protoc-gen-c) ENDFUNCTION() - IF(BUILD_TESTS) ENABLE_TESTING() @@ -130,32 +199,37 @@ GENERATE_TEST_SOURCES(${TEST_DIR}/test.proto t/test.pb-c.c t/test.pb-c.h) ADD_EXECUTABLE(test-generated-code ${TEST_DIR}/generated-code/test-generated-code.c t/test.pb-c.c t/test.pb-c.h ) TARGET_LINK_LIBRARIES(test-generated-code protobuf-c) - ADD_CUSTOM_COMMAND(OUTPUT t/test-full.pb.cc t/test-full.pb.h - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I${MAIN_DIR} ${TEST_DIR}/test-full.proto) + COMMAND ${CMAKE_COMMAND} + ARGS -E env PATH="${OS_PATH_VARIABLE}" -- ${PROTOBUF_PROTOC_EXECUTABLE} + --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I${MAIN_DIR} ${TEST_DIR}/test-full.proto +) GENERATE_TEST_SOURCES(${TEST_DIR}/test-full.proto t/test-full.pb-c.c t/test-full.pb-c.h) ADD_EXECUTABLE(cxx-generate-packed-data ${TEST_DIR}/generated-code2/cxx-generate-packed-data.cc t/test-full.pb.h t/test-full.pb.cc protobuf-c/protobuf-c.pb.cc protobuf-c/protobuf-c.pb.h) -TARGET_LINK_LIBRARIES(cxx-generate-packed-data ${PROTOBUF_LIBRARY}) +TARGET_LINK_LIBRARIES(cxx-generate-packed-data + ${PROTOBUF_LIBRARY} + ${protobuf_ABSL_USED_TARGETS} + ${protobuf_UTF8_USED_TARGETS} +) IF (MSVC AND BUILD_SHARED_LIBS) TARGET_COMPILE_DEFINITIONS(cxx-generate-packed-data PRIVATE -DPROTOBUF_USE_DLLS) ENDIF (MSVC AND BUILD_SHARED_LIBS) FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/t/generated-code2) ADD_CUSTOM_COMMAND(OUTPUT t/generated-code2/test-full-cxx-output.inc - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/cxx-generate-packed-data ">t/generated-code2/test-full-cxx-output.inc" - DEPENDS cxx-generate-packed-data - ) + COMMAND ${CMAKE_COMMAND} + ARGS -E env PATH="${OS_PATH_VARIABLE}" -- cxx-generate-packed-data + ">t/generated-code2/test-full-cxx-output.inc" + DEPENDS cxx-generate-packed-data +) GENERATE_TEST_SOURCES(${TEST_DIR}/test-optimized.proto t/test-optimized.pb-c.c t/test-optimized.pb-c.h) ADD_EXECUTABLE(test-generated-code2 ${TEST_DIR}/generated-code2/test-generated-code2.c t/generated-code2/test-full-cxx-output.inc t/test-full.pb-c.h t/test-full.pb-c.c t/test-optimized.pb-c.h t/test-optimized.pb-c.c) TARGET_LINK_LIBRARIES(test-generated-code2 protobuf-c) - - GENERATE_TEST_SOURCES(${TEST_DIR}/issue220/issue220.proto t/issue220/issue220.pb-c.c t/issue220/issue220.pb-c.h) ADD_EXECUTABLE(test-issue220 ${TEST_DIR}/issue220/issue220.c t/issue220/issue220.pb-c.c t/issue220/issue220.pb-c.h) TARGET_LINK_LIBRARIES(test-issue220 protobuf-c) @@ -239,7 +313,18 @@ ADD_TEST(test-generated-code3 test-generated-code3) ADD_TEST(test-issue220 test-issue220) ADD_TEST(test-issue251 test-issue251) ADD_TEST(test-version test-version) + +if(WIN32) + set_tests_properties( + test-generated-code + test-generated-code2 + test-generated-code3 + test-issue220 + test-issue251 + test-version + PROPERTIES ENVIRONMENT "PATH=${WINDOWS_PATH_VARIABLE}\\;$" ) +endif(WIN32) + ENDIF() - INCLUDE(CPack)