@@ -58,6 +58,120 @@ endfunction()
5858
5959#==============================================================================
6060
61+ function (_yup_module_upstream_has_content module_name module_path output_variable )
62+ set (source_upstream_path "${module_path} /upstream" )
63+ set (build_upstream_path "${CMAKE_BINARY_DIR} /externals/${module_name} /upstream" )
64+
65+ foreach (candidate_path IN ITEMS "${source_upstream_path} " "${build_upstream_path} " )
66+ if (EXISTS "${candidate_path} " )
67+ file (GLOB upstream_items "${candidate_path} /*" )
68+ list (LENGTH upstream_items upstream_items_len)
69+ if (upstream_items_len GREATER 0)
70+ set (${output_variable} ON PARENT_SCOPE)
71+ return ()
72+ endif ()
73+ endif ()
74+ endforeach ()
75+
76+ set (${output_variable} OFF PARENT_SCOPE)
77+ endfunction ()
78+
79+ #==============================================================================
80+
81+ function (_yup_module_get_upstream_path module_name module_path output_variable )
82+ set (source_upstream_path "${module_path} /upstream" )
83+ if (EXISTS "${source_upstream_path} " )
84+ set (${output_variable} "${source_upstream_path} " PARENT_SCOPE)
85+ return ()
86+ endif ()
87+
88+ set (build_upstream_path "${CMAKE_BINARY_DIR} /externals/${module_name} /upstream" )
89+ if (EXISTS "${build_upstream_path} " )
90+ set (${output_variable} "${build_upstream_path} " PARENT_SCOPE)
91+ return ()
92+ endif ()
93+
94+ set (${output_variable} "" PARENT_SCOPE)
95+ endfunction ()
96+
97+ #==============================================================================
98+
99+ function (_yup_module_fetch_upstream module_name module_path module_upstream module_sha256 module_repository module_branch)
100+ if (NOT YUP_FETCH_UPSTREAM_MODULES)
101+ return ()
102+ endif ()
103+
104+ if (module_upstream AND module_repository)
105+ _yup_message (FATAL_ERROR "Module ${module_name} defines both upstream and repository sources" )
106+ endif ()
107+
108+ if (NOT module_upstream AND NOT module_repository)
109+ return ()
110+ endif ()
111+
112+ _yup_module_upstream_has_content ("${module_name} " "${module_path} " upstream_has_content)
113+ if (upstream_has_content)
114+ return ()
115+ endif ()
116+
117+ _yup_message (STATUS "Fetching upstream sources for ${module_name} " )
118+
119+ if (module_upstream)
120+ set (download_dir "${CMAKE_BINARY_DIR} /_yup_upstream_downloads" )
121+ file (MAKE_DIRECTORY "${download_dir} " )
122+ get_filename_component (archive_name "${module_upstream} " NAME )
123+ if ("${archive_name} " STREQUAL "" )
124+ set (archive_name "${module_name} .archive" )
125+ endif ()
126+ set (archive_path "${download_dir} /${archive_name} " )
127+
128+ # SHOW_PROGRESS
129+ if (module_sha256)
130+ file (DOWNLOAD "${module_upstream} " "${archive_path} " EXPECTED_HASH SHA256=${module_sha256} )
131+ else ()
132+ file (DOWNLOAD "${module_upstream} " "${archive_path} " )
133+ endif ()
134+
135+ set (extract_dir "${CMAKE_BINARY_DIR} /_yup_upstream_extract/${module_name} " )
136+ file (REMOVE_RECURSE "${extract_dir} " )
137+ file (MAKE_DIRECTORY "${extract_dir} " )
138+ file (ARCHIVE_EXTRACT INPUT "${archive_path} " DESTINATION "${extract_dir} " )
139+
140+ file (GLOB extracted_entries RELATIVE "${extract_dir} " "${extract_dir} /*" )
141+ list (LENGTH extracted_entries extracted_entries_len)
142+ set (source_dir "${extract_dir} " )
143+ if (extracted_entries_len EQUAL 1)
144+ list (GET extracted_entries 0 single_entry)
145+ if (IS_DIRECTORY "${extract_dir} /${single_entry} " )
146+ set (source_dir "${extract_dir} /${single_entry} " )
147+ endif ()
148+ endif ()
149+
150+ set (upstream_target_dir "${CMAKE_BINARY_DIR} /externals/${module_name} /upstream" )
151+ file (REMOVE_RECURSE "${upstream_target_dir} " )
152+ file (MAKE_DIRECTORY "${upstream_target_dir} " )
153+ file (GLOB extracted_items "${source_dir} /*" )
154+ if (extracted_items)
155+ file (COPY ${extracted_items} DESTINATION "${upstream_target_dir} " )
156+ endif ()
157+ else ()
158+ if (NOT module_branch)
159+ set (module_branch "HEAD" )
160+ endif ()
161+
162+ set (upstream_target_dir "${CMAKE_BINARY_DIR} /externals/${module_name} /upstream" )
163+ FetchContent_Declare(
164+ "${module_name} _upstream"
165+ GIT_REPOSITORY "${module_repository} "
166+ GIT_TAG "${module_branch} "
167+ GIT_SUBMODULES_RECURSE ON
168+ SOURCE_DIR "${upstream_target_dir} " )
169+ FetchContent_Populate ("${module_name} _upstream" )
170+ endif ()
171+ endfunction ()
172+
173+ #==============================================================================
174+
61175function (_yup_module_collect_sources folder output_variable )
62176 set (source_extensions ".c;.cc;.cxx;.cpp;.h;.hh;.hxx;.hpp" )
63177 if (APPLE )
@@ -363,6 +477,14 @@ function (yup_add_module module_path modules_definitions module_group)
363477 _yup_boolean_property ("${value} " module_arc_enabled)
364478 elseif (${key} MATCHES "^needsPython$" )
365479 _yup_boolean_property ("${value} " module_needs_python)
480+ elseif (${key} MATCHES "^upstream$" )
481+ set (module_upstream "${value} " )
482+ elseif (${key} MATCHES "^sha256$" )
483+ set (module_sha256 "${value} " )
484+ elseif (${key} MATCHES "^repository$" )
485+ set (module_repository "${value} " )
486+ elseif (${key} MATCHES "^branch$" )
487+ set (module_branch "${value} " )
366488 endif ()
367489 endforeach ()
368490
@@ -371,6 +493,17 @@ function (yup_add_module module_path modules_definitions module_group)
371493 _yup_set_default (module_needs_python OFF )
372494 _yup_resolve_variable_paths ("${module_searchpaths} " module_searchpaths)
373495
496+ if (module_upstream OR module_repository)
497+ _yup_module_upstream_has_content ("${module_name} " "${module_path} " upstream_has_content)
498+ if (NOT upstream_has_content)
499+ if (YUP_FETCH_UPSTREAM_MODULES)
500+ _yup_module_fetch_upstream ("${module_name} " "${module_path} " "${module_upstream} " "${module_sha256} " "${module_repository} " "${module_branch} " )
501+ else ()
502+ _yup_message (WARNING "Upstream sources for ${module_name} are missing and YUP_FETCH_UPSTREAM_MODULES is OFF" )
503+ endif ()
504+ endif ()
505+ endif ()
506+
374507 # ==== Setup Platform-Specific Configurations
375508 if (YUP_PLATFORM_IOS)
376509 if (module_appleCppStandard)
@@ -513,11 +646,22 @@ function (yup_add_module module_path modules_definitions module_group)
513646 get_filename_component (module_include_path ${module_path} DIRECTORY )
514647 list (APPEND module_include_paths "${module_include_path} " )
515648
649+ if (module_upstream OR module_repository)
650+ _yup_module_get_upstream_path ("${module_name} " "${module_path} " module_upstream_path)
651+ if (module_upstream_path)
652+ list (APPEND module_include_paths "${module_upstream_path} " )
653+ endif ()
654+ endif ()
655+
516656 foreach (searchpath IN LISTS module_searchpaths)
517657 if (EXISTS "${searchpath} " )
518658 list (APPEND module_include_paths "${searchpath} " )
519659 elseif (EXISTS "${module_path} /${searchpath} " )
520660 list (APPEND module_include_paths "${module_path} /${searchpath} " )
661+ elseif (module_upstream_path AND EXISTS "${module_upstream_path} /${searchpath} " )
662+ list (APPEND module_include_paths "${module_upstream_path} /${searchpath} " )
663+ elseif (module_upstream OR module_repository)
664+ list (APPEND module_include_paths "${CMAKE_BINARY_DIR} /externals/${module_name} /upstream/${searchpath} " )
521665 endif ()
522666 endforeach ()
523667
@@ -621,6 +765,7 @@ macro (yup_add_default_modules modules_path)
621765 yup_add_module (${modules_path} /thirdparty/oboe_library "${modules_definitions} " ${thirdparty_group} )
622766 yup_add_module (${modules_path} /thirdparty/pffft_library "${modules_definitions} " ${thirdparty_group} )
623767 yup_add_module (${modules_path} /thirdparty/dr_libs "${modules_definitions} " ${thirdparty_group} )
768+ yup_add_module (${modules_path} /thirdparty/opus_library "${modules_definitions} " ${thirdparty_group} )
624769
625770 # ==== Yup modules
626771 set (modules_group "Modules" )
0 commit comments