Skip to content

Commit

Permalink
Add Makefile for debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
perklet committed Dec 30, 2023
1 parent e8878ed commit 92de30e
Showing 1 changed file with 330 additions and 0 deletions.
330 changes: 330 additions & 0 deletions Makefile.win
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

0 comments on commit 92de30e

Please sign in to comment.