forked from lwthiker/curl-impersonate
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,330 @@ | ||
# Makefile to build curl-impersonate | ||
# Some Makefile tricks were taken from https://tech.davis-hansson.com/p/make/ | ||
|
||
SHELL := bash | ||
.ONESHELL: | ||
.SHELLFLAGS := -euc | ||
.DELETE_ON_ERROR: | ||
# MAKEFLAGS += --warn-undefined-variables | ||
# MAKEFLAGS += --no-builtin-rules | ||
|
||
BROTLI_VERSION := 1.0.9 | ||
# In case this is changed, update build-and-test-make.yml as well | ||
BORING_SSL_COMMIT := d24a38200fef19150eef00cad35b138936c08767 | ||
NGHTTP2_VERSION := nghttp2-1.56.0 | ||
NGHTTP2_URL := https://github.com/nghttp2/nghttp2/releases/download/v1.56.0/nghttp2-1.56.0.tar.bz2 | ||
CURL_VERSION := curl-8.1.1 | ||
|
||
brotli_install_dir := $(abspath brotli-$(BROTLI_VERSION)/out/installed) | ||
brotli_static_libs := $(brotli_install_dir)/lib/libbrotlicommon-static.a $(brotli_install_dir)/lib/libbrotlidec-static.a | ||
boringssl_install_dir := $(abspath boringssl/build) | ||
boringssl_static_libs := $(boringssl_install_dir)/lib/libssl.a $(boringssl_install_dir)/lib/libcrypto.a | ||
nghttp2_install_dir := $(abspath $(NGHTTP2_VERSION)/installed) | ||
nghttp2_static_libs := $(nghttp2_install_dir)/lib/libnghttp2.a | ||
|
||
# Dependencies needed to compile the Chrome version | ||
chrome_libs := $(brotli_static_libs) $(boringssl_static_libs) $(nghttp2_static_libs) | ||
|
||
# The following variables will be set by the configure script. | ||
prefix = /usr/local | ||
exec_prefix = ${prefix} | ||
srcdir = /Users/yifei/repos/curl-impersonate/build/.. | ||
host = aarch64-apple-darwin23.0.0 | ||
host_alias = | ||
host_cpu = aarch64 | ||
host_os = darwin23.0.0 | ||
build = aarch64-apple-darwin23.0.0 | ||
# Whether to link curl-impersonate with libcurl-impersonate statically. | ||
static_build = no | ||
# Whether the user provided a specific find for zlib | ||
with_zlib = | ||
# Path to be passed to curl's --with-ca-bundle configure option. | ||
with_ca_bundle = | ||
# Path to be passed to curl's --with-ca-path configure option. | ||
with_ca_path = | ||
# Path to be passed to curl's --with-libnssckbi configure option (an option | ||
# added for curl-impersonate). | ||
with_libnssckbi = | ||
|
||
CC = gcc | ||
CXX = g++ | ||
STRIP = strip | ||
|
||
# Auto-generate Makefile help. | ||
# Borrowed from https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html | ||
help: ## Show this help message | ||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' | ||
.PHONY: help | ||
.DEFAULT_GOAL := help | ||
|
||
chrome-build: $(CURL_VERSION)/.chrome ## Build the Chrome version of curl-impersonate | ||
cd $(CURL_VERSION) | ||
# Don't pass this Makefile's MAKEFLAGS | ||
$(MAKE) MAKEFLAGS= | ||
.PHONY: chrome-build | ||
|
||
chrome-checkbuild: ## Run basic checks on the built binary | ||
ifeq ($(host),$(build)) | ||
cd $(CURL_VERSION) | ||
# Make sure all needed features were compiled in | ||
./src/curl-impersonate-chrome -V | grep -q zlib | ||
./src/curl-impersonate-chrome -V | grep -q brotli | ||
./src/curl-impersonate-chrome -V | grep -q nghttp2 | ||
./src/curl-impersonate-chrome -V | grep -q BoringSSL | ||
$(info Build OK) | ||
else | ||
$(info Cross compiling, skipping checkbuild) | ||
endif | ||
.PHONY: chrome-checkbuild | ||
|
||
chrome-install: ## Install the Chrome version of curl-impersonate after build | ||
cd $(CURL_VERSION) | ||
$(MAKE) install-exec MAKEFLAGS= | ||
# Wrapper scripts for the Chrome version (e.g. 'curl_chrome99') | ||
install $(srcdir)/chrome/curl_chrome* $(srcdir)/chrome/curl_edge* $(srcdir)/chrome/curl_safari* ${exec_prefix}/bin | ||
.PHONY: chrome-install | ||
|
||
chrome-install-strip: ## Like 'chrome-install', but strip binaries for smaller size | ||
cd $(CURL_VERSION) | ||
$(MAKE) install-exec MAKEFLAGS= | ||
# We could have used 'install-strip' but then the docs would be installed as well. | ||
# Instead strip manually. | ||
$(STRIP) ${exec_prefix}/bin/curl-impersonate-chrome | ||
# Wrapper scripts for the Chrome version (e.g. 'curl_chrome99') | ||
install $(srcdir)/chrome/curl_chrome* $(srcdir)/chrome/curl_edge* $(srcdir)/chrome/curl_safari* ${exec_prefix}/bin | ||
.PHONY: chrome-install-strip | ||
|
||
chrome-uninstall: ## Uninstall the Chrome version of curl-impersonate after 'make install' | ||
cd $(CURL_VERSION) | ||
$(MAKE) uninstall MAKEFLAGS= | ||
rm -Rf ${exec_prefix}/bin/curl_chrome* ${exec_prefix}/bin/curl_edge* ${exec_prefix}/bin/curl_safari* | ||
.PHONY: chrome-uninstall | ||
|
||
chrome-clean: ## Clean build artifacts of the Chrome version. Use after re-running './configure' | ||
cd $(CURL_VERSION) | ||
$(MAKE) clean MAKEFLAGS= | ||
rm -f .chrome | ||
.PHONY: chrome-clean | ||
|
||
clean: ## Remove all build artifacts, including dependencies | ||
rm -Rf brotli-$(BROTLI_VERSION).tar.gz brotli-$(BROTLI_VERSION) | ||
rm -Rf $(NSS_VERSION).tar.gz $(NSS_VERSION) | ||
rm -Rf boringssl.zip boringssl | ||
rm -Rf $(NGHTTP2_VERSION).tar.bz2 $(NGHTTP2_VERSION) | ||
rm -Rf $(CURL_VERSION).tar.xz $(CURL_VERSION) | ||
|
||
brotli-$(BROTLI_VERSION).tar.gz: | ||
curl -L "https://github.com/google/brotli/archive/refs/tags/v${BROTLI_VERSION}.tar.gz" \ | ||
-o "brotli-${BROTLI_VERSION}.tar.gz" | ||
|
||
$(brotli_static_libs): brotli-$(BROTLI_VERSION).tar.gz | ||
tar xf brotli-$(BROTLI_VERSION).tar.gz | ||
cd brotli-$(BROTLI_VERSION) | ||
mkdir -p out | ||
cd out | ||
|
||
# Convert autoconf style os name to CMake style os name. | ||
case $(host_os) in \ | ||
linux*) \ | ||
system_name=Linux \ | ||
;; \ | ||
darwin*) \ | ||
system_name=Darwin \ | ||
;; \ | ||
*) \ | ||
system_name=$(host_os) \ | ||
;; \ | ||
esac | ||
|
||
cmake -DCMAKE_BUILD_TYPE=Release \ | ||
-DCMAKE_INSTALL_PREFIX=./installed \ | ||
-DCMAKE_INSTALL_LIBDIR=lib \ | ||
-DCMAKE_CXX_COMPILER=$(CXX) \ | ||
-DCMAKE_C_COMPILER=$(CC) \ | ||
-DCMAKE_SYSTEM_NAME=$$system_name \ | ||
-DCMAKE_SYSTEM_PROCESSOR=$(host_cpu) \ | ||
.. | ||
|
||
cmake --build . --config Release --target install | ||
|
||
|
||
$(NSS_VERSION).tar.gz: | ||
curl -L -o $(NSS_VERSION).tar.gz $(NSS_URL) | ||
|
||
$(nss_static_libs): $(NSS_VERSION).tar.gz | ||
tar xf $(NSS_VERSION).tar.gz | ||
|
||
ifeq ($(host),$(build)) | ||
# Native build, use NSS' build script. | ||
cd $(NSS_VERSION)/nss | ||
./build.sh -o --disable-tests --static --python=python3 | ||
else | ||
# We are cross compiling. | ||
# Cross compiling NSS is not supported by its build script and is poorly | ||
# documented. We need to compile NSPR manually and only then compile nss. | ||
case $(host_cpu) in \ | ||
*64*) \ | ||
use_64="1"; \ | ||
nspr_configure_flags="--enable-64bit"; \ | ||
;; \ | ||
*) \ | ||
use_64="0"; \ | ||
nspr_configure_flags=""; \ | ||
;; \ | ||
esac | ||
|
||
# Cross-compile nspr separately | ||
cd $(NSS_VERSION)/nspr | ||
./configure --prefix=$(nss_install_dir) \ | ||
--disable-debug --enable-optimize \ | ||
--target=$(host_alias) \ | ||
$$nspr_configure_flags | ||
$(MAKE) MAKEFLAGS= | ||
$(MAKE) install MAKEFLAGS= | ||
|
||
# Now we can run ./build.sh with the already built nspr | ||
cd ../nss | ||
CC=$(CC) CXX=$(CXX) CCC=$(CXX) \ | ||
./build.sh -o --disable-tests --static --python=python3 \ | ||
--with-nspr=$(nss_install_dir)/include/nspr:$(nss_install_dir)/lib \ | ||
--target=$(host_cpu) \ | ||
-Duse_system_zlib=0 \ | ||
-Dsign_libs=0 | ||
endif | ||
# Hack for macOS: Remove dynamic libraries to force the linker to use the | ||
# static ones when linking curl. | ||
rm -Rf $(nss_install_dir)/lib/*.dylib | ||
|
||
|
||
boringssl.zip: | ||
curl -L https://github.com/google/boringssl/archive/$(BORING_SSL_COMMIT).zip \ | ||
-o boringssl.zip | ||
|
||
# Patch boringssl and use a dummy '.patched' file to mark it patched | ||
boringssl/.patched: $(srcdir)/chrome/patches/boringssl-*.patch | ||
unzip -q -o boringssl.zip | ||
mv boringssl-$(BORING_SSL_COMMIT) boringssl | ||
cd boringssl/ | ||
for p in $^; do patch -p1 < $$p; done | ||
touch .patched | ||
|
||
$(boringssl_static_libs): boringssl.zip boringssl/.patched | ||
mkdir -p $(boringssl_install_dir) | ||
cd $(boringssl_install_dir) | ||
|
||
# Convert autoconf style os name to CMake style os name. | ||
case $(host_os) in \ | ||
linux*) \ | ||
system_name=Linux \ | ||
;; \ | ||
darwin*) \ | ||
system_name=Darwin \ | ||
;; \ | ||
*) \ | ||
system_name=Linux \ | ||
;; \ | ||
esac | ||
|
||
# The extra CMAKE_C_FLAGS are needed because otherwise boringssl fails to | ||
# compile in release mode on some systems with gcc 12 (e.g. Fedora). | ||
# In addition, guard these options with -Wno-unknown-warning-option to | ||
# prevent clang from failing on them. | ||
cmake -DCMAKE_BUILD_TYPE=Release \ | ||
-DCMAKE_POSITION_INDEPENDENT_CODE=on \ | ||
-DCMAKE_C_FLAGS="-Wno-unknown-warning-option -Wno-stringop-overflow -Wno-array-bounds" \ | ||
-DCMAKE_CXX_COMPILER=$(CXX) \ | ||
-DCMAKE_C_COMPILER=$(CC) \ | ||
-DCMAKE_SYSTEM_NAME=$$system_name \ | ||
-DCMAKE_SYSTEM_PROCESSOR=$(host_cpu) \ | ||
-GNinja \ | ||
.. | ||
ninja | ||
# Fix the directory structure so that curl can compile against it. | ||
# See https://everything.curl.dev/source/build/tls/boringssl | ||
mkdir -p lib | ||
ln -sf ../crypto/libcrypto.a lib/libcrypto.a | ||
ln -sf ../ssl/libssl.a lib/libssl.a | ||
cp -Rf ../include . | ||
|
||
|
||
$(NGHTTP2_VERSION).tar.bz2: | ||
curl -L $(NGHTTP2_URL) -o $(NGHTTP2_VERSION).tar.bz2 | ||
|
||
$(nghttp2_static_libs): $(NGHTTP2_VERSION).tar.bz2 | ||
tar -xf $(NGHTTP2_VERSION).tar.bz2 | ||
cd $(NGHTTP2_VERSION) | ||
|
||
# Set up the configure flags to nghttp2. | ||
# If the user provided the --host flag to our configure script | ||
# (for cross compilation), then pass it on to nghttp2. | ||
{ \ | ||
config_flags="--prefix=$(nghttp2_install_dir)"; \ | ||
config_flags="$$config_flags --with-pic --enable-lib-only"; \ | ||
config_flags="$$config_flags --disable-shared --disable-python-bindings"; \ | ||
if test -n "$(host_alias)"; then \ | ||
config_flags="$$config_flags --host=$(host_alias)"; \ | ||
fi; \ | ||
} | ||
|
||
./configure $$config_flags | ||
$(MAKE) MAKEFLAGS= | ||
$(MAKE) install MAKEFLAGS= | ||
|
||
$(CURL_VERSION).tar.xz: | ||
curl -L "https://curl.se/download/$(CURL_VERSION).tar.xz" \ | ||
-o "$(CURL_VERSION).tar.xz" | ||
|
||
# Apply the "Chorme version" patches and mark using a dummy file | ||
$(CURL_VERSION)/.patched-chrome: $(srcdir)/chrome/patches/curl-*.patch | ||
rm -Rf $(CURL_VERSION) | ||
tar -xf $(CURL_VERSION).tar.xz | ||
cd $(CURL_VERSION) | ||
for p in $^; do patch -p1 < $$p; done | ||
# Re-generate the configure script | ||
autoreconf -fi | ||
touch .patched-chrome | ||
rm -f .patched-ff | ||
|
||
# This is a small hack that flags that curl was patched and configured in the "chrome" version | ||
$(CURL_VERSION)/.chrome: $(chrome_libs) $(CURL_VERSION).tar.xz $(CURL_VERSION)/.patched-chrome | ||
cd $(CURL_VERSION) | ||
|
||
# Set up the configure flags to curl. | ||
# If the user provided the --host flag to our configure script | ||
# (for cross compilation), then pass it on to curl. | ||
{ \ | ||
config_flags="--prefix=/usr/local"; \ | ||
config_flags="$$config_flags --with-nghttp2=$(nghttp2_install_dir)"; \ | ||
config_flags="$$config_flags --with-brotli=$(brotli_install_dir)"; \ | ||
config_flags="$$config_flags --with-openssl=$(boringssl_install_dir)"; \ | ||
config_flags="$$config_flags --without-zstd"; \ | ||
config_flags="$$config_flags --enable-websockets"; \ | ||
config_flags="$$config_flags --enable-ech"; \ | ||
config_flags="$$config_flags USE_CURL_SSLKEYLOGFILE=true"; \ | ||
if test "$(static_build)" = "yes"; then \ | ||
config_flags="$$config_flags --enable-static --disable-shared"; | ||
fi; \ | ||
if test -n "$(host_alias)"; then \ | ||
config_flags="$$config_flags --host=$(host_alias)"; \ | ||
fi; \ | ||
if test -n "$(with_zlib)"; then \ | ||
config_flags="$$config_flags --with-zlib=$(with_zlib)"; \ | ||
else \ | ||
config_flags+=" --with-zlib"; \ | ||
fi; \ | ||
if test -n "$(with_ca_bundle)"; then \ | ||
config_flags="$$config_flags --with-ca-bundle=$(with_ca_bundle)"; \ | ||
fi; \ | ||
if test -n "$(with_ca_path)"; then \ | ||
config_flags="$$config_flags --with-ca-path=$(with_ca_path)"; \ | ||
fi; \ | ||
add_libs="-pthread"; \ | ||
} | ||
|
||
echo "Configuring curl with: $$config_flags" | ||
|
||
./configure $$config_flags LIBS="$$add_libs" | ||
|
||
# Remove possible leftovers from a previous compilation | ||
$(MAKE) clean MAKEFLAGS= | ||
touch .chrome |