Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Protobuf 22+ which can require either C++14 or C++17 #76

Closed
cho-m opened this issue Dec 25, 2023 · 9 comments
Closed

Add support for Protobuf 22+ which can require either C++14 or C++17 #76

cho-m opened this issue Dec 25, 2023 · 9 comments

Comments

@cho-m
Copy link

cho-m commented Dec 25, 2023

Since Protobuf 22, the minimum C++ standard is now C++14. If using recent Protobuf linked to Abseil, this may go up to C++17.

Looking at OSM code:

These both seem to force C++11 resulting in error:

[ 66%] Building CXX object osmpbf/CMakeFiles/osmpbf_shared.dir/fileformat.pb.cc.o
cd /tmp/osm-pbf-20231224-1763-27ruyv/OSM-binary-1.5.0/osmpbf && /opt/homebrew/Library/Homebrew/shims/mac/super/clang++ -Dosmpbf_shared_EXPORTS  -O3 -DNDEBUG -std=gnu++11 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -fPIC -MD -MT osmpbf/CMakeFiles/osmpbf_shared.dir/osmformat.pb.cc.o -MF CMakeFiles/osmpbf_shared.dir/osmformat.pb.cc.o.d -o CMakeFiles/osmpbf_shared.dir/osmformat.pb.cc.o -c /tmp/osm-pbf-20231224-1763-27ruyv/OSM-binary-1.5.0/osmpbf/osmformat.pb.cc
cd /tmp/osm-pbf-20231224-1763-27ruyv/OSM-binary-1.5.0/osmpbf && /opt/homebrew/Library/Homebrew/shims/mac/super/clang++ -Dosmpbf_shared_EXPORTS  -O3 -DNDEBUG -std=gnu++11 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -fPIC -MD -MT osmpbf/CMakeFiles/osmpbf_shared.dir/fileformat.pb.cc.o -MF CMakeFiles/osmpbf_shared.dir/fileformat.pb.cc.o.d -o CMakeFiles/osmpbf_shared.dir/fileformat.pb.cc.o -c /tmp/osm-pbf-20231224-1763-27ruyv/OSM-binary-1.5.0/osmpbf/fileformat.pb.cc
In file included from /tmp/osm-pbf-20231224-1763-27ruyv/OSM-binary-1.5.0/osmpbf/fileformat.pb.cc:4:
In file included from /tmp/osm-pbf-20231224-1763-27ruyv/OSM-binary-1.5.0/osmpbf/fileformat.pb.h:13:
In file included from /opt/homebrew/include/google/protobuf/port_def.inc:33:
In file included from /opt/homebrew/include/absl/base/attributes.h:37:
In file included from /opt/homebrew/include/absl/base/config.h:86:
/opt/homebrew/include/absl/base/policy_checks.h:79:2: error: "C++ versions less than C++14 are not supported."
#error "C++ versions less than C++14 are not supported."
 ^

There may be a way to use CMake meta features as Protobuf CMake files specify cxx_std_14 and Abseil CMake files specify cxx_std_17.

Alternatively, a way of letting user to just override CMAKE_CXX_STANDARD or an option to set value would help. Right now, -DCMAKE_CXX_STANDARD=17 doesn't work due to C++11 changes.

@joto
Copy link
Collaborator

joto commented Jan 6, 2024

I can not figure out how this is supposed to work with CMake. As I understand it setting the C++ standard in CMake should be a minimum and CMake should automatically figure out that an included library needs a newer version and then do the right thing. But it seems it doesn't do that. I have tried a different approach in the trial-cmake branch, but in that case it doesn't work either.

You should be able to add -std=c++17 to the CXXFLAGS environment variable and it should compile then. This is the approach used in our Github action script. Unfortunately that also fails on macOS because of some problem with Abseil that I don't understand but seems to be unrelated.

I can not test all of this on macOS except through Github action which is a pain. If you can shed any light on this and propose a solution I'd be greatful. There must be some way we can say: The minimum C++ version for our software is C++11 and CMake will combine this with the minimum version of all libraries used and do the right thing.

@cho-m
Copy link
Author

cho-m commented Jan 6, 2024

I don't know best way to handle.

At least the shared library seems to work if you switch to Protobuf's CMake files rather than the outdated ones provided by CMake, but I haven't figured out static library. I may need to build some static libs for Protobuf and/or Abseil first.

For shared, I tried following and CMake did pick -std=gnu++17

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 147d012..dadad15 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,8 @@ project(osmpbf VERSION 1.5.0)
 
 include(GNUInstallDirs)
 
-find_package(Protobuf REQUIRED)
+set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")
+find_package(Protobuf CONFIG REQUIRED)
 
 add_subdirectory(osmpbf)
 
diff --git a/osmpbf/CMakeLists.txt b/osmpbf/CMakeLists.txt
index 41f3c2a..b64d726 100644
--- a/osmpbf/CMakeLists.txt
+++ b/osmpbf/CMakeLists.txt
@@ -1,9 +1,9 @@
 protobuf_generate_cpp(CPPS HS fileformat.proto osmformat.proto)
 
-add_library(osmpbf STATIC ${CPPS})
-target_include_directories(osmpbf SYSTEM PUBLIC ${Protobuf_INCLUDE_DIRS})
-set_property(TARGET osmpbf PROPERTY CXX_STANDARD 11)
-install(TARGETS osmpbf ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+#add_library(osmpbf STATIC ${CPPS})
+#target_include_directories(osmpbf SYSTEM PUBLIC ${Protobuf_INCLUDE_DIRS})
+#set_property(TARGET osmpbf PROPERTY CXX_STANDARD 11)
+#install(TARGETS osmpbf ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
 add_library(osmpbf_shared SHARED ${CPPS})
 set_property(TARGET osmpbf_shared PROPERTY CXX_STANDARD 11)
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index c7e7002..ce10303 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -9,7 +9,7 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64)
 add_executable(osmpbf-outline osmpbf-outline.cpp)
 
 target_include_directories(osmpbf-outline SYSTEM PRIVATE ${ZLIB_INCLUDE_DIR})
-target_link_libraries(osmpbf-outline PRIVATE osmpbf ZLIB::ZLIB protobuf::libprotobuf)
+target_link_libraries(osmpbf-outline PRIVATE osmpbf_shared ZLIB::ZLIB protobuf::libprotobuf)
 set_property(TARGET osmpbf-outline PROPERTY CXX_STANDARD 11)
 
 install(TARGETS osmpbf-outline RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

@cho-m
Copy link
Author

cho-m commented Jan 6, 2024

Though, above example only works if Protobuf package includes CMake files, so may need to do some fallback onto MODULE mode.

find_package(Protobuf CONFIG)
if(NOT Protobuf_FOUND)
    find_package(Protobuf MODULE REQUIRED)
endif()

EDIT: I guess setting up link to protobuf lib would allow picking up C++ standard, but can't comment on functionality. Most repositories (Linux distros and Homebrew) don't provide static libs for Protobuf and its dependencies.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 147d012..52bd709 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,11 @@ project(osmpbf VERSION 1.5.0)
 
 include(GNUInstallDirs)
 
-find_package(Protobuf REQUIRED)
+set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "")
+find_package(Protobuf CONFIG)
+if(NOT Protobuf_FOUND)
+    find_package(Protobuf MODULE REQUIRED)
+endif()
 
 add_subdirectory(osmpbf)
 
diff --git a/osmpbf/CMakeLists.txt b/osmpbf/CMakeLists.txt
index 41f3c2a..2478f06 100644
--- a/osmpbf/CMakeLists.txt
+++ b/osmpbf/CMakeLists.txt
@@ -1,6 +1,7 @@
 protobuf_generate_cpp(CPPS HS fileformat.proto osmformat.proto)
 
 add_library(osmpbf STATIC ${CPPS})
+target_link_libraries(osmpbf PRIVATE protobuf::libprotobuf)
 target_include_directories(osmpbf SYSTEM PUBLIC ${Protobuf_INCLUDE_DIRS})
 set_property(TARGET osmpbf PROPERTY CXX_STANDARD 11)
 install(TARGETS osmpbf ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})

@joto
Copy link
Collaborator

joto commented Jan 7, 2024

I tried various things and I think I came up with a solution that should work everwhere. Instead of explicitly trying find_package() twice, this can be achieved by setting set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE). Please try the version in the trial-cmake branch to see whether it works for you.

@joto
Copy link
Collaborator

joto commented Feb 8, 2024

@cho-m Did you get a chance to check that version?

@chenrui333
Copy link

@joto the homebrew build for protobuf is actually compiled with the latest abseil (which requires cpp cxx 17), any chance of updating to cxx17?

this is our cmake config change, inreplace "CMakeLists.txt", "set(CMAKE_CXX_STANDARD 11)", "set(CMAKE_CXX_STANDARD 17)"

@cho-m
Copy link
Author

cho-m commented Mar 10, 2024

@cho-m Did you get a chance to check that version?

Sorry, just got around to this again.

The CMake should be fine in that branch. Homebrew has also used CMAKE_FIND_PACKAGE_PREFER_CONFIG as a workaround in some packages.

I've confirmed successful compilation with both:

  • Protobuf 25.3 (C++17)
  • Protobuf 3.20.3 (C++11)

@joto
Copy link
Collaborator

joto commented Mar 11, 2024

Thanks @cho-m, I have merged that code now. Closing this as fixed. I'll tag a release soon.

@joto joto closed this as completed Mar 11, 2024
@chenrui333
Copy link

Thanks @joto!! We shipped out c++17 change via Homebrew/homebrew-core#165865

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants