-
-
Save Tokarak/ef81f4d0c4bb448c5bd4f3014844c5cd to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# TODO: rebuild dependencies each script run, like qbittorent itself. Currently, the only way to make the script rebuild the dependencies, each dependency's lib folder needs to be deleted. This however would bring a small overhead to each operation, since dependencies are unlikely to be modified. | |
# standalone script to build qBittorent for macOS (including Apple Silicon based Macs) | |
# | |
# Script peforms much better when it caches the process for future use - it is completely unrecommended to run this script in the default temporary folder. (That was only allowed because it is still preferable to the script potentially overwriting by accident in the current working directory.) To make use of the caching functionaly, it is recommended to store the script in its own empty directory. Call the script (from that directory): | |
# ./build_qbt_dmg.sh -w . -o . | |
# This will cause the script to _W_ork and _O_utput in the same directory - everything is nicely centralised. | |
# Default outdir is better: it pops the dmg straight into downloads. | |
# | |
# only Xcode must be installed (Xcode 12 is required to produce arm64 binaries) | |
# all required dependencies and tools are automatically downloaded and used only from script's working directory | |
# (can be specified), nothing is installed into the system | |
# working directory is removed on completion if it was not specified | |
# | |
# by default script produces binaries for the architecture it was launched on, but cross-compilation is also supported | |
# in both directions, i.e. x86_64 -> arm64 and arm64 -> x86_64 | |
# Use -a option to specify arch eg "... -a universal" | |
# | |
# following conventions are used in the script: | |
# - variables names are in snake_case (special variables are an exception) | |
# - variables starting with '_' (underscore) should be considered "internal" | |
# - variables without '_' prefix can be considered "options" or "default values" | |
# | |
# script accepts few arguments which can customize its behavior the same way as editing "option" variables, | |
# see 'command line arguments parsing' section for details and possible options | |
# | |
# script is not interactive and doesn't ask anything, it just automates build routine | |
# it can be launched multiple times with the same or different set of arguments, this may be useful for development | |
# environment setup for example (just pass some working directory, and it will contain everything required for | |
# qBittorrent development) | |
# moreover, passing the same working directory with other arguments allows you to get environment with few different | |
# Qt and/or libtorrent versions (or libraries for different architectures) that you can switch easily | |
# | |
# Dependencies are only redownload | |
# qBittorrent is always recompiled (but cache is not cleaned resulting on fast rebuilds) | |
# ===================================================================================================================== | |
# software versions to use | |
# NOTICE: currently all dependencies are only updated the first time the script is run | |
# With the exception of: cmake, boost | |
# All others should be manually upgraded by running "git fetch" + "git checkout ..." to the desired branch/tag. | |
# This is to avoid the script checking out by accident - now you can modify repo without needing to change version in the script. | |
# NOTICE: Please manually specify latest version of Boost, cmake, qt before running the script for the first time: they could be outdated. | |
# If you didn't read the script first and you are only reading this now: | |
# First two can be changed at any time; they will be redownloaded. Qt can be upgraded with "git checkout". | |
qbittorrent_ver=v4_5_x # qBittorrent (branch or tag) https://github.com/qbittorrent/qBittorrent/releases | |
openssl_ver=1_1_1-stable # OpenSSL https://www.openssl.org/source/ | |
boost_ver=1.80.0 # Boost https://www.boost.org/ | |
#libtorrent_ver=RC_2_0 # libtorrent https://github.com/arvidn/libtorrent/releases | |
libtorrent_ver=v2.0.8 # Or alternatively specify a release tag in this format | |
qt_ver=6.4.1 # Qt https://code.qt.io/cgit/qt/qt5.git/refs/tags | |
cmake_ver=3.25.1 # CMake https://cmake.org/download/ | |
# Ninja version is always master | |
# build environment variables | |
target_arch=$(uname -m) # target architecture, host by default | |
# qBittorrent requires C++17 features available only since macOS 10.14 | |
cxxstd=17 # C++ standard | |
min_macos_ver=10.14 # minimum version of the target platform | |
# ===================================================================================================================== | |
work_dir="" # working directory, in a temp by default (not recommended); overridden by -w option | |
prod_dir="${HOME}/Downloads" # output directory for result qBittorrent .dmg image; overridden by -o option | |
universal_arch_tag="universal" # value used as arch to build a universal binary | |
# --------------------------------------------------------------------------------------------------------------------- | |
# command line arguments parsing | |
# https://stackoverflow.com/questions/402377/using-getopts-to-process-long-and-short-command-line-options | |
_die() { echo "$*" >&2; exit 2; } | |
_needs_arg() { if [ -z "$OPTARG" ]; then _die "No arg for --$OPT option"; fi; } | |
_no_arg() { if [ -n "$OPTARG" ]; then _die "No arg allowed for --$OPT option"; fi; } | |
while getopts ha:w:o:-: OPT; do | |
if [ "$OPT" = "-" ]; then | |
OPT="${OPTARG%%=*}" | |
OPTARG="${OPTARG#$OPT}" | |
OPTARG="${OPTARG#=}" | |
fi | |
case "$OPT" in | |
h | help ) | |
echo "no help there! but script accepts few command line agruments, just open it to find them :)" | |
exit 0 | |
;; | |
a | target-arch ) _needs_arg; target_arch="$OPTARG" ;; | |
w | workdir ) _needs_arg; work_dir="${OPTARG%/}" ;; | |
o | outdir ) _needs_arg; prod_dir="${OPTARG%/}" ;; | |
qbittorrent ) _needs_arg; qbittorrent_ver="$OPTARG" ;; | |
openssl ) _needs_arg; openssl_ver="$OPTARG" ;; | |
boost ) _needs_arg; boost_ver="$OPTARG" ;; | |
libtorrent ) _needs_arg; libtorrent_ver="$OPTARG" ;; | |
qt ) _needs_arg; qt_ver="$OPTARG" ;; | |
cmake ) _needs_arg; cmake_ver="$OPTARG" ;; | |
cxx ) _needs_arg; cxxstd="$OPTARG" ;; | |
macos ) _needs_arg; min_macos_ver="$OPTARG" ;; | |
??* ) _die "Illegal option --$OPT" ;; # bad long option | |
? ) exit 2 ;; # bad short option (error reported via getopts) | |
esac | |
done | |
shift $((OPTIND-1)) | |
# --------------------------------------------------------------------------------------------------------------------- | |
set -o errexit # exit immediately if a command exits with a non-zero status | |
set -o nounset # treat unset variables as an error when substituting | |
#set -o xtrace # print commands and their arguments as they are executed | |
set -o pipefail # the return value of a pipeline is the status of the last command to exit with a non-zero status | |
# --------------------------------------------------------------------------------------------------------------------- | |
# working directory setup | |
if [[ -z ${work_dir} ]] | |
then | |
work_dir=$(mktemp -d) | |
_remove_work_dir=1 | |
else | |
mkdir -p "${work_dir}" | |
_remove_work_dir=0 | |
fi | |
# output directory setup | |
[[ -d "${prod_dir}" ]] || mkdir -p "${prod_dir}" | |
# get rid of symlinks in paths, Qt6 build system fails if they are faced... | |
# (Does not require zsh any more.) | |
cd "${work_dir}" | |
work_dir=$(pwd -P) | |
pushd "${prod_dir}" > /dev/null | |
prod_dir=$(pwd -P) | |
popd > /dev/null | |
_src_dir="${work_dir}/src" # sources will be downloaded here | |
_tmp_dir="${work_dir}/build/${target_arch}" # build intermediates will be placed here | |
_lib_dir="${work_dir}/lib/${target_arch}" # compiled libraries and headers go here | |
_qbt_dmg_path="${prod_dir}/qBittorrent-${qbittorrent_ver}-macOS-${target_arch}.dmg" | |
[[ "${target_arch}" == "${universal_arch_tag}" ]] && target_arch="x86_64;arm64" | |
# --------------------------------------------------------------------------------------------------------------------- | |
# download everything required (only missing parts will be downloaded) | |
mkdir -p ${_src_dir} | |
pushd "${_src_dir}" > /dev/null | |
_qbt_src_dir_name="qBittorrent" | |
_qbt_src_dir="${_src_dir}/${_qbt_src_dir_name}" | |
_qbt_tmp_dir="${_tmp_dir}/${_qbt_src_dir_name}" | |
# anything known to git (i.e. branch names or tags) can be used as 'version' | |
git clone --filter=blob:none -b $qbittorrent_ver "https://github.com/qbittorrent/qBittorrent" $_qbt_src_dir_name || : | |
_ssl_src_dir_name="openssl" | |
_ssl_src_dir="${_src_dir}/${_ssl_src_dir_name}" | |
_ssl_tmp_dir="${_tmp_dir}/${_ssl_src_dir_name}" | |
_ssl_lib_dir="${_lib_dir}/${_ssl_src_dir_name}" | |
git clone --filter=blob:none -b "OpenSSL_$openssl_ver" "https://github.com/openssl/openssl" $_ssl_src_dir_name || : | |
_boost_ver_u=${boost_ver//./_} | |
_boost_src_dir_name="boost_${_boost_ver_u}" | |
_boost_src_dir="${_src_dir}/${_boost_src_dir_name}" | |
# boost will NOT be compiled, only headers are enough, since 1.69.0 Boost.System is header-only | |
[[ -d ${_boost_src_dir} ]] || curl -L https://boostorg.jfrog.io/artifactory/main/release/${boost_ver}/source/boost_${_boost_ver_u}.tar.bz2 | tar xj | |
_lt_src_dir_name="libtorrent-rasterbar" | |
_lt_src_dir="${_src_dir}/${_lt_src_dir_name}" | |
_lt_tmp_dir="${_tmp_dir}/${_lt_src_dir_name}" | |
_lt_lib_dir="${_lib_dir}/${_lt_src_dir_name}" | |
# use libtorrent release archives, because GitHub doesn't include submodules into generated archives, | |
# but since 2.0 libtorrent has few, and they are required for compilation | |
git clone --filter=blob:none --recurse-submodules -b $libtorrent_ver "https://github.com/arvidn/libtorrent" $_lt_src_dir_name || : | |
# unfortunately, Qt repository must be cloned... it is much easier rather to deal with release archive | |
_qt_src_dir_name="qt6" | |
_qt_src_dir="${_src_dir}/${_qt_src_dir_name}" | |
_qt_tmp_dir="${_tmp_dir}/${_qt_src_dir_name}" | |
_qt_lib_dir="${_lib_dir}/${_qt_src_dir_name}" | |
git clone -b v${qt_ver} --filter=blob:none https://code.qt.io/qt/qt5.git ${_qt_src_dir_name} || : | |
# Spawn a sub-process to avoid having to cd back and messing up the directory stack. Neat! | |
(cd ${_qt_src_dir_name}; perl init-repository --module-subset=qtbase,qtsvg,qttools,qttranslations || :) | |
# download CMake, 3.19.2 and above is required for Apple Silicon support | |
popd > /dev/null # back to working directory | |
_cmake_dir_name="cmake-${cmake_ver}-macos-universal" | |
[[ -d ${_cmake_dir_name} ]] || curl -L https://github.com/Kitware/CMake/releases/download/v${cmake_ver}/cmake-${cmake_ver}-macos-universal.tar.gz | tar xz | |
cmake="${work_dir}/${_cmake_dir_name}/CMake.app/Contents/bin/cmake" | |
# Qt6 uses CMake as build system, but also provides convenient configure script | |
# this script relies on cmake executable in PATH | |
export PATH="$(dirname ${cmake})":$PATH | |
# Qt6 requires ninja build system. even this is not strict requirement, but why not to satisfy it? | |
# even more, ninja can be used to build almost any cmake-based project | |
# download ninja sources and later build them for required architecture, use master branch | |
# Prebuilt libraries could be used, but that would be a (small) pain to refactor. Enjoy the cpu cycles. | |
_ninja_ver="master" # ninja https://github.com/ninja-build/ninja/releases | |
_ninja_src_dir_name="ninja-${_ninja_ver}" | |
_ninja_src_dir="${_src_dir}"/"${_ninja_src_dir_name}" | |
_ninja_tmp_dir="${_tmp_dir}"/"${_ninja_src_dir_name}" | |
# anything known to git (i.e. branch names or tags) can be used as 'version' | |
[[ -d ${_ninja_src_dir} ]] || curl -L https://github.com/ninja-build/ninja/archive/${_ninja_ver}.tar.gz | tar xz -C $_src_dir | |
# git clone --filter=blob:none -b $_ninja_ver "https://github.com/ninja-build/ninja" $_ninja_src_dir_name | |
# ninja is a build tool, so it must be compiled only for build host architecture, so that's why CMAKE_OSX_ARCHITECTURES is omitted | |
if ! [[ -d ${_ninja_tmp_dir} ]] | |
then | |
${cmake} -S ${_ninja_src_dir} -B ${_ninja_tmp_dir} -D CMAKE_VERBOSE_MAKEFILE=ON -D CMAKE_OSX_DEPLOYMENT_TARGET=${min_macos_ver} -D CMAKE_BUILD_TYPE=Release | |
${cmake} --build ${_ninja_tmp_dir} -j$(sysctl -n hw.ncpu) | |
fi | |
# to be able to use ninja, it must be available in PATH | |
export PATH=${_ninja_tmp_dir}:$PATH | |
# --------------------------------------------------------------------------------------------------------------------- | |
# everything is prepared now, time to start the build | |
# | |
# all dependencies are built as static libraries, the main reason for that was a possibility to use LTO | |
# | |
# all options used at configuration step are set only based on only my opinion or preference, there are no strict | |
# reasons for most of options in most cases | |
# OpenSSL doesn't provide the way to build an universal binary in one build step, so the only one way to get it - | |
# is build for each architecture separately and then merge architecture-specific binaries into one universal binary | |
function build_openssl_arch() | |
{ | |
local arch=$1 | |
local ssl_lib_dir="${work_dir}/lib/${arch}/${_ssl_src_dir_name}" | |
local ssl_tmp_dir="${work_dir}/build/${arch}/${_ssl_src_dir_name}" | |
if ! [[ -d ${ssl_lib_dir} ]] | |
then | |
mkdir -p ${ssl_tmp_dir} && cd $_ | |
"${_ssl_src_dir}/Configure" no-comp no-deprecated no-dynamic-engine no-tests no-shared no-zlib --openssldir=/etc/ssl --prefix=${ssl_lib_dir} -mmacosx-version-min=${min_macos_ver} darwin64-${arch}-cc | |
make -j$(sysctl -n hw.ncpu) | |
make install_sw | |
cd - | |
fi | |
} | |
# OpenSSL is used by Qt, which is compiled as universal binaries in case of cross-compilation | |
# so OpenSSL is also must be universal binary when it is used for cross-compilation | |
[[ "${target_arch}" != "$(uname -m)" ]] && _ssl_lib_dir="${work_dir}/lib/${universal_arch_tag}/${_ssl_src_dir_name}" | |
if ! [[ -d ${_ssl_lib_dir} ]] | |
then | |
if [[ "${target_arch}" == "$(uname -m)" ]] | |
then | |
build_openssl_arch ${target_arch} | |
else | |
build_openssl_arch x86_64 | |
build_openssl_arch arm64 | |
mkdir -p "${_ssl_lib_dir}/lib" | |
# copy include directory (includes are the same for each arch) | |
cp -r "${work_dir}/lib/x86_64/${_ssl_src_dir_name}/include" "${_ssl_lib_dir}/" | |
# create universal binaries using lipo | |
lipo -create "${work_dir}/lib/x86_64/${_ssl_src_dir_name}/lib/libcrypto.a" "${work_dir}/lib/arm64/${_ssl_src_dir_name}/lib/libcrypto.a" -output "${_ssl_lib_dir}/lib/libcrypto.a" | |
lipo -create "${work_dir}/lib/x86_64/${_ssl_src_dir_name}/lib/libssl.a" "${work_dir}/lib/arm64/${_ssl_src_dir_name}/lib/libssl.a" -output "${_ssl_lib_dir}/lib/libssl.a" | |
fi | |
fi | |
if ! [[ -d ${_lt_lib_dir} ]] | |
then | |
${cmake} -S ${_lt_src_dir} -B ${_lt_tmp_dir} -D CMAKE_VERBOSE_MAKEFILE=ON -D CMAKE_PREFIX_PATH="${_boost_src_dir};${_ssl_lib_dir}" -D CMAKE_CXX_STANDARD=${cxxstd} -D CMAKE_CXX_EXTENSIONS=OFF -D CMAKE_OSX_DEPLOYMENT_TARGET=${min_macos_ver} -D CMAKE_OSX_ARCHITECTURES=${target_arch} -D CMAKE_BUILD_TYPE=Release -D BUILD_SHARED_LIBS=OFF -D deprecated-functions=OFF -D CMAKE_INSTALL_PREFIX=${_lt_lib_dir} | |
${cmake} --build ${_lt_tmp_dir} -j$(sysctl -n hw.ncpu) | |
${cmake} --install ${_lt_tmp_dir} | |
fi | |
_qt_arch=${target_arch} | |
# Qt6 supports universal binaries out of the box, and in case of cross-compilation | |
# it is easier to build universal binaries rather than only for target architecture | |
if [[ "${target_arch}" != "$(uname -m)" ]] | |
then | |
_qt_arch="x86_64;arm64" | |
_qt_tmp_dir="${work_dir}/build/${universal_arch_tag}/${_qt_src_dir_name}" | |
_qt_lib_dir="${work_dir}/lib/${universal_arch_tag}/${_qt_src_dir_name}" | |
fi | |
if ! [[ -d ${_qt_lib_dir} ]] | |
then | |
mkdir -p ${_qt_tmp_dir} && cd $_ | |
"${_qt_src_dir}/configure" -prefix ${_qt_lib_dir} -release -static -appstore-compliant -no-pch -no-dbus -no-icu -qt-pcre -system-zlib -ssl -openssl-linked -no-cups -qt-libpng -qt-libjpeg -no-feature-testlib -no-feature-concurrent -- -D CMAKE_PREFIX_PATH="${_ssl_lib_dir}" -D CMAKE_OSX_ARCHITECTURES=${_qt_arch} -D QT_BUILD_EXAMPLES=OFF | |
${cmake} --build . --parallel | |
${cmake} --install . | |
cd - | |
fi | |
# build qBittorrent | |
${cmake} -S ${_qbt_src_dir} -B ${_qbt_tmp_dir} -D CMAKE_VERBOSE_MAKEFILE=ON -D CMAKE_PREFIX_PATH="${_boost_src_dir};${_ssl_lib_dir};${_lt_lib_dir};${_qt_lib_dir}" -D CMAKE_CXX_STANDARD=${cxxstd} -D CMAKE_CXX_EXTENSIONS=OFF -D CMAKE_CXX_VISIBILITY_PRESET=hidden -D CMAKE_VISIBILITY_INLINES_HIDDEN=ON -D CMAKE_OSX_DEPLOYMENT_TARGET=${min_macos_ver} -D CMAKE_OSX_ARCHITECTURES=${target_arch} -D CMAKE_BUILD_TYPE=Release -D QT6=ON | |
${cmake} --build ${_qbt_tmp_dir} -j$(sysctl -n hw.ncpu) | |
# build result .dmg image containing qBittorrent | |
pushd ${_qbt_tmp_dir} > /dev/null | |
rm -rf qBittorrent/ | |
mkdir -p qBittorrent | |
ln -s /Applications qBittorrent/Applications | |
mv qbittorrent.app qBittorrent/qBittorrent.app | |
codesign --deep --force --verify --verbose --sign "-" qBittorrent/qBittorrent.app | |
hdiutil create -srcfolder qBittorrent -nospotlight -layout NONE -fs HFS+ -format ULFO -ov ${_qbt_dmg_path} | |
popd > /dev/null | |
# only automatically created directory will be removed | |
[[ $_remove_work_dir -eq 0 ]] || rm -rf ${work_dir} |
Thank you for the quick response! I have followed your directions and the outcome is the same. I would appreciate further help.
I don't compile software often 😬 so don't have much experience to tease out the issues, but I am thinking this is an incompatibility with the new version of Xcode v14.1 and the 13.0 SDK or possibly the Minimum Version that each of the libraries requires may differ now that they have all been bumped?
Linking CXX executable qtbase/libexec/qhelpgenerator
ld: warning: object file (/Users/john/Build/qbt/lib/x86_64/openssl/lib/libssl.a(bio_ssl.o)) was built for newer macOS version (10.15) than being linked (10.14)
I have placed the script inside the directory I am building in and run it without modification as you mention (except for changing the qbittorrent tag to release-4.5.0beta1
).
I have cleared all lib
directory content first.
I have re-run your perl command from within \qt6
using the -f
flag to force.
I have removed both homebrew paths (/usr/local/bin
, /usr/local/sbin
) from the terminal session to avoid potential conflicts.
One warning I see early on in the script output is this...
CMake Warning at CMakeLists.txt:53 (message):
re2c was not found; changes to src/*.in.cc will not affect your build.
When xcode is called to build libtorrent-rasterbar I see another warning:
warning: include location '/usr/local/include' is unsafe for cross-compilation [-Wpoison-system-directories]
Apparently this can be ignored but there is a way to avoid the warning by adding this somewhere in your script:
Set the logical system root with the -isysroot option.
Full command (if the developer command lines tools are installed):
cc -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -Weverything -Werror helloworld.c
Full command (using the SDK from inside Xcode):
cc -isysroot "$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -Weverything -Werror helloworld.c
I have a successful build!
I made these changes before running the script again.
In the script I changed the following:
qbittorrent_ver=release-4.5.0beta1
min_macos_ver=10.14
qt_ver=6.4.0
I installed re2c
using brew and added it to my path for this session:
brew install re2c
export PATH="/Users/john/.pyenv/shims:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/usr/local/bin/re2c:"
One thing... the build didn't end up in the Downloads directory..
/Users/john/Build/qbt/qBittorrent-release-4.5.0beta1-macOS-x86_64.dmg
Script shows:
prod_dir="${HOME}/Downloads"
...
[100%] Built target qbt_app
/Users/john/Build/qbt/cmake-3.23.3-macos-universal/CMake.app/Contents/bin/cmake -E cmake_progress_start /Users/john/Build/qbt/build/x86_64/qBittorrent/CMakeFiles 0
+ pushd /Users/john/Build/qbt/build/x86_64/qBittorrent
+ rm -rf qBittorrent/
+ mkdir -p qBittorrent
+ ln -s /Applications qBittorrent/Applications
+ mv qbittorrent.app qBittorrent/qBittorrent.app
+ codesign --deep --force --verify --verbose --sign - qBittorrent/qBittorrent.app
qBittorrent/qBittorrent.app: signed app bundle with Mach-O thin (x86_64) [org.qbittorrent.qBittorrent]
+ hdiutil create -srcfolder qBittorrent -nospotlight -layout NONE -fs HFS+ -format ULFO -ov /Users/john/Build/qbt/qBittorrent-release-4.5.0beta1-macOS-x86_64.dmg
......................................................................................................................................................................................................
created: /Users/john/Build/qbt/qBittorrent-release-4.5.0beta1-macOS-x86_64.dmg
+ popd
+ [[ 0 -eq 0 ]]
I tested build again (native arm), on latest xcode; it worked. I updated deps and set min macos ver back to 10.14 (this is most likely the source of the issue, apart from maybe unstable sources.)
Worked out of the box on my M1 MBP on 13.0, thanks!
anyone have any changes/updates to this script?
I am struggling to get this working on macOS 14.5
[100%] Linking CXX executable ../../qbittorrent.app/Contents/MacOS/qbittorrent
cd /Users/john/Build/qbt/build/x86_64/qBittorrent/src/app && /Users/john/Build/qbt/cmake-3.25.1-macos-universal/CMake.app/Contents/bin/cmake -E cmake_link_script CMakeFiles/qbt_app.dir/link.txt --verbose=1
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -O3 -DNDEBUG -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -mmacosx-version-min=14.0 -Wl,-search_paths_first -Wl,-headerpad_max_install_names -rdynamic -Wl,-dead_strip CMakeFiles/qbt_app.dir/qbt_app_autogen/mocs_compilation.cpp.o CMakeFiles/qbt_app.dir/application.cpp.o CMakeFiles/qbt_app.dir/applicationinstancemanager.cpp.o CMakeFiles/qbt_app.dir/cmdoptions.cpp.o CMakeFiles/qbt_app.dir/filelogger.cpp.o CMakeFiles/qbt_app.dir/main.cpp.o CMakeFiles/qbt_app.dir/qtlocalpeer/qtlocalpeer.cpp.o CMakeFiles/qbt_app.dir/signalhandler.cpp.o CMakeFiles/qbt_app.dir/upgrade.cpp.o CMakeFiles/qbt_app.dir/stacktrace.cpp.o CMakeFiles/qbt_app.dir/qbt_app_autogen/NPXYM6ZNPF/qrc_icons.cpp.o CMakeFiles/qbt_app.dir/qbt_app_autogen/G6NVOLQRLL/qrc_searchengine.cpp.o CMakeFiles/qbt_app.dir/qbt_app_autogen/QEGXZHQBWD/qrc_lang.cpp.o CMakeFiles/qbt_app.dir/qbt_app_autogen/MMBH3QESQQ/qrc_webui_translations.cpp.o CMakeFiles/qbt_app.dir/qbt_app_autogen/TUYZJ7PCOQ/qrc_about.cpp.o CMakeFiles/qbt_app.dir/qbt_app_autogen/TEN4WZ4RQ3/qrc_webui.cpp.o -o ../../qbittorrent.app/Contents/MacOS/qbittorrent /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/Gui_resources_1/.qt/rcc/qrc_qpdf_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/Gui_resources_2/.qt/rcc/qrc_gui_shaders_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/Widgets_resources_1/.qt/rcc/qrc_qstyle_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/Widgets_resources_2/.qt/rcc/qrc_qstyle1_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/Widgets_resources_3/.qt/rcc/qrc_qstyle_fusion_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/Widgets_resources_4/.qt/rcc/qrc_qmessagebox_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/networkinformation/objects-Release/QSCNetworkReachabilityNetworkInformationPlugin_init/QSCNetworkReachabilityNetworkInformationPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/objects-Release/QSecureTransportBackendPlugin_init/QSecureTransportBackendPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/objects-Release/QTlsBackendOpenSSLPlugin_init/QTlsBackendOpenSSLPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/sqldrivers/objects-Release/QSQLiteDriverPlugin_init/QSQLiteDriverPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/lib/objects-Release/QCocoaIntegrationPlugin_resources_1/.qt/rcc/qrc_qcocoaresources_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/platforms/objects-Release/QCocoaIntegrationPlugin_init/QCocoaIntegrationPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/objects-Release/QGifPlugin_init/QGifPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/objects-Release/QICOPlugin_init/QICOPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/objects-Release/QJpegPlugin_init/QJpegPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/iconengines/objects-Release/QSvgIconPlugin_init/QSvgIconPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/objects-Release/QSvgPlugin_init/QSvgPlugin_init.cpp.o /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/styles/objects-Release/QMacStylePlugin_init/QMacStylePlugin_init.cpp.o ../base/libqbt_base.a ../gui/libqbt_gui.a ../webui/libqbt_webui.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Widgets.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/styles/libqmacstyle.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Widgets.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/styles/libqmacstyle.a -lz /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Gui.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/platforms/libqcocoa.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqgif.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqico.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqjpeg.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/iconengines/libqsvgicon.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqsvg.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Svg.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Gui.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/platforms/libqcocoa.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqgif.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqico.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqjpeg.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/iconengines/libqsvgicon.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqsvg.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Svg.a -Xlinker -framework -Xlinker OpenGL -Xlinker -framework -Xlinker AGL -framework ImageIO -framework CoreGraphics -framework CoreText /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6BundledHarfbuzz.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6BundledFreetype.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6BundledLibpng.a -framework Carbon -framework CoreVideo -framework IOSurface -framework Metal -framework QuartzCore -framework UniformTypeIdentifiers /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6BundledLibjpeg.a -lobjc ../base/libqbt_base.a /usr/local/lib/libcrypto.dylib /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/lib/libz.tbd /Users/john/Build/qbt/lib/x86_64/libtorrent-rasterbar/lib/libtorrent-rasterbar.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Network.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/networkinformation/libqscnetworkreachability.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/libqsecuretransportbackend.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/libqopensslbackend.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Network.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/networkinformation/libqscnetworkreachability.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/libqsecuretransportbackend.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/libqopensslbackend.a -framework CFNetwork /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/lib/libresolv.tbd -Xlinker -framework -Xlinker GSS -framework SystemConfiguration /usr/local/lib/libssl.dylib /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Sql.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/sqldrivers/libqsqlite.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Sql.a /Users/john/Build/qbt/lib/x86_64/qt6/./plugins/sqldrivers/libqsqlite.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Xml.a /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Core.a -framework CoreFoundation -lz -framework IOKit -framework Foundation -framework DiskArbitration -framework AppKit -framework ApplicationServices -framework CoreServices -framework Security /Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6BundledPcre2.a -Xlinker -framework -Xlinker AppKit -Xlinker -framework -Xlinker Carbon -Xlinker -framework -Xlinker IOKit
ld: warning: ignoring duplicate libraries: '-lz', '../base/libqbt_base.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/iconengines/libqsvgicon.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqgif.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqico.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqjpeg.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/imageformats/libqsvg.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/networkinformation/libqscnetworkreachability.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/platforms/libqcocoa.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/sqldrivers/libqsqlite.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/styles/libqmacstyle.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/libqopensslbackend.a', '/Users/john/Build/qbt/lib/x86_64/qt6/./plugins/tls/libqsecuretransportbackend.a', '/Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Gui.a', '/Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Network.a', '/Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Sql.a', '/Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Svg.a', '/Users/john/Build/qbt/lib/x86_64/qt6/lib/libQt6Widgets.a'
Undefined symbols for architecture x86_64:
"_EVP_PKEY_base_id", referenced from:
q_EVP_PKEY_base_id(evp_pkey_st*) in libqopensslbackend.a[12](qsslsocket_openssl_symbols.cpp.o)
"_SSL_get_peer_certificate", referenced from:
q_SSL_get_peer_certificate(ssl_st*) in libqopensslbackend.a[12](qsslsocket_openssl_symbols.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [qbittorrent.app/Contents/MacOS/qbittorrent] Error 1
make[1]: *** [src/app/CMakeFiles/qbt_app.dir/all] Error 2
make: *** [all] Error 2
➜ brew --config
HOMEBREW_VERSION: 4.3.7-47-g09223c7
ORIGIN: https://github.com/Homebrew/brew
HEAD: 09223c700a35c020f9922b36dce4cf045674467f
Last commit: 17 hours ago
Core tap HEAD: 54b4e20793a97974b76ba0a48e7f46c02b5cb0a9
Core tap last commit: 3 weeks ago
Core tap JSON: 30 Jun 14:40 UTC
Core cask tap HEAD: 86eefe1293ab75352806c3d5c3bf2bfc7e28d006
Core cask tap last commit: 3 weeks ago
Core cask tap JSON: 30 Jun 14:40 UTC
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CASK_OPTS: ["--greedy", "--require-sha", "--no-quarantine", "--appdir=/Applications", "--fontdir=/Library/Fonts", "--qlplugindir=/Library/QuickLook", "--internet_plugindir=/Library/Internet Plug-Ins", "--prefpanedir=/Library/PreferencePanes/", "--servicedir=/Library/Services"]
HOMEBREW_DISPLAY: /private/tmp/com.apple.launchd.maWOIJjI3g/org.xquartz:0
HOMEBREW_EDITOR: nano
HOMEBREW_GITHUB_API_TOKEN: set
HOMEBREW_MAKE_JOBS: 16
HOMEBREW_SORBET_RUNTIME: set
Homebrew Ruby: 3.3.3 => /usr/local/Homebrew/Library/Homebrew/vendor/portable-ruby/3.3.3/bin/ruby
CPU: 16-core 64-bit kabylake
Clang: 15.0.0 build 1500
Git: 2.45.2 => /usr/local/bin/git
Curl: 8.6.0 => /usr/bin/curl
macOS: 14.5-x86_64
CLT: 15.3.0.0.1.1708646388
Xcode: 15.4
➜ clang++ -v
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: x86_64-apple-darwin23.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
➜ lipo -info /Users/john/Build/qbt/build/x86_64/openssl/apps/openssl
Non-fat file: /Users/john/Build/qbt/build/x86_64/openssl/apps/openssl is architecture: x86_64
@jprokos The first error appears in qt6. I would use this to update to the latest qt version and rerun
perl init-repository --module-subset=qtbase,qtsvg,qttools,qttranslations
.Clean the lib folder between builds.
For using a build directory, you just had to specify it using flag -w. You don’t need to change anything else, or you could have broken something.