diff --git a/.github/workflows/prebuilt-tdlib.yml b/.github/workflows/prebuilt-tdlib.yml index 0f11454..f5c52b9 100644 --- a/.github/workflows/prebuilt-tdlib.yml +++ b/.github/workflows/prebuilt-tdlib.yml @@ -20,143 +20,149 @@ on: # NOTE: The ZLIB_USE_STATIC_LIBS option requires CMake >= 3.24 jobs: build-linux-x64: - name: Build TDLib (GNU/Linux x86_64) - runs-on: ubuntu-latest + name: Build TDLib (Linux x86_64 glibc) + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v27 with: - repository: 'tdlib/td' - ref: ${{ inputs.tdlib }} - - name: Create a build script - run: | - cat > prebuilt-tdlib-docker.sh <> info.txt - ldd --version | grep ldd >> info.txt - openssl version >> info.txt - sed -n 's/#define ZLIB_VERSION "\([^"]*\)"/zlib version: \1/p' /hbb_shlib/include/zlib.h >> info.txt - EOF - - name: Build in docker + nix_path: nixpkgs=channel:nixos-unstable + - name: Build TDLib run: | + set -ex + cd packages/prebuilt-tdlib mkdir to-upload - docker run -v $(pwd):/td ghcr.io/phusion/holy-build-box/hbb-64 \ - bash /td/prebuilt-tdlib-docker.sh - - name: Info - working-directory: to-upload - run: | - cat info.txt - echo "-----" - du -hs libtdjson.so - ldd libtdjson.so + _fetchparams=$(nix run nixpkgs#nix-prefetch-github -- \ + tdlib td --rev "${{ inputs.tdlib }}" --no-deep-clone) + nix-build build-scripts/tdlib-linux.nix --arg fetchparams "''$_fetchparams''" -v + tree result/ + cp -L ./result/lib/libtdjson.so to-upload/libtdjson.so + ldd to-upload/libtdjson.so + # - name: Setup tmate session + # uses: mxschmitt/action-tmate@v3 + # if: always() + # with: + # limit-access-to-actor: true - uses: actions/upload-artifact@v4 with: name: tdlib-linux-x64 path: to-upload - build-macos: - name: Build TDLib (macOS universal) - runs-on: macos-12 - env: - openssl_dir: /usr/local/opt/custom_openssl - openssl_tag: '1.1.2100' # OpenSSL 1.1.1u - zlib_ver: '1.2.13' - zlib_dir: /usr/local/opt/custom_zlib + build-macos-x64: + name: Build TDLib (macOS x86_64) + runs-on: macos-13 + steps: + # - uses: actions/checkout@v4 + # with: + # repository: 'tdlib/td' + # ref: ${{ inputs.tdlib }} + # - name: Install dependencies (homebrew) + # run: HOMEBREW_NO_INSTALL_CLEANUP=1 brew install gperf zlib openssl + # - name: Build TDLib + # run: | + # set -ex + # cmake --version + # mkdir -p to-upload && mkdir -p build && cd build + # MACOSX_DEPLOYMENT_TARGET=10.14 cmake \ + # -DCMAKE_BUILD_TYPE=Release \ + # -DCMAKE_OSX_ARCHITECTURES='x86_64' \ + # -DOPENSSL_USE_STATIC_LIBS=TRUE \ + # -DZLIB_USE_STATIC_LIBS=TRUE \ + # -DZLIB_LIBRARY=/usr/local/opt/zlib/lib/libz.a \ + # -DZLIB_INCLUDE_DIR=/usr/local/opt/zlib/include \ + # -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl \ + # .. + # cmake --build . --target tdjson -- -j 4 + # cd .. + # cp -L build/libtdjson.dylib to-upload/libtdjson.dylib + # cd to-upload + # install_name_tool -id @rpath/libtdjson.dylib libtdjson.dylib + # echo "clang:" >> info.txt && clang --version >> info.txt + # echo "openssl:" >> info.txt && /usr/local/opt/openssl/bin/openssl version >> info.txt + # file libtdjson.dylib + # otool -L libtdjson.dylib + - uses: actions/checkout@v4 + - uses: cachix/install-nix-action@v27 + with: + nix_path: nixpkgs=channel:nixpkgs-unstable + - name: Build TDLib + run: | + set -ex + cd packages/prebuilt-tdlib + mkdir to-upload + _url="https://github.com/tdlib/td/archive/${{ tdlib }}.tar.gz" + _hash=(nix-prefetch-url --type sha256 --unpack $_url) + nix-build build-scripts/tdlib-macos.nix -v --argstr url $_url --argstr hash $_hash + tree result/ + cp -L ./result/lib/libtdjson.dylib to-upload/libtdjson.dylib + otool -L to-upload/libtdjson.dylib + - uses: actions/upload-artifact@v4 + with: + name: temp-macos-x64 + path: to-upload + build-macos-arm64: + name: Build TDLib (macOS arm64) + runs-on: macos-14 steps: - uses: actions/checkout@v4 with: repository: 'tdlib/td' ref: ${{ inputs.tdlib }} - - name: Install gperf via homebrew - run: HOMEBREW_NO_INSTALL_CLEANUP=1 brew install gperf - - name: CMake version - run: cmake --version - # https://github.com/up9cloud/ios-libtdjson/blob/d4426dca16933b6178acb030955de92f040b7574/build.sh - - name: Download pre-built OpenSSL - run: | - # around 80 mb - curl -SL https://github.com/krzyzanowskim/OpenSSL/archive/refs/tags/${openssl_tag}.tar.gz -o OpenSSL.tar.gz - tar xzf OpenSSL.tar.gz - # As for now, MACOSX_DEPLOYMENT_TARGET in these pre-built openssl binaries should be 10.13 - mv OpenSSL-${openssl_tag}/macosx ${openssl_dir} - - name: Download and build zlib - run: | - set -x - curl -SL https://github.com/madler/zlib/releases/download/v${zlib_ver}/zlib-${zlib_ver}.tar.gz -o zlib.tar.gz - tar xzf zlib.tar.gz - cd zlib-${zlib_ver} - MACOSX_DEPLOYMENT_TARGET=10.14 CFLAGS="-O2 -mmacosx-version-min=10.14 -arch x86_64" \ - ./configure --static --prefix=${zlib_dir} - MACOSX_DEPLOYMENT_TARGET=10.14 make - make install && rm ${zlib_dir}/lib/libz.a - cp libz.a libz-x86_64.a - make clean - MACOSX_DEPLOYMENT_TARGET=11.0 CFLAGS="-O2 -mmacosx-version-min=11.0 -arch arm64" \ - ./configure --static - MACOSX_DEPLOYMENT_TARGET=11.0 make - mv libz.a libz-arm64.a - lipo -create libz-x86_64.a libz-arm64.a -output libz.a - cp libz.a ${zlib_dir}/lib/libz.a + - name: Install dependencies (homebrew) + run: HOMEBREW_NO_INSTALL_CLEANUP=1 brew install gperf zlib openssl - name: Build TDLib run: | - mkdir to-upload - mkdir -p build && cd build - MACOSX_DEPLOYMENT_TARGET=10.14 cmake \ + set -ex + cmake --version + mkdir -p to-upload && mkdir -p build && cd build + MACOSX_DEPLOYMENT_TARGET=11.0 cmake \ -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_OSX_ARCHITECTURES='x86_64;arm64' \ - -DOPENSSL_USE_STATIC_LIBS=TRUE -DZLIB_USE_STATIC_LIBS=TRUE \ - -DOPENSSL_FOUND=1 \ - -DOPENSSL_CRYPTO_LIBRARY=${openssl_dir}/lib/libcrypto.a \ - -DOPENSSL_SSL_LIBRARY=${openssl_dir}/lib/libssl.a \ - -DOPENSSL_LIBRARIES="${openssl_dir}/lib/libcrypto.a;${openssl_dir}/lib/libssl.a" \ - -DOPENSSL_INCLUDE_DIR=${openssl_dir}/include \ - -DZLIB_INCLUDE_DIR=${zlib_dir}/include \ - -DZLIB_LIBRARY=${zlib_dir}/lib/libz.a \ + -DCMAKE_OSX_ARCHITECTURES='arm64' \ + -DOPENSSL_USE_STATIC_LIBS=TRUE \ + -DZLIB_USE_STATIC_LIBS=TRUE \ + -DZLIB_LIBRARY=/opt/homebrew/zlib/lib/libz.a \ + -DZLIB_INCLUDE_DIR=/opt/homebrew/zlib/include \ + -DOPENSSL_ROOT_DIR=/opt/homebrew/openssl \ .. - cmake --build . --target tdjson -- -j 3 + cmake --build . --target tdjson -- -j 2 cd .. cp -L build/libtdjson.dylib to-upload/libtdjson.dylib - install_name_tool -id @rpath/libtdjson.dylib to-upload/libtdjson.dylib - - name: Info - working-directory: to-upload - run: | - touch info.txt - grep OPENSSL_VERSION_TEXT ${openssl_dir}/include/openssl/opensslv.h | sed 's/.*"\([^"]*\)"/\1/' >> info.txt - echo "zlib version: ${zlib_ver}" >> info.txt - otool -L libtdjson.dylib >> info.txt - cat info.txt - echo "-----" - uname -a + cd to-upload + install_name_tool -id @rpath/libtdjson.dylib libtdjson.dylib + echo "clang:" >> info.txt && clang --version >> info.txt + echo "openssl:" >> info.txt && /opt/homebrew/openssl/bin/openssl version >> info.txt file libtdjson.dylib - du -hs libtdjson.dylib - otool -arch x86_64 -l libtdjson.dylib - echo "---" - otool -arch arm64 -l libtdjson.dylib + otool -L libtdjson.dylib - uses: actions/upload-artifact@v4 with: - name: tdlib-macos + name: temp-macos-arm64 + path: to-upload + build-macos: + name: Create universal macOS shared library + needs: [build-macos-x64, build-macos-arm64] + runs-on: macos-13 + steps: + - uses: actions/download-artifact@v4 + with: + name: temp-macos-* + merge-multiple: true + - name: Combine shared libraries + run: | + mkdir -p to-upload + lipo temp-macos-x64/libtdjson.dylib temp-macos-arm64/libtdjson.dylib \ + -output to-upload/libtdjson.dylib -create + cd to-upload + echo "--x86_64--" >> info.txt + cat ../temp-macos-x64/libtdjson.dylib >> info.txt + echo "--arm64--" >> info.txt + cat ../temp-macos-arm64/libtdjson.dylib >> info.txt + - uses: actions/upload-artifact@v4 + with: + name: build-macos path: to-upload build-windows-x64: name: Build TDLib (Windows x86_64) runs-on: windows-2019 + if: ${{ false }} steps: - uses: actions/checkout@v4 with: @@ -182,12 +188,10 @@ jobs: -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake ` -DVCPKG_TARGET_TRIPLET=x64-windows-static ` -DOPENSSL_USE_STATIC_LIBS=TRUE -DZLIB_USE_STATIC_LIBS=TRUE .. - cmake --build . --target tdjson --config Release --parallel 2 + cmake --build . --target tdjson --config Release --parallel 4 cd .. cp build\Release\tdjson.dll to-upload\tdjson.dll - - name: Info - # It should be possible to print the dependencies using dumpbin.exe - run: | + # It should be possible to print the dependencies using dumpbin.exe vcpkg list | Select-String openssl,zlib > to-upload\info.txt cat to-upload\info.txt - uses: actions/upload-artifact@v4 @@ -245,6 +249,7 @@ jobs: pattern: tdlib-* path: packages/prebuilt-tdlib/prebuilds - run: tree packages/prebuilt-tdlib + - run: du -hsc packages/prebuilt-tdlib/prebuilds/* - run: npm run test:integration env: PREBUILT_PATH: packages/prebuilt-tdlib diff --git a/.github/workflows/publish-tdl.yml b/.github/workflows/publish-tdl.yml index c84dd5d..0838702 100644 --- a/.github/workflows/publish-tdl.yml +++ b/.github/workflows/publish-tdl.yml @@ -24,6 +24,8 @@ jobs: node-version: lts/* cache: npm - uses: goto-bus-stop/setup-zig@v2 + with: + version: '0.13.0' if: runner.os == 'Linux' - name: Install dependencies run: npm install diff --git a/packages/prebuilt-tdlib/build-scripts/tdlib-linux.nix b/packages/prebuilt-tdlib/build-scripts/tdlib-linux.nix new file mode 100644 index 0000000..95f5140 --- /dev/null +++ b/packages/prebuilt-tdlib/build-scripts/tdlib-linux.nix @@ -0,0 +1,37 @@ +{ fetchparams }: +let + pkgs = import {}; + inherit (pkgs) lib stdenv; +in +# Based on https://github.com/NixOS/nixpkgs/blob/af51e23ce535b1bfa8484021ff3913d876e09082/pkgs/development/libraries/tdlib/default.nix +stdenv.mkDerivation { + pname = "tdlib"; + version = "0.0"; + + src = pkgs.fetchFromGitHub (builtins.fromJSON fetchparams); + + buildInputs = with pkgs; [ openssl zlib ]; + nativeBuildInputs = with pkgs; [ cmake gperf ]; + + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Release" + "-DOPENSSL_USE_STATIC_LIBS=TRUE" + "-DZLIB_USE_STATIC_LIBS=TRUE" + ]; + + buildPhase = '' + cmake --build build --target tdjson -j$NIX_BUILD_CORES + ''; + + # https://github.com/tdlib/td/issues/1974 + postPatch = '' + substituteInPlace CMake/GeneratePkgConfig.cmake \ + --replace 'function(generate_pkgconfig' \ + 'include(GNUInstallDirs) + function(generate_pkgconfig' \ + --replace '\$'{prefix}/'$'{CMAKE_INSTALL_LIBDIR} '$'{CMAKE_INSTALL_FULL_LIBDIR} \ + --replace '\$'{prefix}/'$'{CMAKE_INSTALL_INCLUDEDIR} '$'{CMAKE_INSTALL_FULL_INCLUDEDIR} + '' + lib.optionalString (stdenv.isDarwin && stdenv.isAarch64) '' + sed -i "/vptr/d" test/CMakeLists.txt + ''; +} diff --git a/packages/prebuilt-tdlib/build-scripts/tdlib-macos.nix b/packages/prebuilt-tdlib/build-scripts/tdlib-macos.nix new file mode 100644 index 0000000..32daacd --- /dev/null +++ b/packages/prebuilt-tdlib/build-scripts/tdlib-macos.nix @@ -0,0 +1,40 @@ +{ url, hash }: +let + pkgs = import {}; + inherit (pkgs) lib stdenv; + zlib = pkgs.zlib.override { static = true; shared = false; }; + openssl = pkgs.openssl.override { static = true; }; +in +# Based on https://github.com/NixOS/nixpkgs/blob/af51e23ce535b1bfa8484021ff3913d876e09082/pkgs/development/libraries/tdlib/default.nix +stdenv.mkDerivation { + pname = "tdlib"; + version = "0.0"; + + src = pkgs.fetchzip { inherit url; hash = "sha256-${hash}"; }; + + buildInputs = [ openssl zlib ]; + nativeBuildInputs = with pkgs; [ cmake gperf ]; + + cmakeFlags = [ + "-DCMAKE_BUILD_TYPE=Release" + "-DOPENSSL_USE_STATIC_LIBS=TRUE" + "-DZLIB_USE_STATIC_LIBS=TRUE" + ]; + + buildPhase = '' + ls + cmake --build . --target tdjson -j$NIX_BUILD_CORES + ''; + + # https://github.com/tdlib/td/issues/1974 + postPatch = '' + substituteInPlace CMake/GeneratePkgConfig.cmake \ + --replace 'function(generate_pkgconfig' \ + 'include(GNUInstallDirs) + function(generate_pkgconfig' \ + --replace '\$'{prefix}/'$'{CMAKE_INSTALL_LIBDIR} '$'{CMAKE_INSTALL_FULL_LIBDIR} \ + --replace '\$'{prefix}/'$'{CMAKE_INSTALL_INCLUDEDIR} '$'{CMAKE_INSTALL_FULL_INCLUDEDIR} + '' + lib.optionalString (stdenv.isDarwin && stdenv.isAarch64) '' + sed -i "/vptr/d" test/CMakeLists.txt + ''; +} diff --git a/packages/prebuilt-tdlib/build-scripts/zig-stdenv.nix b/packages/prebuilt-tdlib/build-scripts/zig-stdenv.nix new file mode 100644 index 0000000..64ee838 --- /dev/null +++ b/packages/prebuilt-tdlib/build-scripts/zig-stdenv.nix @@ -0,0 +1,107 @@ +# https://gist.github.com/Cloudef/acb74ff9e36ab41709479240596ab501 +{ pkgs ? import {}, lib ? pkgs.lib, stdenv ? pkgs.stdenv, zig ? pkgs.zig, static ? false, target, zig-target }: + +with lib; +with builtins; + +let + zig-stdenv = let + write-zig-wrapper = cmd: pkgs.writeShellScript "zig-${cmd}" ''${zig}/bin/zig ${cmd} "$@"''; + zig-cc = write-zig-wrapper "cc"; + zig-cxx = write-zig-wrapper "c++"; + zig-ar = write-zig-wrapper "ar"; + zig-ranlib = write-zig-wrapper "ranlib"; + zig-dlltool = write-zig-wrapper "dlltool"; + zig-lib = write-zig-wrapper "lib"; + + # XXX: Consider LLVM binutils instead? + bintools = pkgs.bintoolsNoLibc; + symlinks = [ + { name = "bin/clang"; path = zig-cc; } + { name = "bin/clang++"; path = zig-cxx; } + { name = "bin/cc"; path = zig-cc; } + { name = "bin/c++"; path = zig-cxx; } + { name = "bin/ld"; path = zig-cc; } + { name = "bin/gold"; path = zig-cc; } + { name = "bin/ar"; path = zig-ar; } + { name = "bin/ranlib"; path = zig-ranlib; } + { name = "bin/dlltool"; path = zig-dlltool; } + { name = "bin/lib"; path = zig-lib; } + ] ++ map (x: { name = "bin/${x}"; path = "${bintools}/bin/${x}"; }) [ + "addr2line" "c++filt" "elfedit" "gprof" "gprofng" "nlmconv" "nm" "as" + "objcopy" "objdump" "readelf" "size" "strings" "windmc" "windres" "strip" + ]; + + zig-toolchain = pkgs.linkFarm "zig-toolchain" (symlinks + ++ map (x: let y = last (splitString "/" x.name); in { name = "bin/${target}-${y}"; path = y; }) symlinks) // { + inherit (pkgs.llvmPackages.libclang) version; + pname = "zig-toolchain"; + isClang = true; + libllvm.out = ""; + }; + + # Bunch of overrides to make sure we don't ever start bootstrapping another cross-compiler + overrides = self: super: let + to-override-set = x: genAttrs x (x: zig-toolchain); + llvmPackages = to-override-set [ "clang" "libclang" "lld" "llvm" "libllvm" "compiler-rt" "libunwind" "libstdcxx" "libcxx" "libcxxapi" "openmp" ]; + in (to-override-set [ + "gcc" "libgcc" "glibc" "bintools" "bintoolsNoLibc" "binutils" "binutilsNoLibc" + "gccCrossStageStatic" "preLibcCrossHeaders" "glibcCross" "muslCross" "libcCross" + ]) // { + inherit llvmPackages; + inherit (llvmPackages) clang libclang lld llvm libllvm libunwind libstdcxx libcxx libcxxapi openmp; + gccForLibs = null; # also disables --gcc-toolchain passed to compiler + }; + + cross0 = import pkgs.path { + crossSystem.config = target; + localSystem.config = pkgs.buildPlatform.config; + crossOverlays = [overrides]; + }; + + static-stdenv-maybe = x: if static then cross0.makeStatic x else x; + + zig-stdenv0 = static-stdenv-maybe (cross0.overrideCC cross0.stdenv (cross0.wrapCCWith rec { + inherit (pkgs) gnugrep coreutils; + cc = zig-toolchain; libc = cc; libcxx = cc; + bintools = cross0.wrapBintoolsWith { inherit libc gnugrep coreutils; bintools = cc; }; + # XXX: -march is not compatible + # https://github.com/ziglang/zig/issues/4911 + extraBuildCommands = '' + substituteInPlace $out/nix-support/add-local-cc-cflags-before.sh --replace "${target}" "${zig-target}" + sed -i 's/-march[^ ]* *//g' $out/nix-support/cc-cflags-before + ''; + })); + + # Aaand .. finally our final stdenv :) + in zig-stdenv0.override { + inherit overrides; + # XXX: Zig doesn't support response file. Nixpkgs wants to use this for clang + # while zig cc is basically clang, it's still not 100% compatible. + # Probably should report this as a bug to zig upstream though. + preHook = '' + ${cross0.stdenv.preHook} + export NIX_CC_USE_RESPONSE_FILE=0 + export ZIG_LOCAL_CACHE_DIR="$TMPDIR/zig-cache-${target}" + export ZIG_GLOBAL_CACHE_DIR="$ZIG_LOCAL_CACHE_DIR" + ''; + }; + + cross = (import pkgs.path { + crossSystem.config = target; + localSystem.config = pkgs.buildPlatform.config; + crossOverlays = [(self: super: { + stdenv = zig-stdenv; + # XXX: libsepol issue on darwin, should be fixed upstrem instead + libsepol = super.libsepol.overrideAttrs (old: { + nativeBuildInputs = with pkgs; old.nativeBuildInputs ++ optionals (stdenv.isDarwin) [ + (writeShellScriptBin "gln" ''${pkgs.coreutils}/bin/ln "$@"'') + ]; + }); + })]; + }); +in { + inherit target; + stdenv = zig-stdenv; + pkgs = cross; +}