1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #28745 from JesusAnaya:fix-bundled-protobuf-include-priority

build: fix bundled protobuf headers being overridden by system-installed protobuf #28745

On macOS with Apple Clang 17, the compiler implicitly injects `/usr/local/include` as a high-priority user include (`-I`). The `SYSTEM` keyword in `target_include_directories` emits `-isystem` for the bundled protobuf path, which is searched after user `-I` paths, allowing a system-installed protobuf v4+ (which requires C++17 and abseil-cpp) to override the bundled headers.

Removing `SYSTEM` causes CMake to emit `-I` instead of `-isystem`, placing the bundled path before the implicit system include, restoring the intended header resolution order regardless of what protobuf version is installed on the host.

### Background

Apple Clang 17 (shipped with macOS 26 Tahoe Command Line Tools) changed the compiler driver behavior: it now unconditionally adds `-I/usr/local/include` to the search path, which is where Homebrew installs headers. Previous Apple Clang versions either omitted this path or added it as a lower-priority system include.

When Homebrew's `protobuf` is installed (v4+, e.g. `33.4_1`), its headers at `/usr/local/include/google/protobuf/` are resolved before the bundled `3rdparty/protobuf/src/` because `SYSTEM PUBLIC` in `target_include_directories` causes the bundled path to be emitted as `-isystem`, which ranks below `-I` in compiler search order. This was confirmed by inspecting the generated `flags.make`:

```
# before fix
-isystem /path/to/opencv/3rdparty/protobuf/src

# after fix
-I /path/to/opencv/3rdparty/protobuf/src   (first in the include list)
```

The system protobuf v4+ headers require C++17 and abseil-cpp. Since OpenCV 4.x compiles with `-std=c++11`, every translation unit in `3rdparty/protobuf/` fails:

```
/usr/local/include/google/protobuf/port_def.inc: error: Protobuf only supports C++17 and newer.
/usr/local/include/absl/base/policy_checks.h: error: C++ versions less than C++17 are not supported.
```

Note that `include_directories(BEFORE ...)` on the line above was intended to prevent exactly this, but it was overridden by `target_include_directories(SYSTEM PUBLIC ...)` deduplicating the path into a single `-isystem` entry. This is essentially the same class of problem tracked in #13328.

### Impact

The change is a one-line diff. Removing `SYSTEM` has no effect on Linux or Windows since those toolchains do not inject `/usr/local/include` implicitly. Warning suppression for protobuf headers in dependent modules is unaffected because OpenCV already applies explicit `-Wno-*` flags for all protobuf-related warnings in `3rdparty/protobuf/CMakeLists.txt`.

### Tested on

- macOS 26.3 (Tahoe), Apple Clang 17.0.0 (`clang-1700.6.4.2`), Homebrew `protobuf 33.4_1`, full build passes with `BUILD_PROTOBUF=ON`.

Fixes #28743, related to #27886.

### 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
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
  Patch to opencv_extra has the same branch name.
- [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
Jesus Armando Anaya
2026-04-17 00:53:45 -07:00
committed by GitHub
parent fa2bb7358a
commit 166c235603
+8
View File
@@ -477,6 +477,14 @@ if(APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT DEFINED ENV{LDFLAGS} AND EXISTS "/
link_directories("/usr/local/lib") link_directories("/usr/local/lib")
endif() endif()
if(APPLE AND NOT CMAKE_CROSSCOMPILING AND CV_CLANG AND EXISTS "/usr/local/include")
# Apple Clang 17+ implicitly injects -I/usr/local/include as a high-priority
# user include, causing system-installed headers (e.g. Homebrew protobuf v4+)
# to override bundled third-party libraries added via -isystem.
# Demote /usr/local/include to -isystem so bundled -isystem paths are searched first.
add_compile_options("-isystem/usr/local/include")
endif()
if(ENABLE_BUILD_HARDENING) if(ENABLE_BUILD_HARDENING)
include("${CMAKE_CURRENT_LIST_DIR}/OpenCVCompilerDefenses.cmake") include("${CMAKE_CURRENT_LIST_DIR}/OpenCVCompilerDefenses.cmake")
endif() endif()