| @@ -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 | |||||
| # names. On macOS, finds the requested frameworks using `find_library` and | |||||
| # links them. On iOS, links directly with `-framework Name`. | |||||
| # Takes a target, a link visibility, if it should be a weak link, and a variable-length list of | |||||
| # framework names. On macOS, for non-weak links, this finds the requested frameworks using | |||||
| # `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) | |||||
| target_link_libraries("${target}" "${visibility}" "${juce_found_${framework}}") | |||||
| if(JUCE_LINK_FRAMEWORKS_WEAK) | |||||
| 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() << "/" | |||||
| << moduleInfo.getHeader().getFileName() | |||||
| out << "#include <" << moduleDescription.getModuleFolder().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.linuxPackages, moduleInfo.getModuleInfo() ["linuxPackages"].toString()); | |||||
| parseAndAddLibsToList (exporter.linuxLibs, moduleInfo["linuxLibs"].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(); } | |||||
| String getID() const { return moduleInfo.getID(); } | |||||
| String getVendor() const { return moduleInfo.getVendor(); } | |||||
| String getVersion() const { return moduleInfo.getVersion(); } | |||||
| String getName() const { return moduleInfo.getName(); } | |||||
| String getDescription() const { return moduleInfo.getDescription(); } | |||||
| String getLicense() const { return moduleInfo.getLicense(); } | |||||
| String getMinimumCppStandard() const { return moduleInfo.getMinimumCppStandard(); } | |||||
| bool isValid() const { return moduleDescription.isValid(); } | |||||
| String getID() const { return moduleDescription.getID(); } | |||||
| String getVendor() const { return moduleDescription.getVendor(); } | |||||
| String getVersion() const { return moduleDescription.getVersion(); } | |||||
| String getName() const { return moduleDescription.getName(); } | |||||
| String getDescription() const { return moduleDescription.getDescription(); } | |||||
| String getLicense() const { return moduleDescription.getLicense(); } | |||||
| 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: | ||||