CMake: Don't unnecessarily bundle

Use RPATH when not creating a bundle.
pull/3794/head
Stenzek 2 weeks ago
parent f39feb9d8f
commit fa77cd4853
No known key found for this signature in database

@ -370,10 +370,11 @@ function(add_resources TARGET DEST_SUBDIR SOURCE_DIR)
endforeach()
endfunction()
function(bundle_libraries TARGET)
function(add_runtime_libraries TARGET)
unset(LIBRARY_SOURCES)
unset(LIBRARY_RPATHS)
foreach(NAME IN LISTS ARGN)
get_target_property(dyn_lib_path ${NAME} IMPORTED_LOCATION_RELEASE)
get_target_property(dyn_lib_path ${NAME} IMPORTED_LOCATION_RELEASE)
get_target_property(dyn_lib_soname ${NAME} IMPORTED_SONAME_RELEASE)
if(dyn_lib_soname)
string(REPLACE "@rpath/" "" dyn_lib_soname_filename "${dyn_lib_soname}")
@ -388,19 +389,35 @@ function(bundle_libraries TARGET)
message(FATAL_ERROR "Could not find ${NAME}.")
endif()
message(STATUS "Bundling imported library ${dyn_lib_soname}")
get_filename_component(dyn_lib_dir "${dyn_lib_path}" DIRECTORY)
if(APPLE)
target_sources(${target} PRIVATE "${dyn_lib_path}")
set_source_files_properties("${dyn_lib_path}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks)
if(APPLE AND NOT CMAKE_GENERATOR STREQUAL "Xcode" AND NOT SKIP_POSTPROCESS_BUNDLE)
# For normal macOS bundle generators, put the dylib into Contents/Frameworks.
message(STATUS "Bundling imported library ${dyn_lib_soname}")
target_sources(${TARGET} PRIVATE "${dyn_lib_path}")
set_source_files_properties(
"${dyn_lib_path}"
PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks
)
else()
list(APPEND LIBRARY_SOURCES "${dyn_lib_path}")
# Linux, and macOS when using the Xcode generator/not using bundles.
list(APPEND LIBRARY_RPATHS "${dyn_lib_dir}")
endif()
endforeach()
if(NOT APPLE)
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LIBRARY_SOURCES} "$<TARGET_FILE_DIR:${TARGET}>"
# Add the required library directories to the target's existing
# build RPATH, without adding duplicate entries.
if(LIBRARY_RPATHS)
get_target_property(existing_rpath ${TARGET} BUILD_RPATH)
if(NOT existing_rpath)
set(existing_rpath "")
endif()
list(APPEND existing_rpath ${LIBRARY_RPATHS})
list(REMOVE_DUPLICATES existing_rpath)
set_target_properties(
${TARGET}
PROPERTIES BUILD_RPATH "${existing_rpath}"
)
endif()
endfunction()

@ -33,15 +33,28 @@ APPDIRNAME=DuckStation.AppDir
STRIP=strip
declare -a MANUAL_LIBS=(
"libharfbuzz.so"
"libfreetype.so.6"
"libjpeg.so.62"
"libpng16.so.16"
"libsharpyuv.so.0"
"libwebpdecoder.so.3"
"libwebpdemux.so.2"
"libwebpmux.so.3"
"libwebp.so.7"
"libz.so.1"
"libdiscord-rpc.so"
"libshaderc_shared.so"
"libspirv-cross-c-shared.so.0"
"libsqlite3.so.3"
"libavcodec.so.63"
"libavformat.so.63"
"libavutil.so.61"
"libswscale.so.10"
"libswresample.so.7"
"libopenh264.so.8"
"libharfbuzz.so"
"libfreetype.so.6"
)
set -e
@ -117,7 +130,6 @@ $LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/duckstat
echo "Copying resources into AppDir..."
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
cp "$BUILDDIR/bin/"*.so* "$OUTDIR/usr/bin"
# Restore unstripped deps (for cache).
rm -fr "$DEPSDIR"

@ -85,6 +85,7 @@ declare -a DEPLIBS=(
"libpng16.so.16"
"libSDL3.so.0"
"libsharpyuv.so.0"
"libwebpdecoder.so.3"
"libwebpdemux.so.2"
"libwebpmux.so.3"
"libwebp.so.7"
@ -97,6 +98,7 @@ declare -a DEPLIBS=(
"libshaderc_shared.so"
"libsoundtouch.so.2"
"libspirv-cross-c-shared.so.0"
"libsqlite3.so.3"
#"libavcodec.so.61"
#"libavformat.so.61"

@ -88,26 +88,6 @@ std::string DynamicLibrary::GetVersionedFilename(const char* libname, int major,
#endif
}
std::string DynamicLibrary::GetBundledLibraryPath(const char* libname, int major /*= -1*/, int minor /*= -1*/,
int patch /*= -1*/)
{
Error error;
std::string program_path = FileSystem::GetProgramPath(&error);
if (program_path.empty()) [[unlikely]]
{
ERROR_LOG("Failed to get program path: {}", error.GetDescription());
return {};
}
#ifdef __APPLE__
program_path = Path::Combine(Path::GetDirectory(program_path), ".." FS_OSPATH_SEPARATOR_STR "Frameworks");
Path::Canonicalize(&program_path);
return Path::Combine(program_path, GetVersionedFilename(libname, major, minor, patch));
#else
return Path::Combine(Path::GetDirectory(program_path), GetVersionedFilename(libname, major, minor, patch));
#endif
}
bool DynamicLibrary::Open(const char* filename, Error* error)
{
#ifdef _WIN32

@ -39,9 +39,6 @@ public:
/// Mac: libLIBNAME.MAJOR.MINOR.PATCH.dylib
static std::string GetVersionedFilename(const char* libname, int major = -1, int minor = -1, int patch = -1);
/// Returns the path to the specified library name, depending on the platform.
static std::string GetBundledLibraryPath(const char* libname, int major = -1, int minor = -1, int patch = -1);
/// Returns true if a module is loaded, otherwise false.
bool IsOpen() const { return m_handle != nullptr; }

@ -226,5 +226,5 @@ function(add_core_resources target)
add_resources(${target} "resources" ${CMAKE_SOURCE_DIR}/data/resources)
# Copy dynamically-loaded libraries into the bundle.
bundle_libraries(${target} DiscordRPC::discord-rpc)
add_runtime_libraries(${target} DiscordRPC::discord-rpc)
endfunction()

@ -58,7 +58,7 @@ bool DiscordPresence::OpenDiscordRPC(Error* error)
if (s_locals.rpc_library.IsOpen())
return true;
if (!s_locals.rpc_library.Open(DynamicLibrary::GetBundledLibraryPath("discord-rpc").c_str(), error))
if (!s_locals.rpc_library.Open(DynamicLibrary::GetVersionedFilename("discord-rpc").c_str(), error))
{
Error::AddPrefix(error, "Failed to load discord-rpc: ");
return false;

@ -280,10 +280,10 @@ function(add_util_resources target)
endif()
# Copy dynamically-loaded libraries into the bundle.
bundle_libraries(${target} spirv-cross-c-shared Shaderc::shaderc_shared SQLite3::sqlite3-shared
libjpeg-turbo::jpeg PNG::png_shared WebP::webp WebP::sharpyuv WebP::webpdecoder
WebP::webpdemux WebP::libwebpmux)
add_runtime_libraries(${target} spirv-cross-c-shared Shaderc::shaderc_shared SQLite3::sqlite3-shared
libjpeg-turbo::jpeg PNG::png_shared WebP::webp WebP::sharpyuv WebP::webpdecoder
WebP::webpdemux WebP::libwebpmux)
if(APPLE)
bundle_libraries(${target} harfbuzz::harfbuzz)
add_runtime_libraries(${target} harfbuzz::harfbuzz)
endif()
endfunction()

@ -1403,7 +1403,7 @@ bool DynShaderc::Open(Error* error)
std::call_once(s_locals.shaderc_init_flag, [&error]() {
Error lerror;
DynamicLibrary lib;
if (!lib.Open(DynamicLibrary::GetBundledLibraryPath("shaderc_shared").c_str(), error))
if (!lib.Open(DynamicLibrary::GetVersionedFilename("shaderc_shared").c_str(), error))
{
ERROR_LOG("Failed to load shaderc: {}", (error ? error : &lerror)->GetDescription());
Error::AddPrefix(error, "Failed to load shaderc: ");
@ -1444,9 +1444,9 @@ bool DynSpirvCross::Open(Error* error)
DynamicLibrary lib;
#if defined(_WIN32) || defined(__ANDROID__)
// SPVC's build on Windows doesn't spit out a versioned DLL.
const std::string libpath = DynamicLibrary::GetBundledLibraryPath("spirv-cross-c-shared");
const std::string libpath = DynamicLibrary::GetVersionedFilename("spirv-cross-c-shared");
#else
const std::string libpath = DynamicLibrary::GetBundledLibraryPath("spirv-cross-c-shared", SPVC_C_API_VERSION_MAJOR);
const std::string libpath = DynamicLibrary::GetVersionedFilename("spirv-cross-c-shared", SPVC_C_API_VERSION_MAJOR);
#endif
if (!lib.Open(libpath.c_str(), error ? error : &lerror))
{

@ -43,7 +43,7 @@ bool DynSqlite::Open(Error* error)
std::call_once(s_locals.sqlite_init_flag, [&error]() {
Error lerror;
DynamicLibrary lib;
if (!lib.Open(DynamicLibrary::GetBundledLibraryPath("sqlite3", lib_major_version).c_str(), &lerror))
if (!lib.Open(DynamicLibrary::GetVersionedFilename("sqlite3", lib_major_version).c_str(), &lerror))
{
ERROR_LOG("Failed to load sqlite: {}", lerror.GetDescription());
Error::SetStringFmt(error, "Failed to load sqlite: {}", lerror.GetDescription());

Loading…
Cancel
Save