V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
laravel
V2EX  ›  程序员

macos 上怎么编译出 portable nginx? 就像 windows 上的绿色软件一样

  •  
  •   laravel · 2023-03-11 00:56:08 +08:00 · 1822 次点击
    这是一个创建于 384 天前的主题,其中的信息可能已经有所发展或是发生改变。

    就是不依赖编译时候的系统,放到任何 macos 上都可以运行

    我现在用

    ./configure --prefix=./nginx --with-pcre=../pcre2-10.42 --with-http_ssl_module --with-openssl=../openssl-1.1.1t
    

    编译出来的 nginx

    通过命令 otool -L sbin/nginx

    可以看到还是依赖我电脑上的文件

    ./sbin/nginx:
    	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
    	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)
    

    怎么编译才能完全不依赖我的系统

    13 条回复    2023-03-11 11:44:06 +08:00
    Love4Taylor
        1
    Love4Taylor  
       2023-03-11 00:58:18 +08:00 via iPhone
    静态编译?应该和 linux 上参数大概一致吧?
    laravel
        2
    laravel  
    OP
       2023-03-11 00:59:29 +08:00
    @Love4Taylor 就是编译时候不让他找系统里的环境,就在执行目录寻找依赖
    laravel
        4
    laravel  
    OP
       2023-03-11 01:06:57 +08:00
    @bakaft 想做 mac 上的绿色软件,现在要做 nginx php mysql 环境的话,还要用 brew 一个一个安装,或者用集成开发环境,这会污染系统,我就想把所有软件和依赖放到一个目录,就跟 windows 上的 zip 解压出来直接可以运行的那种软件一样
    laravel
        5
    laravel  
    OP
       2023-03-11 01:07:33 +08:00
    @bakaft 现在我发现我编译出来的,放到别人系统无法运行
    laravel
        6
    laravel  
    OP
       2023-03-11 01:26:25 +08:00
    刚才指定了一下 zlib 目录,又减少了一个依赖,看来是有希望

    执行 otool -L ./nginx

    现在是
    ```
    ./nginx:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.0.0)
    ```

    这是什么依赖?
    hguandl
        7
    hguandl  
       2023-03-11 02:45:12 +08:00   ❤️ 4
    libSystem.B.dylib 应该是 macOS 上的 libc ,属于系统的一部分,正常来说所有程序都会动态链接这个库,不能再去掉了。只剩这一个动态库的话,可以说这个程序是静态的,其他人系统无法运行应该不是链接库的问题。我想了几种可能的原因:

    1. 系统版本:如果不指定的话,默认情况下编译出来的程序所需的系统版本是和当前系统一致的。可以通过 otool -l nginx | grep minos 查看。可以加编译参数把目标版本设置得低一些,比如 -mmacosx-version-min=11.0 ,就是兼容 Big Sur 版本。

    2. 架构:可能你用的是 Apple Silicon ,编译出来的是 arm64 的二进制文件,别人电脑是 x86 的,就无法运行。这就需要交叉编译,可以看官方文档 https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary

    3. 签名:macOS 的安全规则比较苛刻,对于下载的文件,如果没有合适的签名可能会阻止运行。试试 xattr -d com.apple.quarantine nginx 把隔离去掉。
    laravel
        8
    laravel  
    OP
       2023-03-11 03:24:15 +08:00
    @hguandl 没有 c/c++基础,感觉太复杂了,还不如只研究 windows 软件,mac 的用户也不是很多
    xiadong1994
        9
    xiadong1994  
       2023-03-11 04:36:35 +08:00
    Docker 就是用来解决这种问题的
    qfdk
        10
    qfdk  
       2023-03-11 06:56:33 +08:00 via iPhone
    docker 不香么? 再不齐用 caddy 吧 这个就一个可执行文件就好了
    yzwduck
        11
    yzwduck  
       2023-03-11 08:50:18 +08:00   ❤️ 2
    macOS 上程序对系统依赖的判定与 Linux 不一样。

    Linux 只保证了系统调用的 ABI 是稳定的,但它不提供任何用户态环境的保障,所以程序需要静态链接 C runtime 等依赖项。

    但 macOS 只保证了 C runtime 和一大堆系统库的 API 是稳定的,它不保障系统调用是稳定的 (
    https://developer.apple.com/forums/thread/706419 ),程序必须链接到 macOS 提供的 C runtime (以及 libSystem 之类) 的动态库上。

    即使在 OS X 10.10 上,系统中也存在 /usr/lib/libz.1.dylib 和 /usr/lib/libSystem.B.dylib 。如果编译选项正确的话,Xcode 14 编译出来的程序能在 macOS 10.13 (甚至更早的系统) 上运行。

    TL;DR:
    如果只需要支持 Xcode 兼容的 deployment target (Xcode 14: macOS 10.13 或更新),在满足 (1) 不链接到系统路径以外的动态库,(2) export MACOSX_DEPLOYMENT_TARGET=10.13 环境变量,或者提供了 -mmacosx-version-min=10.13 编译参数,(3) 编译 x86_64 和 ARM64 两份架构的代码,就应该能保证程序能在 macOS 10.13 以后的系统上运行。

    如果要支持 OS X 10.9 或更老的系统,或者 i386/PPC 架构的话,就超出我的实践范围了。
    guanzhangzhang
        12
    guanzhangzhang  
       2023-03-11 09:55:33 +08:00
    ```
    --with-cc-opt='-static -s' \
    --with-ld-opt=-static
    ```
    加这俩试试,不知道 mac 上能有用不
    laravel
        13
    laravel  
    OP
       2023-03-11 11:44:06 +08:00
    @guanzhangzhang 不行,我估计别人是修改了 nginx 的代码,让他编译时候去自己的目录找依赖
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2892 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:52 · PVG 21:52 · LAX 06:52 · JFK 09:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.