You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Ubuntu上通过musl-gcc静态编译libcurl?

如何在Ubuntu上通过musl-gcc静态编译libcurl?

我明白你想在Ubuntu上用musl编译出完全静态的libcurl,这样你的程序能在更多Linux发行版上通用——之前你遇到的问题是curl最终还是动态链接了musl libc,而且ldd报错,这大概率是configure过程没指定用musl-gcc作为编译器导致的。我给你一套亲测可行的步骤,你可以试试:

一、环境准备

先把基础依赖装齐,musl-tools已经包含了musl开发所需的组件,不用单独装musl-dev

sudo apt update && sudo apt install -y musl-tools git build-essential

二、静态编译OpenSSL

你之前的OpenSSL编译看起来成功了,但再按这个标准步骤确认下,确保是完全适配musl的静态库:

  • 克隆指定版本的OpenSSL:
    git clone --branch openssl-3.3.0 https://github.com/openssl/openssl.git
    cd openssl
    
  • 用musl专属配置项编译静态库:
    ./Configure linux-x86_64-musl --prefix=/musl --openssldir=/musl/ssl no-shared
    
    这里linux-x86_64-musl是OpenSSL针对musl的预定义配置,no-shared强制只生成静态库。
  • 编译并安装:
    make -j$(nproc)
    sudo make install
    

三、静态编译libcurl

这一步的核心是指定musl-gcc作为编译器,否则系统会用默认的glibc版gcc,导致最终产物还是动态链接:

  • 克隆指定版本的curl:
    git clone --branch curl-8_6_0 https://github.com/curl/curl.git
    cd curl
    
  • 配置编译参数,确保全静态链接:
    CC=musl-gcc ./configure \
      --prefix=/musl \
      --with-ssl=/musl \
      --without-libpsl \
      --enable-static \
      --disable-shared \
      --disable-dependency-tracking \
      --disable-ldap \
      --disable-ldaps \
      --disable-manual \
      LDFLAGS="-static -L/musl/lib" \
      CPPFLAGS="-I/musl/include"
    
    解释下关键参数:
    • CC=musl-gcc:告诉configure使用musl的编译器,这是解决你之前问题的核心
    • --disable-ldap --disable-ldaps:关闭不必要的依赖,避免引入动态库
    • LDFLAGS="-static":强制所有链接都是静态的
  • 编译并安装:
    make -j$(nproc)
    sudo make install
    
  • 验证静态链接结果:
    file /musl/bin/curl
    
    正常输出应该是:ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped,用ldd检查会提示not a dynamic executable

四、编译你的C程序

用musl-gcc编译你的代码,链接静态的libcurl和OpenSSL:

musl-gcc -o your_program your_code.c -I/musl/include -L/musl/lib -lcurl -lcrypto -ldl -lpthread

这里-ldl-lpthread是musl需要的系统静态库,必须加上。

为啥你之前失败了?

你之前的configure命令没指定CC=musl-gcc,导致系统用了默认的glibc版gcc。虽然你加了-static,但gcc会优先链接musl的动态库而不是静态的,最终生成的是依赖/lib/ld-musl-x86_64.so.1的PIE动态程序——而Ubuntu默认用glibc,所以ldd会报错找不到正确的libc。

另外,如果用Alpine Docker的话会更省心,因为Alpine本身就是基于musl的发行版,直接装curl-static包或者从源码编译都不需要额外指定编译器。

备注:内容来源于stack exchange,提问作者Gordon

火山引擎 最新活动