mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-09 23:34:20 +00:00
macOS/iOS: Add the ability to weak link module frameworks
This commit is contained in:
parent
04e7014d0f
commit
e5cbcd7628
6 changed files with 81 additions and 45 deletions
|
|
@ -185,11 +185,18 @@ Possible values:
|
||||||
parent folder, which need to be added to a project's header search path
|
parent folder, which need to be added to a project's header search path
|
||||||
|
|
||||||
- OSXFrameworks
|
- OSXFrameworks
|
||||||
- (Optional) A list (space or comma-separated) of OSX frameworks that are needed
|
- (Optional) A list (space or comma-separated) of OSX frameworks that are needed by this module
|
||||||
|
|
||||||
|
- WeakOSXFrameworks
|
||||||
|
- (Optional) A list (space or comma-separated) of weak linked OSX frameworks that are needed
|
||||||
by this module
|
by this module
|
||||||
|
|
||||||
- iOSFrameworks
|
- iOSFrameworks
|
||||||
- (Optional) Like OSXFrameworks, but for iOS targets
|
- (Optional) A list (space or comma-separated) of iOS frameworks that are needed by this module
|
||||||
|
|
||||||
|
- WeakiOSFrameworks
|
||||||
|
- (Optional) A list (space or comma-separated) of weak linked iOS frameworks that are needed
|
||||||
|
by this module
|
||||||
|
|
||||||
- linuxPackages
|
- linuxPackages
|
||||||
- (Optional) A list (space or comma-separated) pkg-config packages that should be used to pass
|
- (Optional) A list (space or comma-separated) pkg-config packages that should be used to pass
|
||||||
|
|
|
||||||
|
|
@ -265,22 +265,29 @@ endfunction()
|
||||||
|
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
|
||||||
# Takes a target, a link visibility, and a variable-length list of framework
|
# Takes a target, a link visibility, if it should be a weak link, and a variable-length list of
|
||||||
# names. On macOS, finds the requested frameworks using `find_library` and
|
# framework names. On macOS, for non-weak links, this finds the requested frameworks using
|
||||||
# links them. On iOS, links directly with `-framework Name`.
|
# `find_library`.
|
||||||
function(_juce_link_frameworks target visibility)
|
function(_juce_link_frameworks target visibility)
|
||||||
foreach(framework IN LISTS ARGN)
|
set(options WEAK)
|
||||||
|
cmake_parse_arguments(JUCE_LINK_FRAMEWORKS "${options}" "" "" ${ARGN})
|
||||||
|
foreach(framework IN LISTS JUCE_LINK_FRAMEWORKS_UNPARSED_ARGUMENTS)
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
find_library("juce_found_${framework}" "${framework}" REQUIRED)
|
if(JUCE_LINK_FRAMEWORKS_WEAK)
|
||||||
target_link_libraries("${target}" "${visibility}" "${juce_found_${framework}}")
|
set(framework_flags "-weak_framework ${framework}")
|
||||||
|
else()
|
||||||
|
find_library("juce_found_${framework}" "${framework}" REQUIRED)
|
||||||
|
set(framework_flags "${juce_found_${framework}}")
|
||||||
|
endif()
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||||
# CoreServices is only available on iOS 12+, we must link it weakly on earlier platforms
|
# CoreServices is only available on iOS 12+, we must link it weakly on earlier platforms
|
||||||
if((framework STREQUAL "CoreServices") AND (CMAKE_OSX_DEPLOYMENT_TARGET LESS 12.0))
|
if(JUCE_LINK_FRAMEWORKS_WEAK OR ((framework STREQUAL "CoreServices") AND (CMAKE_OSX_DEPLOYMENT_TARGET LESS 12.0)))
|
||||||
set(framework_flags "-weak_framework ${framework}")
|
set(framework_flags "-weak_framework ${framework}")
|
||||||
else()
|
else()
|
||||||
set(framework_flags "-framework ${framework}")
|
set(framework_flags "-framework ${framework}")
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
if(NOT framework_flags STREQUAL "")
|
||||||
target_link_libraries("${target}" "${visibility}" "${framework_flags}")
|
target_link_libraries("${target}" "${visibility}" "${framework_flags}")
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
@ -391,6 +398,11 @@ endfunction()
|
||||||
|
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
|
|
||||||
|
function(_juce_remove_empty_list_elements arg)
|
||||||
|
list(FILTER ${arg} EXCLUDE REGEX "^$")
|
||||||
|
set(${arg} ${${arg}} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
function(juce_add_module module_path)
|
function(juce_add_module module_path)
|
||||||
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
|
set(one_value_args INSTALL_PATH ALIAS_NAMESPACE)
|
||||||
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
|
cmake_parse_arguments(JUCE_ARG "" "${one_value_args}" "" ${ARGN})
|
||||||
|
|
@ -522,26 +534,34 @@ function(juce_add_module module_path)
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
_juce_get_metadata("${metadata_dict}" OSXFrameworks module_osxframeworks)
|
_juce_get_metadata("${metadata_dict}" OSXFrameworks module_osxframeworks)
|
||||||
|
|
||||||
|
_juce_remove_empty_list_elements(module_osxframeworks)
|
||||||
foreach(module_framework IN LISTS module_osxframeworks)
|
foreach(module_framework IN LISTS module_osxframeworks)
|
||||||
if(module_framework STREQUAL "")
|
|
||||||
continue()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
_juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
|
_juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
_juce_get_metadata("${metadata_dict}" WeakOSXFrameworks module_weakosxframeworks)
|
||||||
|
|
||||||
|
_juce_remove_empty_list_elements(module_weakosxframeworks)
|
||||||
|
foreach(module_framework IN LISTS module_weakosxframeworks)
|
||||||
|
_juce_link_frameworks("${module_name}" INTERFACE WEAK "${module_framework}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" OSXLibs)
|
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" OSXLibs)
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||||
_juce_get_metadata("${metadata_dict}" iOSFrameworks module_iosframeworks)
|
_juce_get_metadata("${metadata_dict}" iOSFrameworks module_iosframeworks)
|
||||||
|
|
||||||
|
_juce_remove_empty_list_elements(module_iosframeworks)
|
||||||
foreach(module_framework IN LISTS module_iosframeworks)
|
foreach(module_framework IN LISTS module_iosframeworks)
|
||||||
if(module_framework STREQUAL "")
|
|
||||||
continue()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
_juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
|
_juce_link_frameworks("${module_name}" INTERFACE "${module_framework}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
_juce_get_metadata("${metadata_dict}" WeakiOSFrameworks module_weakiosframeworks)
|
||||||
|
|
||||||
|
_juce_remove_empty_list_elements(module_weakiosframeworks)
|
||||||
|
foreach(module_framework IN LISTS module_weakiosframeworks)
|
||||||
|
_juce_link_frameworks("${module_name}" INTERFACE WEAK "${module_framework}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" iOSLibs)
|
_juce_link_libs_from_metadata("${module_name}" "${metadata_dict}" iOSLibs)
|
||||||
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
|
elseif((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME MATCHES ".*BSD"))
|
||||||
_juce_get_metadata("${metadata_dict}" linuxPackages module_linuxpackages)
|
_juce_get_metadata("${metadata_dict}" linuxPackages module_linuxpackages)
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ namespace
|
||||||
|
|
||||||
var moduleInfo (new DynamicObject());
|
var moduleInfo (new DynamicObject());
|
||||||
moduleInfo.getDynamicObject()->setProperty ("file", getModulePackageName (module));
|
moduleInfo.getDynamicObject()->setProperty ("file", getModulePackageName (module));
|
||||||
moduleInfo.getDynamicObject()->setProperty ("info", module.moduleInfo.getModuleInfo());
|
moduleInfo.getDynamicObject()->setProperty ("info", module.moduleDescription.getModuleInfo());
|
||||||
infoList.append (moduleInfo);
|
infoList.append (moduleInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
LibraryModule::LibraryModule (const ModuleDescription& d)
|
LibraryModule::LibraryModule (const ModuleDescription& d)
|
||||||
: moduleInfo (d)
|
: moduleDescription (d)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,15 +36,15 @@ void LibraryModule::writeIncludes (ProjectSaver& projectSaver, OutputStream& out
|
||||||
|
|
||||||
if (modules.shouldCopyModuleFilesLocally (moduleID))
|
if (modules.shouldCopyModuleFilesLocally (moduleID))
|
||||||
{
|
{
|
||||||
auto juceModuleFolder = moduleInfo.getFolder();
|
auto juceModuleFolder = moduleDescription.getFolder();
|
||||||
|
|
||||||
auto localModuleFolder = project.getLocalModuleFolder (moduleID);
|
auto localModuleFolder = project.getLocalModuleFolder (moduleID);
|
||||||
localModuleFolder.createDirectory();
|
localModuleFolder.createDirectory();
|
||||||
projectSaver.copyFolder (juceModuleFolder, localModuleFolder);
|
projectSaver.copyFolder (juceModuleFolder, localModuleFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "#include <" << moduleInfo.getModuleFolder().getFileName() << "/"
|
out << "#include <" << moduleDescription.getModuleFolder().getFileName() << "/"
|
||||||
<< moduleInfo.getHeader().getFileName()
|
<< moduleDescription.getHeader().getFileName()
|
||||||
<< ">" << newLine;
|
<< ">" << newLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ void LibraryModule::addSearchPathsToExporter (ProjectExporter& exporter) const
|
||||||
if (moduleLibDir.exists())
|
if (moduleLibDir.exists())
|
||||||
exporter.addToModuleLibPaths ({ libSubdirPath, moduleRelativePath.getRoot() });
|
exporter.addToModuleLibPaths ({ libSubdirPath, moduleRelativePath.getRoot() });
|
||||||
|
|
||||||
auto extraInternalSearchPaths = moduleInfo.getExtraSearchPaths().trim();
|
auto extraInternalSearchPaths = moduleDescription.getExtraSearchPaths().trim();
|
||||||
|
|
||||||
if (extraInternalSearchPaths.isNotEmpty())
|
if (extraInternalSearchPaths.isNotEmpty())
|
||||||
{
|
{
|
||||||
|
|
@ -84,7 +84,7 @@ void LibraryModule::addSearchPathsToExporter (ProjectExporter& exporter) const
|
||||||
|
|
||||||
void LibraryModule::addDefinesToExporter (ProjectExporter& exporter) const
|
void LibraryModule::addDefinesToExporter (ProjectExporter& exporter) const
|
||||||
{
|
{
|
||||||
auto extraDefs = moduleInfo.getPreprocessorDefs().trim();
|
auto extraDefs = moduleDescription.getPreprocessorDefs().trim();
|
||||||
|
|
||||||
if (extraDefs.isNotEmpty())
|
if (extraDefs.isNotEmpty())
|
||||||
exporter.getExporterPreprocessorDefsValue() = exporter.getExporterPreprocessorDefsString() + "\n" + extraDefs;
|
exporter.getExporterPreprocessorDefsValue() = exporter.getExporterPreprocessorDefsString() + "\n" + extraDefs;
|
||||||
|
|
@ -98,7 +98,7 @@ void LibraryModule::addCompileUnitsToExporter (ProjectExporter& exporter, Projec
|
||||||
auto moduleID = getID();
|
auto moduleID = getID();
|
||||||
|
|
||||||
auto localModuleFolder = modules.shouldCopyModuleFilesLocally (moduleID) ? project.getLocalModuleFolder (moduleID)
|
auto localModuleFolder = modules.shouldCopyModuleFilesLocally (moduleID) ? project.getLocalModuleFolder (moduleID)
|
||||||
: moduleInfo.getFolder();
|
: moduleDescription.getFolder();
|
||||||
|
|
||||||
Array<File> compiled;
|
Array<File> compiled;
|
||||||
findAndAddCompiledUnits (exporter, &projectSaver, compiled);
|
findAndAddCompiledUnits (exporter, &projectSaver, compiled);
|
||||||
|
|
@ -118,6 +118,8 @@ void LibraryModule::addLibsToExporter (ProjectExporter& exporter) const
|
||||||
|
|
||||||
auto& project = exporter.getProject();
|
auto& project = exporter.getProject();
|
||||||
|
|
||||||
|
auto moduleInfo = moduleDescription.getModuleInfo();
|
||||||
|
|
||||||
if (exporter.isXcode())
|
if (exporter.isXcode())
|
||||||
{
|
{
|
||||||
auto& xcodeExporter = dynamic_cast<XcodeProjectExporter&> (exporter);
|
auto& xcodeExporter = dynamic_cast<XcodeProjectExporter&> (exporter);
|
||||||
|
|
@ -130,26 +132,29 @@ void LibraryModule::addLibsToExporter (ProjectExporter& exporter) const
|
||||||
xcodeExporter.xcodeFrameworks.add ("AudioUnit");
|
xcodeExporter.xcodeFrameworks.add ("AudioUnit");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frameworks = moduleInfo.getModuleInfo() [xcodeExporter.isOSX() ? "OSXFrameworks" : "iOSFrameworks"].toString();
|
auto frameworks = moduleInfo[xcodeExporter.isOSX() ? "OSXFrameworks" : "iOSFrameworks"].toString();
|
||||||
xcodeExporter.xcodeFrameworks.addTokens (frameworks, ", ", {});
|
xcodeExporter.xcodeFrameworks.addTokens (frameworks, ", ", {});
|
||||||
|
|
||||||
parseAndAddLibsToList (xcodeExporter.xcodeLibs, moduleInfo.getModuleInfo() [exporter.isOSX() ? "OSXLibs" : "iOSLibs"].toString());
|
auto weakFrameworks = moduleInfo[xcodeExporter.isOSX() ? "WeakOSXFrameworks" : "WeakiOSFrameworks"].toString();
|
||||||
|
xcodeExporter.xcodeWeakFrameworks.addTokens (weakFrameworks, ", ", {});
|
||||||
|
|
||||||
|
parseAndAddLibsToList (xcodeExporter.xcodeLibs, moduleInfo[exporter.isOSX() ? "OSXLibs" : "iOSLibs"].toString());
|
||||||
}
|
}
|
||||||
else if (exporter.isLinux())
|
else if (exporter.isLinux())
|
||||||
{
|
{
|
||||||
parseAndAddLibsToList (exporter.linuxLibs, moduleInfo.getModuleInfo() ["linuxLibs"].toString());
|
parseAndAddLibsToList (exporter.linuxLibs, moduleInfo["linuxLibs"].toString());
|
||||||
parseAndAddLibsToList (exporter.linuxPackages, moduleInfo.getModuleInfo() ["linuxPackages"].toString());
|
parseAndAddLibsToList (exporter.linuxPackages, moduleInfo["linuxPackages"].toString());
|
||||||
}
|
}
|
||||||
else if (exporter.isWindows())
|
else if (exporter.isWindows())
|
||||||
{
|
{
|
||||||
if (exporter.isCodeBlocks())
|
if (exporter.isCodeBlocks())
|
||||||
parseAndAddLibsToList (exporter.mingwLibs, moduleInfo.getModuleInfo() ["mingwLibs"].toString());
|
parseAndAddLibsToList (exporter.mingwLibs, moduleInfo["mingwLibs"].toString());
|
||||||
else
|
else
|
||||||
parseAndAddLibsToList (exporter.windowsLibs, moduleInfo.getModuleInfo() ["windowsLibs"].toString());
|
parseAndAddLibsToList (exporter.windowsLibs, moduleInfo["windowsLibs"].toString());
|
||||||
}
|
}
|
||||||
else if (exporter.isAndroid())
|
else if (exporter.isAndroid())
|
||||||
{
|
{
|
||||||
parseAndAddLibsToList (exporter.androidLibs, moduleInfo.getModuleInfo() ["androidLibs"].toString());
|
parseAndAddLibsToList (exporter.androidLibs, moduleInfo["androidLibs"].toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +168,7 @@ void LibraryModule::addSettingsForModuleToExporter (ProjectExporter& exporter, P
|
||||||
|
|
||||||
void LibraryModule::getConfigFlags (Project& project, OwnedArray<Project::ConfigFlag>& flags) const
|
void LibraryModule::getConfigFlags (Project& project, OwnedArray<Project::ConfigFlag>& flags) const
|
||||||
{
|
{
|
||||||
auto header = moduleInfo.getHeader();
|
auto header = moduleDescription.getHeader();
|
||||||
jassert (header.exists());
|
jassert (header.exists());
|
||||||
|
|
||||||
StringArray lines;
|
StringArray lines;
|
||||||
|
|
@ -348,7 +353,7 @@ void LibraryModule::addBrowseableCode (ProjectExporter& exporter, const Array<Fi
|
||||||
|
|
||||||
auto sourceGroup = Project::Item::createGroup (exporter.getProject(), getID(), "__mainsourcegroup" + getID(), false);
|
auto sourceGroup = Project::Item::createGroup (exporter.getProject(), getID(), "__mainsourcegroup" + getID(), false);
|
||||||
auto moduleFromProject = exporter.getModuleFolderRelativeToProject (getID());
|
auto moduleFromProject = exporter.getModuleFolderRelativeToProject (getID());
|
||||||
auto moduleHeader = moduleInfo.getHeader();
|
auto moduleHeader = moduleDescription.getHeader();
|
||||||
|
|
||||||
auto& project = exporter.getProject();
|
auto& project = exporter.getProject();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,16 @@ class LibraryModule
|
||||||
public:
|
public:
|
||||||
LibraryModule (const ModuleDescription&);
|
LibraryModule (const ModuleDescription&);
|
||||||
|
|
||||||
bool isValid() const { return moduleInfo.isValid(); }
|
bool isValid() const { return moduleDescription.isValid(); }
|
||||||
String getID() const { return moduleInfo.getID(); }
|
String getID() const { return moduleDescription.getID(); }
|
||||||
String getVendor() const { return moduleInfo.getVendor(); }
|
String getVendor() const { return moduleDescription.getVendor(); }
|
||||||
String getVersion() const { return moduleInfo.getVersion(); }
|
String getVersion() const { return moduleDescription.getVersion(); }
|
||||||
String getName() const { return moduleInfo.getName(); }
|
String getName() const { return moduleDescription.getName(); }
|
||||||
String getDescription() const { return moduleInfo.getDescription(); }
|
String getDescription() const { return moduleDescription.getDescription(); }
|
||||||
String getLicense() const { return moduleInfo.getLicense(); }
|
String getLicense() const { return moduleDescription.getLicense(); }
|
||||||
String getMinimumCppStandard() const { return moduleInfo.getMinimumCppStandard(); }
|
String getMinimumCppStandard() const { return moduleDescription.getMinimumCppStandard(); }
|
||||||
|
|
||||||
File getFolder() const { return moduleInfo.getFolder(); }
|
File getFolder() const { return moduleDescription.getFolder(); }
|
||||||
|
|
||||||
void writeIncludes (ProjectSaver&, OutputStream&);
|
void writeIncludes (ProjectSaver&, OutputStream&);
|
||||||
void addSettingsForModuleToExporter (ProjectExporter&, ProjectSaver&) const;
|
void addSettingsForModuleToExporter (ProjectExporter&, ProjectSaver&) const;
|
||||||
|
|
@ -61,7 +61,7 @@ public:
|
||||||
build_tools::ProjectType::Target::Type forTarget =
|
build_tools::ProjectType::Target::Type forTarget =
|
||||||
build_tools::ProjectType::Target::unspecified) const;
|
build_tools::ProjectType::Target::unspecified) const;
|
||||||
|
|
||||||
ModuleDescription moduleInfo;
|
ModuleDescription moduleDescription;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addSearchPathsToExporter (ProjectExporter&) const;
|
void addSearchPathsToExporter (ProjectExporter&) const;
|
||||||
|
|
|
||||||
|
|
@ -1696,6 +1696,9 @@ public:
|
||||||
StringArray linkerFlags, librarySearchPaths;
|
StringArray linkerFlags, librarySearchPaths;
|
||||||
getLinkerSettings (config, linkerFlags, librarySearchPaths);
|
getLinkerSettings (config, linkerFlags, librarySearchPaths);
|
||||||
|
|
||||||
|
for (const auto& weakFramework : owner.xcodeWeakFrameworks)
|
||||||
|
linkerFlags.add ("-weak_framework " + weakFramework);
|
||||||
|
|
||||||
if (linkerFlags.size() > 0)
|
if (linkerFlags.size() > 0)
|
||||||
s.set ("OTHER_LDFLAGS", linkerFlags.joinIntoString (" ").quoted());
|
s.set ("OTHER_LDFLAGS", linkerFlags.joinIntoString (" ").quoted());
|
||||||
|
|
||||||
|
|
@ -2054,6 +2057,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable StringArray xcodeFrameworks;
|
mutable StringArray xcodeFrameworks;
|
||||||
|
mutable StringArray xcodeWeakFrameworks;
|
||||||
StringArray xcodeLibs;
|
StringArray xcodeLibs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue