Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/dfss-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: dfss-macos

on:
pull_request:
paths:
- 'source/pdfss_cpp/**'
push:
branches: [main]
paths:
- 'source/pdfss_cpp/**'
workflow_dispatch:

jobs:
build-x86-64:
name: build darwin x86_64
runs-on: macos-15-intel
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: build dfss-cpp darwin (x86_64)
run: |
bash source/pdfss_cpp/linux_release.sh darwin lib
- name: smoke test
run: |
cd source/pdfss_cpp/output
test "$(uname -m)" = "x86_64"
file dfss-cpp-darwin-x86_64
./dfss-cpp-darwin-x86_64 --no_json --list
- name: upload artifact
uses: actions/upload-artifact@v4
with:
name: dfss-cpp-darwin-x86_64
path: source/pdfss_cpp/output/dfss-cpp-darwin-x86_64
retention-days: 14

build-arm64:
name: build darwin arm64
runs-on: macos-15
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v4
- name: build dfss-cpp darwin (arm64)
run: |
bash source/pdfss_cpp/linux_release.sh darwin lib
- name: smoke test
run: |
cd source/pdfss_cpp/output
test "$(uname -m)" = "arm64"
file dfss-cpp-darwin-arm64
./dfss-cpp-darwin-arm64 --no_json --list
- name: upload artifact
uses: actions/upload-artifact@v4
with:
name: dfss-cpp-darwin-arm64
path: source/pdfss_cpp/output/dfss-cpp-darwin-arm64
retention-days: 14
5 changes: 5 additions & 0 deletions source/pdfss_cpp/dfss_pip/dfss/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ def get_architecture():
return 'linux-amd64'
elif system == 'windows':
return 'win-amd64.exe'
elif system == 'darwin':
return 'darwin-x86_64'
if arch == 'amd64':
if system == 'linux':
return 'linux-amd64'
Expand All @@ -23,6 +25,9 @@ def get_architecture():
elif arch == 'i686' or arch == 'x86':
if system == 'windows':
return 'win-i686.exe'
elif arch == 'arm64':
if system == 'darwin':
return 'darwin-arm64'
elif arch == 'aarch64':
if system == 'linux':
return 'linux-arm64'
Expand Down
69 changes: 64 additions & 5 deletions source/pdfss_cpp/libs/build_libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,29 @@
set -e

unset build_shell
build_shell="$(dirname "$(readlink -f "$0")")"
if [[ "$(uname -s)" == "Darwin" ]]; then
# macOS 没有 readlink -f
build_shell="$(cd "$(dirname "$0")" && pwd -P)"
else
build_shell="$(dirname "$(readlink -f "$0")")"
fi

unset CROSS_COMPILE
unset CC
unset CXX
unset ARCH
unset CROSS_COMPILE

sudo rm -rf libssh*
sudo rm -rf zlib*
sudo rm -rf mbedtls*
if [[ "$(uname -s)" == "Darwin" ]]; then
# macOS 上不需要 sudo(解压目录属于当前用户),避免交互式密码卡住
rm -rf libssh*
rm -rf zlib*
rm -rf mbedtls*
else
sudo rm -rf libssh*
sudo rm -rf zlib*
sudo rm -rf mbedtls*
fi

tar -xaf "$(find ${build_shell}/zips/ -name "libssh2*")" -C ./
mv libssh2* libssh2
Expand All @@ -31,7 +43,11 @@ unset AR
unset CROSS_COMPILE

build_target="${build_shell}/${1}_build"
sudo rm -rf "${build_target}"
if [[ "$(uname -s)" == "Darwin" ]]; then
rm -rf "${build_target}"
else
sudo rm -rf "${build_target}"
fi

if [[ "$1" == "host" ]]; then
# host gcc
Expand Down Expand Up @@ -403,4 +419,47 @@ elif [[ "$1" == "sw_64" ]]; then
make -j$(nproc) VERBOSE=1 || exit 1
make install -j$(nproc)
popd #libssh2
elif [[ "$1" == "darwin" ]]; then
# macOS 本机编译(x86_64 / arm64 取决于当前 Mac),交叉编译 darwin 需要 macOS SDK,仅本机构建
if [[ "$(uname -s)" != "Darwin" ]]; then
echo "ERROR: darwin 目标必须在 macOS 主机上构建(需要 macOS SDK/工具链)。非 macOS 主机请构建 linux/win 目标。" >&2
exit 1
fi
rm -rf darwin_build
mkdir -p darwin_build
unset CROSS_COMPILE
unset CC
unset CXX

make_procs="$(sysctl -n hw.ncpu 2>/dev/null || echo 1)"

## zlib static
pushd "${build_shell}/zlib"
CC=gcc ./configure --prefix="${build_target}" --static
make clean
make -j"${make_procs}"
make install -j"${make_procs}"
popd #zlib

## mbedtls static
pushd "${build_shell}/mbedtls"
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=OFF -DUSE_STATIC_MBEDTLS_LIBRARY=ON -DUSE_SHARED_MBEDTLS_LIBRARY=OFF -DINSTALL_MBEDTLS_HEADERS=ON -DCMAKE_INSTALL_PREFIX="${build_target}" ..
make -j"${make_procs}"
make install -j"${make_procs}"
cd ..
popd #mbedtls

pushd "${build_target}"
ln -s lib lib64 2>/dev/null || true
popd

## libssh2 static
pushd "${build_shell}/libssh2"
./configure --disable-examples-build --disable-sshd-tests --disable-docker-tests --with-sysroot="${build_target}" --enable-static=yes --enable-shared=no --with-libmbedcrypto-prefix="${build_target}" --prefix="${build_target}" --with-crypto=mbedtls --with-libz --with-libz-prefix="${build_target}"
make clean
make -j"${make_procs}" VERBOSE=1 || exit 1
make install -j"${make_procs}"
popd #libssh2
fi
21 changes: 20 additions & 1 deletion source/pdfss_cpp/linux_release.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#!/bin/bash

build_shell="$(dirname "$(readlink -f "$0")")"
if [[ "$(uname -s)" == "Darwin" ]]; then
# macOS 没有 readlink -f
build_shell="$(cd "$(dirname "$0")" && pwd -P)"
else
build_shell="$(dirname "$(readlink -f "$0")")"
fi
# 脚本路径自包含:以下相对路径(libs/src/output)均以脚本所在目录为基准
cd "$build_shell"

if [[ "$2" == "lib" ]]; then
pushd libs
Expand Down Expand Up @@ -53,5 +60,17 @@ elif [[ "$1" == "sw_64" ]]; then
make clean
EXT_LIB_FLAG_STATIC=" -static -Wl,-Bstatic -lssh2 -lmbedcrypto -lpthread -lz " EXT_LIB_FLAG_DYNAMIC=" " EXT_FLAG=" " ARCH="sw_64" BUILD_PATH="${build_shell}" CROSS_COMPILE="sw_64-sunway-linux-gnu-" LIBS_TYPE="${build_target}" NEED_DEBUG="${NEED_DEBUG}" make VERBOSE=1
mv dfss-cpp ${build_shell}/output/dfss-cpp-linux-sw_64
elif [[ "$1" == "darwin" ]]; then
# macOS 本机编译(x86_64 / arm64 取决于当前 Mac),交叉编译 darwin 需要 macOS SDK,仅本机构建
if [[ "$(uname -s)" != "Darwin" ]]; then
echo "ERROR: darwin 目标必须在 macOS 主机上构建(需要 macOS SDK/工具链)。非 macOS 主机请构建 linux/win 目标。" >&2
exit 1
fi
make clean
MAC_ARCH="$(uname -m)"
export EXT_LIB_FLAG_STATIC=" -Wl,-force_load,${build_shell}/libs/darwin_build/lib/libssh2.a -Wl,-force_load,${build_shell}/libs/darwin_build/lib/libmbedtls.a -Wl,-force_load,${build_shell}/libs/darwin_build/lib/libmbedx509.a -Wl,-force_load,${build_shell}/libs/darwin_build/lib/libmbedcrypto.a -Wl,-force_load,${build_shell}/libs/darwin_build/lib/libz.a "
export EXT_LIB_FLAG_DYNAMIC=" -lpthread "
EXT_FLAG=" -mmacosx-version-min=10.15 " ARCH="${MAC_ARCH}" BUILD_PATH="${build_shell}" CROSS_COMPILE="" LIBS_TYPE="darwin_build" NEED_DEBUG="${NEED_DEBUG}" make VERBOSE=1
mv dfss-cpp ${build_shell}/output/dfss-cpp-darwin-${MAC_ARCH}
fi
popd
11 changes: 11 additions & 0 deletions source/pdfss_cpp/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ dfss的install功能可以方便地下载和安装软件包。
* riscv64 linux
* armbi linux
* sw_64 linux
* x86_64 darwin (macOS Intel)
* arm64 darwin (macOS Apple Silicon)

### 示例

Expand All @@ -60,8 +62,16 @@ dfss的install功能可以方便地下载和安装软件包。
./linux_release.sh riscv64 lib;
./linux_release.sh mingw lib;
./linux_release.sh mingw64 lib;
./linux_release.sh darwin lib;
```

### macOS 说明

* macOS 目标需在 Mac 本机上编译(交叉编译 darwin 需要 macOS SDK,Linux 环境下无法构建),`./linux_release.sh darwin lib` 会按当前 Mac 芯片生成对应架构产物
* Intel Mac (x86_64) 生成 `dfss-cpp-darwin-x86_64`,Apple Silicon (arm64) 生成 `dfss-cpp-darwin-arm64`
* 编译依赖 Xcode Command Line Tools(提供 clang/链接器等),依赖库 zlib/mbedtls/libssh2 会由 `libs/build_libs.sh` 自动构建静态版本
* 最低支持 macOS 10.15(`std::filesystem` 与 `clock_gettime` 依赖,构建时已显式指定 `-mmacosx-version-min=10.15`)

### 默认编译器版本

* amd64 linux gcc9.4(ubuntu20) static
Expand All @@ -72,6 +82,7 @@ dfss的install功能可以方便地下载和安装软件包。
* riscv64 linux gcc9.4(ubuntu20) static
* armbi linux gcc9.4(ubuntu20)
* sw_64 linux gcc8.3(ubuntu20) static
* darwin clang(macOS Xcode CLT) 静态库 zlib/mbedtls/libssh2 + 动态系统库

### 发布方式

Expand Down
14 changes: 10 additions & 4 deletions source/pdfss_cpp/release.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
#!/bin/bash
# pdfss_cpp 统一构建接口 (M1 规范 v0.1)
# 用法: bash release.sh [ARCH] [VERSION]
# ARCH: host(amd64) | arm64 | all(默认 host;all=8 架构,含 win/loongarch64/riscv64/sw_64/armbi)
# ARCH: host(amd64) | arm64 | darwin(macOS 本机) | all(默认 host;all=8 架构,含 win/loongarch64/riscv64/sw_64/armbi)
# VERSION: 显式版本号(默认读 git_version 文件)
# env OUTPUT_DIR: 产物目录(默认 <repo>/output/pdfss_cpp/)
# 注意: 多架构交叉需要对应工具链,全部在 sophon-tools-build 镜像内预置。
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
if [[ "$(uname -s)" == "Darwin" ]]; then
# macOS 没有 readlink -f
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
else
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
fi
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
ARCH="${1:-host}"
OUTPUT_DIR="${OUTPUT_DIR:-$REPO_ROOT/output/pdfss_cpp}"
Expand All @@ -19,10 +24,11 @@ echo "==> pdfss_cpp version=$VERSION"
case "$ARCH" in
host|amd64) TARGETS="host" ;;
arm64) TARGETS="aarch64" ;;
all) TARGETS="host aarch64 armbi loongarch64 riscv64 sw_64 mingw64 mingw" ;;
all) TARGETS="host aarch64 armbi loongarch64 riscv64 sw_64 mingw64 mingw" ;; # darwin 需在 macOS 主机单独构建
darwin) TARGETS="darwin" ;;
sw_64) TARGETS="sw_64" ;;
loongarch64) TARGETS="loongarch64" ;;
*) echo "ERROR: ARCH 必须是 host|amd64|arm64|all,得到: $ARCH" >&2; exit 1 ;;
*) echo "ERROR: ARCH 必须是 host|amd64|arm64|darwin|all,得到: $ARCH" >&2; exit 1 ;;
esac

mkdir -p "$OUTPUT_DIR"
Expand Down
6 changes: 5 additions & 1 deletion source/pdfss_cpp/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ ifeq ($(NEED_DEBUG),1)
STRIP_CMD := @echo "Skip stripping in debug mode"
else
BUILD_TYPE_FLAG := -O3
STRIP_CMD := $(STRIP) -v --strip-debug --strip-unneeded
ifeq ($(shell uname -s),Darwin)
STRIP_CMD := $(STRIP) -x
else
STRIP_CMD := $(STRIP) -v --strip-debug --strip-unneeded
endif
endif

CFLAGS = $(EXT_FLAG) -I. $(INCLUDE) $(LIBS) -std=gnu99 -Wall ${BUILD_TYPE_FLAG}
Expand Down
21 changes: 17 additions & 4 deletions source/pdfss_cpp/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@
#include <iostream>
#include <mutex>
#include <string>
#if defined(__GNUC__) && !defined(__clang__)
#if (__GNUC__ > 4) && (__GNUC__ < 8)
#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ > 4) && (__GNUC__ < 8)
#include <experimental/filesystem>
#else
#include <filesystem>
#endif
#endif

#include "cxxopts.hpp"
#include "httplib.h"
Expand All @@ -40,6 +38,10 @@
#include <unistd.h>
#endif

#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif

extern "C" {
#include "log.h"
}
Expand All @@ -54,7 +56,7 @@ extern "C" {

using namespace std;
using json = nlohmann::json;
#if (__GNUC__ > 4) && (__GNUC__ < 8)
#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ > 4) && (__GNUC__ < 8)
namespace fs = std::experimental::filesystem;
#else
namespace fs = std::filesystem;
Expand Down Expand Up @@ -1240,6 +1242,17 @@ std::string getExecutablePath() {
memset(buffer_in, 0, 1024);
#ifdef _WIN32
GetModuleFileNameA(NULL, buffer_in, sizeof(buffer_in));
#elif defined(__APPLE__)
uint32_t path_size = sizeof(buffer_in);
if (_NSGetExecutablePath(buffer_in, &path_size) != 0) {
return std::string();
}
// 解析符号链接,与 Linux /proc/self/exe 行为一致
char resolved_path[PATH_MAX];
if (realpath(buffer_in, resolved_path) != nullptr) {
return std::string(resolved_path);
}
return std::string(buffer_in);
#else
ssize_t len = readlink("/proc/self/exe", buffer_in, sizeof(buffer_in) - 1);
if (len != -1) {
Expand Down
Loading