supporting protobuf v22 and later(with abseil-cpp/C++17)#24372
supporting protobuf v22 and later(with abseil-cpp/C++17)#24372asmorkalov merged 8 commits intoopencv:4.xfrom
Conversation
|
I was relieved that the test passed completely. And this patch requires special setting to install protobuf v24+. How to install external protobuf v24 and abseil-cpp at Ubuntu 23.04.git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git checkout v4.24.4
git reset --hard
git submodule update --init --recursive
cd ..
cmake -S protobuf/third_party/abseil-cpp/ -B build_absl -GNinja -DCMAKE_CXX_STANDARD=17
cmake --build build_absl
sudo cmake --install build_absl
sudo ldconfig
cmake -S protobuf/ -B build_protobuf -GNinja -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=ON -DCMAKE_CXX_STANDARD=17
cmake --build build_protobuf
sudo cmake --install build_protobuf
sudo ldconfigAfter that, we can detect To test building opencv4 with options.cmake -S opencv -B build4-main_cxx17 -DCMAKE_CXX_STANDARD=17 -GNinja -DBUILD_PROTOBUF=OFF -DPROTOBUF_UPDATE_FILES=ON
cmake --build main_cxx17 If no patch, there are following errors./usr/bin/ld: modules/dnn/CMakeFiles/opencv_dnn.dir/attr_value.pb.cc.o: in function `absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <34>(char const (&) [34])':
attr_value.pb.cc:(.text._ZN4absl12lts_2023012512log_internal10LogMessagelsILi34EEERS2_RAT__Kc[_ZN4absl12lts_2023012512log_internal10LogMessagelsILi34EEERS2_RAT__Kc]+0x24): undefined reference to `absl::lts_20230125::log_internal::LogMessage::CopyToEncodedBuffer(std::basic_string_view<char, std::char_traits<char> >, absl::lts_20230125::log_internal::LogMessage::StringType)'
/usr/bin/ld: modules/dnn/CMakeFiles/opencv_dnn.dir/attr_value.pb.cc.o: in function `google::protobuf::MapKey::type() const [clone .part.0]':
... |
cmake/OpenCVFindProtobuf.cmake
Outdated
|
|
||
| if(HAVE_ABSL_STRINGS AND HAVE_ABSL_LOG) | ||
| list(APPEND CUSTOM_STATUS absl) | ||
| list(APPEND CUSTOM_STATUS_absl " abseil-cpp:" "YES (${ABSL_STRINGS_VERSION})" ) |
There was a problem hiding this comment.
abseil-cpp is a direct dependency of Protobuf, not OpenCV. Not sure that it has to be reported.
There was a problem hiding this comment.
When using protobuf v22 or later,
the dnn module directly references abseil-cpp library ( via *.pb.cc converted *.pb with protoc ).
Unfortunally, there is also a possibility that OpenCV Users may use a combination of protobuf and abseil-cpp versions that are not expected.
I think it is better to leave abseil-cpp version information as a cmake log.
It is helpful to investifate compile/runtime errors
kmtr@kmtr-VMware-Virtual-Platform:~/work/build4-main_cxx17/modules/dnn/CMakeFiles/opencv_dnn.dir$ nm attr_value.pb.cc.o | c++filt | grep "absl" | head -10
U absl::lts_20230125::log_internal::LogMessage::OstreamView::stream()
U absl::lts_20230125::log_internal::LogMessage::OstreamView::OstreamView(absl::lts_20230125::log_internal::LogMessage::LogMessageData&)
U absl::lts_20230125::log_internal::LogMessage::OstreamView::~OstreamView()
U absl::lts_20230125::log_internal::LogMessage::CopyToEncodedBuffer(std::basic_string_view<char, std::char_traits<char> >, absl::lts_20230125::log_internal::LogMessage::StringType)
0000000000000000 W absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <14>(char const (&) [14])
0000000000000000 W absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <22>(char const (&) [22])
0000000000000000 W absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <23>(char const (&) [23])
0000000000000000 W absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <2>(char const (&) [2])
0000000000000000 W absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <34>(char const (&) [34])
0000000000000000 t absl::lts_20230125::log_internal::LogMessage& absl::lts_20230125::log_internal::LogMessage::operator<< <48>(char const (&) [48]) [clone .isra.0]There was a problem hiding this comment.
I thought about it additionally.
When a user builds a protobuf, it is fully expected that the appropriate abseil-cpp version will be applied in the git submodule.
Therefore, I would like to delete the version log. thank you very much!
e.g. https://github.com/protocolbuffers/protobuf/tree/main/third_party
abseil-cpp @ fb3621f Update to latest absl LTS patch 20230802.1 (#14145)
There was a problem hiding this comment.
I removed it, thank you for your comment !
modules/dnn/CMakeLists.txt
Outdated
| ocv_add_accuracy_tests(${dnn_runtime_libs}) | ||
|
|
||
| if(NOT BUILD_PROTOBUF) | ||
| ocv_target_compile_definitions(opencv_test_dnn PRIVATE "OPENCV_DNN_EXTERNAL_PROTOBUF=1") |
There was a problem hiding this comment.
Does this need "if(TARGET opencv_test_dnn)" as well? I'm seeing:
CMake Error at cmake/OpenCVUtils.cmake:1517 (message):
ocv_target_compile_definitions: invalid target: 'opencv_test_dnn'
Call Stack (most recent call first):
modules/dnn/CMakeLists.txt:258 (ocv_target_compile_definitions)
There was a problem hiding this comment.
Hello, thank you for your comment, I agree with you.
When ENABLE_TESTS=OFF, same problem is occured.
I push additional patch to fix it.
|
Thanks, tested in OpenEmbedded environment where I've first seen this issue and with these changes it builds fine again. Thank you! |
cmake/OpenCVFindProtobuf.cmake
Outdated
| message(FATAL_ERROR "protobuf(v22 and later) and abseil-cpp request CMAKE_CXX_STANDARD=17 and later.") | ||
| endif() | ||
|
|
||
| ocv_check_modules(ABSL_STRINGS absl_strings) |
There was a problem hiding this comment.
Does abseil has cmake package? Can we use find_package instead of pkg_config and find_library?
|
Some time ago I've been able to build OpenCV with latest protobuf: #23791 (comment) And I did not need to explicitly link with abseil. Did something change over time or was my configuration different than yours in some way? Maybe you don't need to build abseil separately then it will be built as part of protobuf and will be linked automatically? |
Thank you for your comment. I found https://protobuf.dev/support/migration/#abseil There are two ways protobuf references abseil-cpp.
If Sorry, I'll need some time to work.
---- Add comment |
|
I tried to build protobuf@24.x and OpenCV. As in previous result only minor patch was needed (replace protobuf cmake package already searches for abseil (see if(NOT TARGET absl::strings)
find_package(absl CONFIG)
endif()and imported target already provides required interface link libraries (see # Create imported target protobuf::libprotobuf
add_library(protobuf::libprotobuf SHARED IMPORTED)
set_target_properties(protobuf::libprotobuf PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
INTERFACE_COMPILE_FEATURES "cxx_std_14"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "absl::absl_check;absl::absl_log;absl::algorithm;absl::base;absl::bind_front;absl::bits;absl::btree;absl::cleanup;absl::cord;absl::core_headers;absl::debugging;absl::die_if_null;absl::dynamic_annotations;absl::flags;absl::flat_hash_map;absl::flat_hash_set;absl::function_ref;absl::hash;absl::layout;absl::log_initialize;absl::log_severity;absl::memory;absl::node_hash_map;absl::node_hash_set;absl::optional;absl::span;absl::status;absl::statusor;absl::strings;absl::synchronization;absl::time;absl::type_traits;absl::utility;absl::variant"
)My script: PD=/work/protobuf/.build
build_pb() {
rm -rf ${PD}
mkdir -p ${PD} && pushd ${PD}
cmake -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-Dprotobuf_BUILD_TESTS=OFF \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \ # need to be compatible with dynamic linkage
-DCMAKE_INSTALL_PREFIX=install \
-Dprotobuf_BUILD_SHARED_LIBS=ON \ # static works as well
..
ninja install
popd
}
build_opencv() {
export LD_LIBRARY_PATH=${PD}/install/lib:${LD_LIBRARY_PATH} # need to set this for protoc to work
mkdir -p $D
pushd $D && rm -rf *
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=${PD}/install \
-DWITH_PROTOBUF=ON \
-DBUILD_PROTOBUF=OFF \
-DPROTOBUF_UPDATE_FILES=ON \
-Dprotobuf_MODULE_COMPATIBLE=ON \ # we still need this for command PROTOBUF_GENERATE_CPP
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_BUILD_TYPE=Release \
-DWITH_OPENCL=OFF \
../opencv
ninja
popd
}
build_pb
build_opencvIn previous PR I promised to integrate this patch to OpenCV, but completely forgot about it 🤦 |
|
I'm sorry to not finished this fix. I tried with Ubuntu23.04.
(1) (2) (3) |
|
Hello, I made the workaround clearly. ( I'll fix it after my job.. ) I tried to debug following command to check
If there is "CONFIG" in if NOT... Now my test code doesn't reference |
As I understood this is related to cmake's built-in protobuf search mechanism. It seem to be using pkg-config and can not correctly add abseil dependencies. Adding I'm working on an integration testing harness for protobuf, I'll try to provide some solution today or tomorrow. |
|
I believe it is better to wait your comments/suggestions. Thank you very much ! This problem ,which is related with linking However, it is not resolved clearly, it seems that there are many problems. I checked what cmake version Ubuntu LTS series uses.
|
|
I intended to maintain the old branch and commit the code without dependence on ABSL to the new branch. However, I made a mistake updating the same branch. The modifications are as expected. I'm sorry... |
cmake/OpenCVFindProtobuf.cmake
Outdated
| if(NOT USED_AFTER_CXX17) | ||
| message("CMAKE_CXX_STANDARD : ${CMAKE_CXX_STANDARD}") | ||
| message("protobuf : ${Protobuf_VERSION}") | ||
| message(FATAL_ERROR "protobuf(v22 and later) and abseil-cpp request CMAKE_CXX_STANDARD=17 and later.") |
There was a problem hiding this comment.
Usually OpenCV does not throw errors if an optional dependency can not be found or used - the dependecy just get turned off.
@asmorkalov , @opencv-alalek , what do you think? Should we show a warning and disable protobuf in case of configuration incompatibilty?
Here and below.
There was a problem hiding this comment.
Thank you for your review !
I would like to wait for comments for the direction of correction.
And unfortunately, there are some message(FATAL_ERROR) in this file like this block. If error is occured, they will stop configuration.
opencv/modules/dnn/CMakeLists.txt
Lines 133 to 135 in 5199850
opencv/modules/dnn/CMakeLists.txt
Lines 166 to 168 in 5199850
opencv/modules/dnn/CMakeLists.txt
Lines 228 to 230 in 5199850
There was a problem hiding this comment.
It is not a default configuration.
Need to explicitly specify BUILD_PROTOBUF=OFF to go here.
I believe we could these errors here.
There was a problem hiding this comment.
Thank you for your review!
Yes, it is clear. This is about protobuf, so I set HAVE_PROTOBUF=OFF if old cxx standard is used. (And I forget C++98 ...)
mshabunin
left a comment
There was a problem hiding this comment.
I've tested this PR using several different protobuf versions (https://github.com/mshabunin/protobuf-check), builds are fine, test had not run.
Overall looks good to me 👍 , except one question.
|
Thank you for testing with various protobuf versions! I also manually verified that there were no problems using the previous version of protobuf (v21), which does not require Abseil-cpp.
I relieve that there were no major problems with this modification. |
cmake/OpenCVFindProtobuf.cmake
Outdated
|
|
||
| if(HAVE_PROTOBUF) | ||
| if("${Protobuf_VERSION}" MATCHES [[[0-9]+.([0-9]+).[0-9]+]]) | ||
| string(COMPARE GREATER "${CMAKE_MATCH_1}" "21" REQUEST_AFTER_CXX17) # >=22 |
There was a problem hiding this comment.
What is the problem with if'(NOT (Protobuf_VERSION VERSION_LESS 22))?
https://cmake.org/cmake/help/latest/command/if.html#version-less
Any non-integer version component or non-integer trailing part of a version component effectively truncates the string at that point.
There was a problem hiding this comment.
Yes, It is better than my script. Thank you very much !
cmake/OpenCVFindProtobuf.cmake
Outdated
| if(REQUEST_AFTER_CXX17) | ||
| string(COMPARE GREATER "${CMAKE_CXX_STANDARD}" "16" USED_AFTER_CXX17) # >=17 | ||
|
|
||
| if(NOT USED_AFTER_CXX17) |
There was a problem hiding this comment.
Use if(GREATER) instead.
There was a problem hiding this comment.
This comparing result is used with "NOT", so I use LESS.
And I add to check C++98. Thank you !
cmake/OpenCVFindProtobuf.cmake
Outdated
| if(NOT USED_AFTER_CXX17) | ||
| message("CMAKE_CXX_STANDARD : ${CMAKE_CXX_STANDARD}") | ||
| message("protobuf : ${Protobuf_VERSION}") | ||
| message(FATAL_ERROR "protobuf(v22 and later) and abseil-cpp request CMAKE_CXX_STANDARD=17 and later.") |
There was a problem hiding this comment.
It is not a default configuration.
Need to explicitly specify BUILD_PROTOBUF=OFF to go here.
I believe we could these errors here.
cmake/OpenCVFindProtobuf.cmake
Outdated
| return() | ||
| endif() | ||
|
|
||
|
|
There was a problem hiding this comment.
I'm sorry I have small mistake that is inserting unnecessary blank line.I had created pull request to fix it.
|
@dkurt @opencv-alalek May I merge the patch? |
Supporting protobuf v22 and later(with abseil-cpp/C++17) opencv#24372 fix opencv#24369 related opencv#23791 1. This patch supports external protobuf v22 and later, it required abseil-cpp and c++17. Even if the built-in protobuf is upgraded to v22 or later, the dependency on abseil-cpp and the requirement for C++17 will continue. 2. Some test for caffe required patched protobuf, so this patch disable them. This patch is tested by following libraries. - Protobuf: /usr/local/lib/libprotobuf.so (4.24.4) - abseil-cpp: YES (20230125) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
Supporting protobuf v22 and later(with abseil-cpp/C++17) opencv#24372 fix opencv#24369 related opencv#23791 1. This patch supports external protobuf v22 and later, it required abseil-cpp and c++17. Even if the built-in protobuf is upgraded to v22 or later, the dependency on abseil-cpp and the requirement for C++17 will continue. 2. Some test for caffe required patched protobuf, so this patch disable them. This patch is tested by following libraries. - Protobuf: /usr/local/lib/libprotobuf.so (4.24.4) - abseil-cpp: YES (20230125) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
Supporting protobuf v22 and later(with abseil-cpp/C++17) opencv#24372 fix opencv#24369 related opencv#23791 1. This patch supports external protobuf v22 and later, it required abseil-cpp and c++17. Even if the built-in protobuf is upgraded to v22 or later, the dependency on abseil-cpp and the requirement for C++17 will continue. 2. Some test for caffe required patched protobuf, so this patch disable them. This patch is tested by following libraries. - Protobuf: /usr/local/lib/libprotobuf.so (4.24.4) - abseil-cpp: YES (20230125) ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
fix #24369
related #23791
Even if the built-in protobuf is upgraded to v22 or later,
the dependency on abseil-cpp and the requirement for C++17 will continue.
This patch is tested by following libraries.
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.