新版的curl 支持了更细致时间粒度的curl_easy_getinfo,以及HTTP2, 这里介绍手工编译源码安装方式,并使用openssl1.1.1b
- 从https://www.openssl.org/ 下载1.1.1 序列的long-term 源码,并编译安装
./config --prefix=/opt/itc/openssl enable-weak-ssl-ciphers no-shared && make && make install
- 从https://nghttp2.org/ 下载nghttp2库, curl 需要它才能支持HTTP2,编译安装,
OPENSSL_LIBS="/opt/itc/openssl/lib/" ./configure --prefix=/opt/itc/curl/nghttp2
–enable-static=yes –enable-shared=no && make && make install
- 从https://curl.haxx.se/ 下载最新的curl版本,并编译安装,编译参数如下
./configure LDFLAGS="-static" --prefix=/opt/itc/curl --with-ssl=/opt/itc/openssl --with-nghttp2=/opt/itc/curl/nghttp2 --disable-ldaps --without-libidn2 --enable-static=yes --enable-shared=no
make
make install
这样子得到的是不依赖openssl和nghttp2动态链接库的curl,可以拷走给别的机器
./configure LDFLAGS="-static" --prefix=/opt/itc/curl --with-ssl=/opt/itc/openssl --with-nghttp2=/opt/itc/curl/nghttp2 --disable-ldaps --without-libidn2 --enable-static=yes --enable-shared=no
make LDFLAGS="-all-static -static -L/opt/itc/openssl/lib -L/opt/itc/curl/nghttp2/lib -ldl"
make install
这样子得到的是: 不依赖任何动态链接库的版本
可能遇到的问题:
1./usr/bin/ld: cannot find -lnghttp2 或者 -lssl 之类的
这是curl找不到对应的依赖库,请确认给了正确的configure参数,如果还不行,可以在configure的时候加上LIBS=-L/opt/itc/openssl/lib/ -L… 多个依赖库以空格分开
2. configure: error: one or more libs available at link-time are not available run-time. Libs used at link-time: -lnghttp2 -lssl -lz -lrt -lcrypto -ldl
这是curl找到了link-time 库,却没找到动态依赖库, 需要在configure的时候加入LDFLAGS=”-static”,让curl的编译程序知道我们要做静态的东西
3. 静态编译make的时候为什么要带那么长的参数,通常不是LDFLAGS=”-all-static”就可以了么?
是的,通常是可以的,打开src/Makefile能看到make LDFLAGS 带的参数会冲掉configure的时候找到的依赖库环境
LD = /usr/bin/ld -m elf_x86_64
LDFLAGS = -static -L/opt/itc/openssl/lib -L/opt/itc/curl/nghttp2/lib
LIBCURL_LIBS = -lnghttp2 -lssl -lrt -lcrypto -ldl
所以要么完整一点写上去,要么就使用curl提供的curl_LDFLAGS参数也OK
make curl_LDFLAGS="-all-static"
4. 那么要用这些新的库编译example里边的例子怎么办?
#gcc chkspeed.c /opt/itc/curl/lib/libcurl.a /opt/itc/curl/nghttp2/lib/libnghttp2.a /opt/itc/openssl/lib/libssl.a /opt/itc/openssl/lib/libcrypto.a -I/opt/itc/curl/include -I/opt/itc/curl/nghttp2/include -lrt -ldl -o chkspeed
#ldd chkspeed
linux-vdso.so.1 => (0x00007ffc475a2000)
librt.so.1 => /lib64/librt.so.1 (0x00007fcb5d748000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fcb5d544000)
libc.so.6 => /lib64/libc.so.6 (0x00007fcb5d1af000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fcb5cf92000)
/lib64/ld-linux-x86-64.so.2 (0x00005593e1eb2000)
这样子编译出来是把这几个库都包含在里边的
gcc chkspeed.c -L/opt/itc/openssl/lib/ -L/opt/itc/curl/nghttp2/lib -L/opt/itc/curl/lib -I/opt/itc/curl/include -I/opt/itc/curl/nghttp2/include -lcurl -lssl -lrt -lcrypto -ldl -lnghttp2
这样子编译出来是带动态链接库的,但是需要设置环境变量,告诉系统那些.so在哪里,或者修改/etc/ld.so.conf.d/, 增加路径
当然,我们的openssl选择的是静态编译,所以出来的程序依赖只有nghttp2.so
部分知识点:
o: 编译的目标文件
a: 静态库,其实就是把若干o文件打了个包
so: 动态链接库(共享库)
lo: 使用libtool编译出的目标文件,其实就是在o文件中添加了一些信息
la: 使用libtool编译出的库文件,其实是个文本文件,记录同名动态库和静态库的相关信息
./configure LDFLAGS="-static"
make LDFLAGS="-all-static"
-I include,头文件和库文件,通常都是源码
-L 依赖链接库的目录,可能是静态的也可能是动态的
-l 依赖库的名称,比如-lssl -ldl -lz
pkgconfig 里边有对应的.pc文件,当-l 或者-L指定依赖的时候会自动去找
-l 是有顺序的,而且是从右到左开始包含的,比如
-lcurl -lssl -lrt -lcrypto -ldl -lnghttp2
这里-lcurl 必须在最前边, -lssl 也必须在-lcrypto的前边,原因很简单: curl调用了所有的其他依赖库, 而ssl调用了crypto
参考文档:
https://github.com/curl/curl/issues/503
https://curl.haxx.se/mail/lib-2017-11/0107.html
https://stackoverflow.com/questions/48726825/setting-up-libcurl-on-linux