Skip to content

[fix](build) stop building libhdfspp on macOS - #408

Merged
morningman merged 1 commit into
apache:hadoop-3.4.2from
morningman:hadoop-3.4.2-skip-libhdfspp-on-macos
Aug 16, 2026
Merged

[fix](build) stop building libhdfspp on macOS#408
morningman merged 1 commit into
apache:hadoop-3.4.2from
morningman:hadoop-3.4.2-skip-libhdfspp-on-macos

Conversation

@morningman

Copy link
Copy Markdown
Contributor

What

On macOS the libhdfspp tree now stops after the x-platform object libraries libhdfs pulls out of it. Linux and Windows are byte for byte unchanged.

This supersedes the NO_SASL half of #407. That guard stays — SASL had libhdfspp as its only consumer, so there is still no reason to look for it — but its comment is rewritten, because the link failure it describes can no longer happen.

Why

apache/doris#66800 adds hadoop_libs_3_4 to the macOS package list, so a macOS third-party build now runs this tree for the first time. The macos-14 leg of that CI run fails while linking libhdfspp.0.1.0.dylib:

Undefined symbols for architecture arm64:
  "std::exception_ptr::__from_native_exception_pointer(void*)", referenced from:
      std::__1::promise<hdfs::Status>::~promise() in filesystem_sync.cc.o
      std::__1::promise<std::__1::tuple<hdfs::Status, hdfs::FileHandle*>>::~promise() in filesystem_sync.cc.o
      ...
  "___cxa_init_primary_exception", referenced from:
      ...
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1
make[2]: *** [native/target/usr/local/lib/libhdfspp.0.1.0.dylib] Error 1

The symbols come from Homebrew's libc++ headers, the link comes from the SDK's libc++

Doris' macOS toolchain is Homebrew llvm@20 (env.sh puts it on PATH and derives CC/CXX from it). Homebrew builds libc++ with _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS 0 — it is right there in the installed __config_site:

$ grep VENDOR_AVAILABILITY /opt/homebrew/opt/llvm@20/include/c++/v1/__config_site
#define _LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS 0

With the annotations off, std::make_exception_ptr's post-macOS-14 fast path is emitted no matter what -mmacosx-version-min says. Two lines reproduce it:

$ cat t.cc
#include <future>
#include <string>
std::promise<std::string> p;
void f() { p.set_value("x"); }

$ /opt/homebrew/opt/llvm@20/bin/clang++ -std=c++17 -stdlib=libc++ -arch arm64 \
      -mmacosx-version-min=12.0 -c t.cc -o t.o
$ nm -u t.o | grep exception
__ZNSt13exception_ptr31__from_native_exception_pointerEPv
___cxa_init_primary_exception

The other half is the link line, which carries -stdlib=libc++ and nothing else — no -L$(brew --prefix llvm@20)/lib/c++, the flag Homebrew's own caveat tells you to add. So -lc++/-lc++abi resolve against the SDK's system libc++, not against the one whose headers were used:

$ clang++ -stdlib=libc++ -arch arm64 -mmacosx-version-min=12.0 \
      -isysroot .../MacOSX15.4.sdk -dynamiclib t.o -o t.dylib
$ otool -L t.dylib
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1900.178.0)

That link succeeds because the macOS 15 SDK exports both symbols from its libc++.tbd. The macOS 14 SDK does not, which is the entire difference between the two macOS legs of apache/doris#66800 — both run arm64 on the same Homebrew clang 20.1.8 with the same MACOSX_DEPLOYMENT_TARGET=12.0:

job runs-on SDK result
Build Third Party Libraries (macOS) macos-15 MacOSX15.5.sdk libhdfspp links
Build Third Party Libraries (macOS-arm64) macos-14 MacOSX14.5.sdk undefined symbols

This repo's own release automation is affected the same way: .github/workflows/build.yml builds the macOS-arm64 matrix entry — the one that produces doris-thirdparty-prebuilt-darwin-arm64 — on os: macos-14.

Why not just link Homebrew's libc++

Adding -L$(brew --prefix llvm@20)/lib/c++ -Wl,-rpath,... does fix the link, but it puts a Homebrew LLVM runtime dependency into an archive that gets redistributed and unpacked on machines that have no such prefix. Raising the runners to macos-15 only moves the problem: the dylib would then carry a system-libc++ symbol that does not exist on macOS 14, so it would fail to load there.

Neither cost is worth paying for a library nothing consumes. Doris never links libhdfspp — be/CMakeLists.txt sets BUILD_LIBHDFSPP OFF — so macOS simply does not build it.

Why the subdirectory is still added

#407 concluded that skipping add_subdirectory(main/native/libhdfspp) outright is not workable, and that is correct: libhdfs/CMakeLists.txt pulls $<TARGET_OBJECTS:x_platform_obj> and $<TARGET_OBJECTS:x_platform_obj_c_api> out of that tree, and dropping it yields No SOURCES given to target: hdfs.

The whole directory does not have to go, though. lib/x-platform is self-contained — six translation units, no protobuf, no Boost, no asio — so the guard sits inside libhdfspp/CMakeLists.txt, after the include_directories() and compile-flag blocks and before add_subdirectory(third_party/uriparser2):

if(APPLE)
    add_subdirectory(lib/x-platform)
    return()
endif()

Placing it there rather than in the parent is what keeps this a no-op for the objects that survive: -fPIC, -DHAVE_EXPLICIT_BZERO, -DUSE_X_PLATFORM_DIRENT, CMAKE_CXX_STANDARD 11 and the include lib search path are all already in effect above that line, so x-platform compiles exactly as it does today.

Of the 63 objects that went into libhdfspp.dylib on the failing run, 59 are no longer compiled on macOS — including all 15 generated .pb.cc files — and the dylib link that failed no longer happens.

Verification

macOS 26.5 / arm64, with the toolchain Doris' macOS CI uses: Homebrew llvm@20 (clang 20.1.8), CMake 3.22.1, JDK 17, MACOSX_DEPLOYMENT_TARGET=12.0, dependencies resolved from a Doris thirdparty prefix.

build.sh completes end to end — hadoop-common-project 9/9, hadoop-hdfs-project 7/7, hadoop-dist — and produces:

hadoop-3.4.2/lib/native/      libhadoop.1.0.0.dylib   159K  arm64
                              libhadoop.a             753K
                              libhadoop.dylib         159K
                              libhdfs.0.0.0.dylib     133K
                              libhdfs.a               1.4M
                              libhdfs.dylib           133K
hadoop-3.4.2/include/         hdfs.h

hadoop-libhdfs-3.4.2/native/  libhdfs.a               1.4M  arm64
                     include/ hdfs.h
                     common/  5 jars
                     hdfs/    10 jars

libhdfspp.dylib — 8.9M in #407's run — is gone; everything Doris consumes is still there. libhdfs.a still exports the full API, including this fork's hdfsSetLogger, plus hdfsGetLastExceptionRootCause, hdfsBuilderSetKerb5Conf, hdfsBuilderSetKeyTabFile, hdfsUnbufferFile, hdfsFileGetReadStatistics, hdfsHSync and hdfsHFlush.

Only the five x-platform objects are built out of the libhdfspp tree, and they carry the same flags they did when the whole library was built:

$ find target/main/native/libhdfspp -name '*.o'
lib/x-platform/CMakeFiles/x_platform_obj.dir/dirent.cc.o
lib/x-platform/CMakeFiles/x_platform_obj.dir/syscall_linux.cc.o
lib/x-platform/CMakeFiles/x_platform_obj.dir/utils.cc.o
lib/x-platform/CMakeFiles/x_platform_obj_c_api.dir/c-api/dirent.cc.o
lib/x-platform/CMakeFiles/x_platform_obj_c_api.dir/c-api/syscall.cc.o

$ grep CXX_FLAGS target/main/native/libhdfspp/lib/x-platform/CMakeFiles/x_platform_obj.dir/flags.make
CXX_FLAGS = -include cstdint -g -O2 -Wall -pthread -D_FILE_OFFSET_BITS=64
  -Wno-cast-function-type -Wno-unused-lambda-capture -Wall -Wextra -pedantic -g -fPIC
  -fno-strict-aliasing -stdlib=libc++ -Wno-deprecated-declarations
  -Wno-unused-local-typedef -arch arm64 -isysroot ... -mmacosx-version-min=12.0 -std=gnu++17

and they do reach libhdfs.anm -g finds 16 XPlatform symbols in it.

Note this cannot reproduce the original undefined-symbol failure locally: a macOS 26 SDK exports both symbols, exactly as the macOS 15 SDK does. What it does verify is that the macOS build no longer reaches that link at all, and that dropping libhdfspp costs libhdfs nothing.

On macOS the libhdfspp tree now stops after the x-platform object
libraries libhdfs pulls out of it.  Linux and Windows are unchanged.

libhdfspp.dylib does not link there.  It is compiled against Homebrew
LLVM's libc++ headers, configured with no Apple availability
annotations, so std::exception_ptr's post-macOS-14 entry points are
emitted whatever -mmacosx-version-min says, while -lc++ still resolves
against the SDK's system libc++.  Against a macOS 14 SDK that leaves
__cxa_init_primary_exception and
std::exception_ptr::__from_native_exception_pointer undefined, and the
failing dylib takes the whole make down with it - libhdfs.a included.

Doris never links libhdfspp (be/CMakeLists.txt sets BUILD_LIBHDFSPP
OFF), so teaching the link line about Homebrew's libc++ would only put
a Homebrew LLVM runtime dependency into a redistributed archive.  The
guard sits after the include directories and compile flags are set, so
the x-platform objects that survive compile exactly as before.

The NO_SASL guard added in apache#407 stays - SASL had libhdfspp as its only
consumer - but its comment is rewritten, since the link failure it
described can no longer happen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@morningman
morningman merged commit 5bedec7 into apache:hadoop-3.4.2 Aug 16, 2026
morningman added a commit to apache/doris that referenced this pull request Aug 17, 2026
…is (#66808)

### What problem does this PR solve?

Related PR: #66783, #66800

Problem Summary:

Picks up
[apache/doris-thirdparty#408](apache/doris-thirdparty#408),
tagged as `hadoop-3.4.2.4-for-doris`. The single change over
`hadoop-3.4.2.3-for-doris` is that macOS no longer builds `libhdfspp`.

That library does not link on macOS. It is compiled against Homebrew
LLVM's libc++ headers, which are configured with
`_LIBCPP_HAS_VENDOR_AVAILABILITY_ANNOTATIONS 0`, so
`std::exception_ptr`'s post-macOS-14 entry points are emitted whatever
`-mmacosx-version-min` says, while `-lc++` still resolves against the
SDK's system libc++. Against a macOS 14 SDK that leaves
`__cxa_init_primary_exception` and
`std::exception_ptr::__from_native_exception_pointer` undefined, and the
failing dylib takes the whole `make` down with it — `libhdfs.a`
included:

```
Undefined symbols for architecture arm64:
  "std::exception_ptr::__from_native_exception_pointer(void*)", referenced from:
      std::__1::promise<hdfs::Status>::~promise() in filesystem_sync.cc.o
      ...
ld: symbol(s) not found for architecture arm64
make[2]: *** [native/target/usr/local/lib/libhdfspp.0.1.0.dylib] Error 1
```

Doris never links libhdfspp — `be/CMakeLists.txt:251` sets
`BUILD_LIBHDFSPP OFF` — so the fork now stops after the x-platform
object libraries `libhdfs` pulls out of that tree. `libhdfs.a`,
`libhdfs.dylib`, `libhadoop.dylib`, `hdfs.h` and the jars are all
unchanged.

Linux is unaffected by the fork change, so this bump is a no-op there
beyond the new tag. It is a prerequisite for #66800, which is where a
macOS third-party build starts producing `lib/hadoop_hdfs_3_4/` and
therefore where the failure above shows up — on the `macos-14` runner
specifically. Note that master's `build-thirdparty.sh` still leaves
`hadoop_libs_3_4` out of the macOS package list, so the macOS legs of
this PR's CI do not exercise the fork change yet; #66800 is what turns
it on.

### Release note

None

### Check List (For Author)

- Test
    - [x] Manual test (add detailed scripts or steps below)

The fork was built end to end on macOS 26.5 / arm64 with the toolchain
the macOS CI uses (Homebrew `llvm@20`, CMake 3.22.1, JDK 17,
`MACOSX_DEPLOYMENT_TARGET=12.0`) before the tag was cut —
hadoop-common-project 9/9, hadoop-hdfs-project 7/7, hadoop-dist all
`BUILD SUCCESS`, producing

    ```
    lib/native/  libhadoop.dylib 159K   libhadoop.a 753K
                 libhdfs.dylib   133K   libhdfs.a   1.4M    arm64
    include/     hdfs.h
    ```

with no `libhdfspp.dylib` (8.9M previously), and `libhdfs.a` still
exporting `hdfsSetLogger`, `hdfsGetLastExceptionRootCause`,
`hdfsBuilderSetKerb5Conf`, `hdfsBuilderSetKeyTabFile`,
`hdfsUnbufferFile`, `hdfsFileGetReadStatistics`, `hdfsHSync` and
`hdfsHFlush`.

The tarball this PR points at was downloaded twice; the MD5 is stable
and the archive unpacks to `doris-thirdparty-hadoop-3.4.2.4-for-doris/`
as `HADOOP_LIBS_3_4_SOURCE` expects.

- Behavior changed:
- [x] No. Linux builds byte for byte the same library set; macOS drops a
library nothing links.

- Does this need documentation?
    - [x] No.

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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

Successfully merging this pull request may close these issues.

1 participant