Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 34 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ project(rp_soundboard)

include(files.cmake)

find_package(Python3 REQUIRED COMPONENTS Interpreter)

# Get prebuilt ffmpeg folders for windows builds
set(ffmpegIncHint "ffmpeg/include")

Expand All @@ -17,11 +19,12 @@ if (WIN32)
set(defLibSuffix "_win32.dll")
endif()
set(defPluginDir "%appdata%/TS3Client/plugins")
elseif(APPLE) # untested thanks to MacOS being a pain in the ass to set up in VM
# mac has no 32 bit variant
set(defFFmpegLibHint "ffmpeg/lib_mac_x64")
set(defLibSuffix "_mac.so")
set(defPluginDir "~/.ts3client/plugins")
elseif(APPLE)
# Build for native arch by default. Override with -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
# for universal binary (requires universal Qt libs).
set(defFFmpegLibHint "ffmpeg/lib_mac_universal")
set(defLibSuffix "_mac.dylib")
set(defPluginDir "$ENV{HOME}/Library/Application Support/TeamSpeak 3/plugins")
else()
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(defFFmpegLibHint "ffmpeg/lib_lin_x64")
Expand Down Expand Up @@ -65,7 +68,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
add_custom_target(autogenFiles ALL
BYPRODUCTS "src/version/version.h" "deploy/package.ini"
COMMENT "running autogen file script"
COMMAND python version.py
COMMAND ${Python3_EXECUTABLE} version.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

Expand All @@ -78,6 +81,23 @@ target_link_libraries(rp_soundboard Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Network
if (WIN32)
# only link this way on Windows. Linux requires VERY special linker commands, see below
target_link_libraries(rp_soundboard ${avcodec} ${avformat} ${avutil} ${swresample})
elseif(APPLE)
target_link_libraries(rp_soundboard ${avcodec} ${avformat} ${avutil} ${swresample})
# System frameworks required by FFmpeg on macOS
# All are needed because the pre-built static libs contain symbols from these
# frameworks, and -Wl,-all_load pulls in all object files.
find_library(AUDIOTOOLBOX AudioToolbox)
find_library(COREAUDIO CoreAudio)
find_library(COREFOUNDATION CoreFoundation)
find_library(COREMEDIA CoreMedia)
find_library(COREVIDEO CoreVideo)
find_library(VIDEOTOOLBOX VideoToolbox)
find_library(SECURITY Security)
target_link_libraries(rp_soundboard
${AUDIOTOOLBOX} ${COREAUDIO} ${COREFOUNDATION}
${COREMEDIA} ${COREVIDEO} ${VIDEOTOOLBOX} ${SECURITY}
bz2 z iconv
)
endif()

target_include_directories(rp_soundboard PUBLIC "pluginsdk/include" ${ffmpegIncludeDir})
Expand All @@ -92,13 +112,15 @@ if (MSVC)
target_sources(rp_soundboard PRIVATE "src/windows/resource.h" "src/windows/Resource.rc")
target_link_libraries(rp_soundboard wsock32 ws2_32 secur32) # some windows stuff
target_compile_options(rp_soundboard PRIVATE /MP) # multiprocessor compiling
elseif(APPLE)
target_compile_definitions(rp_soundboard PRIVATE "MACOS")
# macOS uses ld64 which has different flags than GNU ld
set_target_properties(rp_soundboard PROPERTIES
LINK_FLAGS "-Wl,-all_load"
)
else()
if(APPLE)
target_compile_definitions(rp_soundboard PRIVATE "MACOS")
else()
target_compile_definitions(rp_soundboard PRIVATE "LINUX")
endif()
# Compile options that are required to NOT get the "recompile with -fPIC"
target_compile_definitions(rp_soundboard PRIVATE "LINUX")
# GNU ld flags required to NOT get the "recompile with -fPIC"
# error when linking the ffmpeg libs. Took me many hours to find this out...
set_target_properties(rp_soundboard PROPERTIES LINK_FLAGS
"-Wl,-Bsymbolic -Wl,--whole-archive \
Expand Down
28 changes: 23 additions & 5 deletions create-pluginfile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,26 @@ execute_process(
)
string(STRIP "${gitVersionRaw}" gitVersion)

message("Running 7zip to create final plugin package in ${RPSB_PLUGINFILE_OUTPUT_DIR}")
execute_process(
COMMAND "C:/Program Files/7-Zip/7z.exe" a "${RPSB_PLUGINFILE_OUTPUT_DIR}/rp_soundboard_${gitVersion}.ts3_plugin" -tzip -mx=9 -mm=Deflate "*"
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
)
set(PLUGIN_FILENAME "rp_soundboard_${gitVersion}.ts3_plugin")
set(PLUGIN_OUTPUT "${RPSB_PLUGINFILE_OUTPUT_DIR}/${PLUGIN_FILENAME}")

message("Creating final plugin package in ${RPSB_PLUGINFILE_OUTPUT_DIR}")

if(WIN32)
execute_process(
COMMAND "C:/Program Files/7-Zip/7z.exe" a "${PLUGIN_OUTPUT}" -tzip -mx=9 -mm=Deflate "*"
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
RESULT_VARIABLE zip_result
)
else()
# Use zip on Linux/macOS
execute_process(
COMMAND zip -r -9 "${PLUGIN_OUTPUT}" .
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
RESULT_VARIABLE zip_result
)
endif()

if(NOT zip_result EQUAL 0)
message(FATAL_ERROR "Failed to create plugin package (exit code: ${zip_result})")
endif()
90 changes: 80 additions & 10 deletions ffmpeg/build-scripts/build_ffmpeg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,31 @@ else
toolchainopt=""
fi


if [[ "$1" == "x86" ]]; then
# On macOS, build universal binary (arm64 + x86_64) by default
if [[ "$machine" == "Mac" && "$1" == "" ]]; then
echo "Machine = Mac (Universal Binary: arm64 + x86_64)"
build_mac_universal=true
elif [[ "$1" == "x86" ]]; then
archprefix="x86"
arch="x86"
build_mac_universal=false
elif [[ "$1" == "arm64" || "$1" == "aarch64" ]]; then
archprefix="arm64"
arch="aarch64"
build_mac_universal=false
elif [[ "$1" == "x64" || "$1" == "x86_64" || "$1" == "amd64" || "$(uname -m)" == "x86_64" ]]; then
archprefix="x64"
arch="x86_64"
build_mac_universal=false
else
archprefix="x86"
arch="x86"
build_mac_universal=false
fi

echo "Machine =" $machine $arch
if [[ "$build_mac_universal" != "true" ]]; then
echo "Machine =" $machine $arch
fi

opts="\
--enable-pic \
Expand Down Expand Up @@ -320,13 +332,71 @@ disabled_decs="\
--disable-decoder=webvtt \
--disable-decoder=xsub"

cmd="./configure --arch=$arch --prefix=$archprefix $toolchainopt $opts $disabled_decs"
njobs=$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 8)
if [ "$njobs" -gt 16 ]; then
njobs=16
fi

build_single_arch() {
local build_arch="$1"
local prefix="$2"
local cc_override="$3"
local extra_configure="$4"

local -a configure_args=(--arch=$build_arch --prefix=$prefix)
if [[ -n "$cc_override" ]]; then
configure_args+=(--cc="$cc_override")
fi
if [[ "$machine" == "Mac" ]]; then
configure_args+=(--extra-cflags="-Wno-incompatible-function-pointer-types")
fi

pushd ../ffmpeg
echo "=== Configuring FFmpeg for $build_arch ==="
./configure "${configure_args[@]}" \
$extra_configure $toolchainopt $opts $disabled_decs
make clean && make -j$njobs && make install
popd
}

pushd ../ffmpeg
echo "Command: $cmd"
$cmd
make clean && make -j8 && make install
if [[ "$build_mac_universal" == "true" ]]; then
host_arch="$(uname -m)"
cross_compile_flags="--enable-cross-compile --target-os=darwin"

popd
# Build arm64 (cross-compile on Intel, native on Apple Silicon)
echo "=== Building FFmpeg for arm64 ==="
if [[ "$host_arch" == "x86_64" ]]; then
build_single_arch "aarch64" "arm64" "clang -arch arm64" "$cross_compile_flags"
else
build_single_arch "aarch64" "arm64" "clang -arch arm64" ""
fi

./copy_binaries.sh
# Build x86_64 (native on Intel, cross-compile on Apple Silicon)
echo "=== Building FFmpeg for x86_64 ==="
if [[ "$host_arch" == "arm64" ]]; then
build_single_arch "x86_64" "x64" "clang -arch x86_64" "$cross_compile_flags"
else
build_single_arch "x86_64" "x64" "clang -arch x86_64" ""
fi

# Combine into universal binaries using lipo
echo "=== Creating universal binaries with lipo ==="
mkdir -p ../ffmpeg/universal/lib
cp -R ../ffmpeg/x64/include ../ffmpeg/universal/include

for lib in libavcodec.a libavformat.a libavutil.a libswresample.a; do
lipo -create \
"../ffmpeg/arm64/lib/$lib" \
"../ffmpeg/x64/lib/$lib" \
-output "../ffmpeg/universal/lib/$lib"
echo "Created universal $lib"
done

./copy_binaries.sh
else
# Remove stale universal artifacts to prevent copy_binaries.sh from
# copying outdated libs into lib_mac_universal
rm -rf ../ffmpeg/universal
build_single_arch "$arch" "$archprefix" "" ""
./copy_binaries.sh
fi
10 changes: 10 additions & 0 deletions ffmpeg/build-scripts/copy_binaries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ esac

pushd ..

# Universal binary (macOS only)
if [ -d "ffmpeg/universal" ]; then
mkdir -p "${prefix}_universal"
cp ffmpeg/universal/lib/${infix}avcodec.$postfix ${prefix}_universal/${infix}avcodec.$postfix
cp ffmpeg/universal/lib/${infix}avformat.$postfix ${prefix}_universal/${infix}avformat.$postfix
cp ffmpeg/universal/lib/${infix}avutil.$postfix ${prefix}_universal/${infix}avutil.$postfix
cp ffmpeg/universal/lib/${infix}swresample.$postfix ${prefix}_universal/${infix}swresample.$postfix
cp -R ffmpeg/universal/include ${prefix}_universal/include
fi

if [ -d "ffmpeg/x64" ]; then
mkdir -p "${prefix}_x64"
cp ffmpeg/x64/lib/libavcodec.a ${prefix}_x64/${infix}avcodec.$postfix
Expand Down
4 changes: 2 additions & 2 deletions src/ConfigModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ void ConfigModel::setSoundInfo( int itemId, const SoundInfo &info )
QString ConfigModel::GetConfigPath()
{
// Find config path for config class
char* configPath = (char*)malloc(PATH_BUFSIZE);
char configPath[PATH_BUFSIZE];
ts3Functions.getConfigPath(configPath, PATH_BUFSIZE);
return QString::fromUtf8(configPath);
}
Expand Down Expand Up @@ -433,7 +433,7 @@ void ConfigModel::setBubbleColsBuild(int build)
//---------------------------------------------------------------
std::vector<SoundInfo> ConfigModel::getInitialSounds()
{
char* pluginPath = (char*)malloc(PATH_BUFSIZE);
char pluginPath[PATH_BUFSIZE];
ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE, getPluginID());
QString fullPath = QString::fromUtf8(pluginPath);
QChar last = fullPath[fullPath.count() - 1];
Expand Down
4 changes: 3 additions & 1 deletion src/buildinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
#define BUILD_NAME "Linux 64-bit"
#elif defined(LINUX) && defined(__i386__)
#define BUILD_NAME "Linux 32-bit"
#elif defined(MACOS) && defined(__aarch64__)
#define BUILD_NAME "MacOS arm64"
#elif defined(MACOS)
#define BUILD_NAME "MacOS 64-bit"
#define BUILD_NAME "MacOS x86_64"
#else
#define BUILD_NAME "Unknown Build"
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/package.ini.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Name = RP Soundboard
Type = Plugin
Author = Marius Gräfe
Version = @version@
Platforms = win32, win64, linux_amd64
Platforms = win32, win64, linux_amd64, mac
Description = Easy to use soundboard to annoy your friends. Play any sound file to all people in your channel (and yourself).
No external tools and no changes to Teamspeaks settings required!

Expand Down