首页 > 解决方案 > NDK 项目 - 未能引用 fdsan 相关函数

问题描述

我正在开发一个使用 NDK 读取文件的项目(通过文件描述符)。该项目是用 cmake 构建的。

我正在尝试使用 ,但无论我做什么,对 fdsan 的任何引用都会失败

use of undeclared identifier 'android_fdsan_<x>

Error while executing process /Users/tim/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja with arguments {-C /Users/tim/Projects/Android/Shuttle2/taglib/lib/.cxx/cmake/debug/arm64-v8a artwork-provider file-scanner}
ninja: Entering directory `/Users/tim/Projects/Android/Shuttle2/taglib/lib/.cxx/cmake/debug/arm64-v8a'
[1/4] Building CXX object CMakeFiles/file-scanner.dir/FileScanner.cpp.o
FAILED: CMakeFiles/file-scanner.dir/FileScanner.cpp.o 
/Users/tim/Library/Android/sdk/ndk/21.0.6011959/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=aarch64-none-linux-android21 --gcc-toolchain=/Users/tim/Library/Android/sdk/ndk/21.0.6011959/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/Users/tim/Library/Android/sdk/ndk/21.0.6011959/toolchains/llvm/prebuilt/darwin-x86_64/sysroot  -Dfile_scanner_EXPORTS -I/Users/tim/Projects/Android/Shuttle2/taglib/lib/src/main/cpp/../../../distribution/taglib/include -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security   -std=gnu++11 -O0 -fno-limit-debug-info  -fPIC -MD -MT CMakeFiles/file-scanner.dir/FileScanner.cpp.o -MF CMakeFiles/file-scanner.dir/FileScanner.cpp.o.d -o CMakeFiles/file-scanner.dir/FileScanner.cpp.o -c /Users/tim/Projects/Android/Shuttle2/taglib/lib/src/main/cpp/FileScanner.cpp
In file included from /Users/tim/Projects/Android/Shuttle2/taglib/lib/src/main/cpp/FileScanner.cpp:18:
/Users/tim/Projects/Android/Shuttle2/taglib/lib/src/main/cpp/unique_fd.h:112:13: error: use of undeclared identifier 'android_fdsan_exchange_owner_tag'
        if (android_fdsan_exchange_owner_tag) {

我正在使用 CMake 3.10.2 和 ndkVersion 21.0.6011959 rc2。我正在 Android 29 上编译、定位和运行。

引用 fdsan 的头文件如下所示:

#pragma once

#include <android/fdsan.h>
#include <unistd.h>

#include <utility>

struct unique_fd {
    unique_fd() = default;

    explicit unique_fd(int fd) {
        reset(fd);
    }

    unique_fd(const unique_fd& copy) = delete;
    unique_fd(unique_fd&& move) {
        *this = std::move(move);
    }

    ~unique_fd() {
        reset();
    }

    unique_fd& operator=(const unique_fd& copy) = delete;
    unique_fd& operator=(unique_fd&& move) {
        if (this == &move) {
            return *this;
        }

        reset();

        if (move.fd_ != -1) {
            fd_ = move.fd_;
            move.fd_ = -1;

            // Acquire ownership from the moved-from object.
            exchange_tag(fd_, move.tag(), tag());
        }

        return *this;
    }

    int get() { return fd_; }

    int release() {
        if (fd_ == -1) {
            return -1;
        }

        int fd = fd_;
        fd_ = -1;

        // Release ownership.
        exchange_tag(fd, tag(), 0);
        return fd;
    }

    void reset(int new_fd = -1) {
        if (fd_ != -1) {
            close(fd_, tag());
            fd_ = -1;
        }

        if (new_fd != -1) {
            fd_ = new_fd;

            // Acquire ownership of the presumably unowned fd.
            exchange_tag(fd_, 0, tag());
        }
    }

private:
    int fd_ = -1;

    // The obvious choice of tag to use is the address of the object.
    uint64_t tag() {
        return reinterpret_cast<uint64_t>(this);
    }

    // These functions are marked with __attribute__((weak)), so that their
    // availability can be determined at runtime. These wrappers will use them
    // if available, and fall back to no-ops or regular close on pre-Q devices.
    static void exchange_tag(int fd, uint64_t old_tag, uint64_t new_tag) {
        if (android_fdsan_exchange_owner_tag) {
            android_fdsan_exchange_owner_tag(fd, old_tag, new_tag);
        }
    }

    static int close(int fd, uint64_t tag) {
        if (android_fdsan_close_with_tag) {
            return android_fdsan_close_with_tag(fd, tag);
        } else {
            return ::close(fd);
        }
    }
};

任何帮助将不胜感激。

标签: androidandroid-ndk

解决方案


您需要使用 Bionic 进行编译:它包含 fdsan 定义(特别是 bionic/libc/include/android/fdsan.h)


推荐阅读