Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 066e261

Browse files
author
Monte Goulding
authored
Merge pull request #1882 from livecode/bugfix-assembly_support
[[ ModuleAssemblies ]] Fix extension functionality for multi-module assemblies
2 parents 76d97e3 + b597e48 commit 066e261

3 files changed

Lines changed: 122 additions & 55 deletions

File tree

Toolset/libraries/revidedeveloperextensionlibrary.livecodescript

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -162,40 +162,36 @@ function revIDEDeveloperExtensions
162162
return tExtensionDetailsA
163163
end revIDEDeveloperExtensions
164164

165-
private command __revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, @rFile, @rType
166-
local tExtFile, tType
167-
revIDEExtensionFetchSourceFromFolder pFolder, tExtFile, tType
165+
private command __revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, @rFile, @rSupportFiles, @rType
166+
local tMainFile, tType, tSupportFiles
167+
revIDEExtensionFetchSourceFromFolder pFolder, tMainFile, tSupportFiles, tType
168168

169-
local tNumExtensions
170-
put the number of lines in tExtFile into tNumExtensions
171-
172-
# If there are multiple lcb files in one folder, it's an error.
173-
if tNumExtensions > 1 then
174-
put replaceText(tExtFile, return, ",") into tExtFile
175-
__revIDEDeveloperExtensionSendError "multiple lcb files in folder" && pFolder & ":" && tExtFile
176-
return empty
169+
if the result is not empty then
170+
__revIDEDeveloperExtensionSendError the result
177171
end if
178172

179-
put tExtFile into rFile
173+
put tMainFile into rFile
174+
put tSupportFiles into rSupportFiles
180175
put tType into rType
181176
end __revIDEDeveloperExtensionFetchExtensionSourceInFolder
182177

183178
function revIDEDeveloperExtensionNoCompile pFolder
184-
local tFile, tType
185-
__revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, tFile, tType
179+
local tFile, tType, tSupportFiles
180+
__revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, tFile, tSupportFiles, tType
186181

187182
if tFile is empty then
188183
return empty
189184
end if
190185

191186
if tType is "lcs" then
192-
return __revIDEDeveloperExtensionDetailsFromFile(pFolder, tFile, tType)
187+
return __revIDEDeveloperExtensionDetailsFromFile(pFolder, tFile, tSupportFiles, tType)
193188
end if
194189

195190
local tDataA
196191
revIDEExtensionMetadata pFolder, tFile, tType, tDataA
197192
if the result is not empty then
198193
put tFile into tDataA["file"]
194+
put tSupportFiles into tDataA["support_files"]
199195
end if
200196
return tDataA
201197
end revIDEDeveloperExtensionNoCompile
@@ -217,14 +213,14 @@ command revIDEDeveloperExtensionsActiveFolders pFolders
217213
end revIDEDeveloperExtensionsActiveFolders
218214

219215
function revIDEDeveloperExtension pFolder
220-
local tFile, tType
221-
__revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, tFile, tType
216+
local tFile, tType, tSupportFiles
217+
__revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, tFile, tSupportFiles, tType
222218

223219
if tFile is empty then
224220
return empty
225221
end if
226222

227-
return __revIDEDeveloperExtensionDetailsFromFile(pFolder, tFile, tType)
223+
return __revIDEDeveloperExtensionDetailsFromFile(pFolder, tFile, tSupportFiles, tType)
228224
end revIDEDeveloperExtension
229225

230226
private function __revIDEDeveloperExtensionFetchFolderDetails pFolder, pFile
@@ -360,11 +356,12 @@ private function __revIDEDeveloperExtensionListResourcesRecursive pFolder, pPref
360356
return tResources
361357
end __revIDEDeveloperExtensionListResourcesRecursive
362358

363-
private function __revIDEDeveloperExtensionDetailsFromFile pFolder, pFile, pType
359+
private function __revIDEDeveloperExtensionDetailsFromFile pFolder, pFile, pSupportFiles, pType
364360
local tDetailsA
365361
put __revIDEDeveloperExtensionFetchFolderDetails(pFolder, pFile) into tDetailsA
366362

367-
put pFile into tDetailsA["file"]
363+
put pFile into tDetailsA["file"]
364+
put pSupportFiles into tDetailsA["support_files"]
368365
if pType is "lcb" then
369366
if not __revIDEDeveloperExtensionShouldRecompile(pFolder, pFile) then
370367

@@ -380,7 +377,7 @@ private function __revIDEDeveloperExtensionDetailsFromFile pFolder, pFile, pType
380377
else
381378
# The compiled module or manifest is not up to date, so compile.
382379
__revIDEDeveloperExtensionLog "Compiling module" && pFolder & slash & pFile
383-
__revIDEDeveloperCompileModule pFolder & slash & pFile, pFolder
380+
__revIDEDeveloperCompileModule pFolder & slash & pFile, pSupportFiles, pFolder
384381
if the result is not empty then
385382
# This may be better as a warning, and try to parse info direct from the file.
386383
__revIDEDeveloperExtensionSendError the result
@@ -681,8 +678,8 @@ private command __revIDEDeveloperExtensionEditLCBScript pFile
681678
end __revIDEDeveloperExtensionEditLCBScript
682679

683680
on revIDEDeveloperExtensionOpen pFolder
684-
local tFile, tType
685-
__revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, tFile, tType
681+
local tFile, tType, tSupportFiles
682+
__revIDEDeveloperExtensionFetchExtensionSourceInFolder pFolder, tFile, tSupportFiles, tType
686683
if tFile is empty then
687684
exit revIDEDeveloperExtensionOpen
688685
end if
@@ -737,8 +734,8 @@ private function __fetchMetadatum pXmlId, pKey
737734
return textDecode(revXMLNodeContents(pXmlId, tNode), "utf-8")
738735
end __fetchMetadatum
739736

740-
private command __revIDEDeveloperCompileModule pFile, pTargetFolder
741-
revIDEExtensionCompile pFile, pTargetFolder
737+
private command __revIDEDeveloperCompileModule pFile, pSupportFiles, pTargetFolder
738+
revIDEExtensionCompile pFile, pSupportFiles, pTargetFolder
742739

743740
if the result is not empty then
744741
__revIDEDeveloperCompilationError the result
@@ -892,9 +889,12 @@ private command __revIDEDeveloperExtensionBuildPackage pFolder, pTargetFolder, @
892889
put empty into tEditors
893890
end if
894891

892+
local tSupportFiles
893+
put tDetailsA["support_files"] into tSupportFiles
894+
895895
if tError is empty then
896896
put __revIDEDeveloperExtensionAddSpecifiedFilesToPackage(\
897-
tFullPath, pFolder, tArchive, pFolder & slash & "module.lcm", \
897+
tFullPath, tSupportFiles, pFolder, tArchive, pFolder & slash & "module.lcm", \
898898
tIcon, tRetinaIcon, tGuide, tDocs, tResources, tCode, \
899899
tSamples, tInterfaceFile, tDefaultScript, tEditors) \
900900
into tError
@@ -918,10 +918,10 @@ private command __revIDEDeveloperExtensionBuildPackage pFolder, pTargetFolder, @
918918
end __revIDEDeveloperExtensionBuildPackage
919919

920920
private function __revIDEDeveloperExtensionAddSpecifiedFilesToPackage \
921-
pSource, pFolder, pArchive, pModule, pIcon, pRetinaIcon, pGuide, \
922-
pDocs, pResourcesFolder, pCodeFolder, pSamplesFolder, \
923-
pInterfaceFile, pDefaultScript, pEditors
924-
921+
pSource, pSupportFiles, pFolder, pArchive, pModule, pIcon, \
922+
pRetinaIcon, pGuide, pDocs, pResourcesFolder, pCodeFolder, \
923+
pSamplesFolder, pInterfaceFile, pDefaultScript, pEditors
924+
925925
local tError
926926

927927
set the itemdelimiter to slash
@@ -932,6 +932,16 @@ private function __revIDEDeveloperExtensionAddSpecifiedFilesToPackage \
932932
put "couldn't add source" into tError
933933
end if
934934

935+
# Add support files into package
936+
repeat for each line tSupport in pSupportFiles
937+
put pFolder & slash & tSupport into tSupport
938+
revZipAddItemWithFile pArchive, item -1 of tSupport, tSupport
939+
940+
if the result begins with "ziperr" then
941+
put "couldn't add support file" && tSupport into tError
942+
end if
943+
end repeat
944+
935945
# Add module into package
936946
revZipAddItemWithFile pArchive, "module.lcm", pModule
937947

@@ -951,10 +961,10 @@ private function __revIDEDeveloperExtensionAddSpecifiedFilesToPackage \
951961
# Add user guide
952962
if tError is empty then
953963
// AL-2015-03-03: [[ Bug 14781 ]] If there is no guide, warn and don't try to add a file
954-
if pGuide is empty then
955-
__revIDEDeveloperExtensionSendWarning "no user guide found"
956-
else
957-
revZipAddItemWithFile pArchive, "docs/guide/guide.md", pGuide
964+
if pGuide is empty then
965+
__revIDEDeveloperExtensionSendWarning "no user guide found"
966+
else
967+
revZipAddItemWithFile pArchive, "docs/guide/guide.md", pGuide
958968
end if
959969
if the result begins with "ziperr" then
960970
put "couldn't add guide" into tError

Toolset/libraries/revideextensionlibrary.livecodescript

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -908,41 +908,72 @@ function revIDEExtensionsOrderByDependency pExtensions
908908
return __dependencyOrder(tDependencies, pExtensions)
909909
end revIDEExtensionsOrderByDependency
910910

911-
command revIDEExtensionFetchSourceFromFolder pFolder, @rSource, @rType
911+
private function __RegexPatternForSource pType
912+
switch pType
913+
case "lcb"
914+
return "^.*\.lcb$"
915+
break
916+
case "lcs"
917+
return "^.*\.livecode(script)?$"
918+
break
919+
end switch
920+
end __RegexPatternForSource
921+
922+
command revIDEExtensionFetchSourceFromFolder pFolder, @rSource, @rSupportFiles, @rType
912923
local tFiles
913924
put files(pFolder) into tFiles
914925

915-
local tExtFile, tType
916-
filter tFiles with "*.lcb" into tExtFile
926+
local tExtFiles, tType
927+
filter tFiles with regex pattern \
928+
__RegexPatternForSource("lcb") into tExtFiles
917929
if there is a file (pFolder & slash & "module.lcm") \
918-
or tExtFile is not empty then
930+
or tExtFiles is not empty then
919931
put "lcb" into tType
920932
end if
933+
921934
if tType is empty then
922-
filter tFiles with regex pattern ".*\.livecode(script)?$" into tExtFile
923-
if tExtFile is not empty then
935+
filter tFiles with regex pattern \
936+
__RegexPatternForSource("lcs") into tExtFiles
937+
if tExtFiles is not empty then
924938
put "lcs" into tType
925939
end if
926940
end if
927941

942+
-- Try and separate main source from support
943+
local tFoundCount, tSupport, tMainFile
944+
put the number of lines in tExtFiles into tFoundCount
945+
if tFoundCount > 1 then
946+
set the itemdelimiter to "."
947+
repeat for each line tTry in tExtFiles
948+
filter tExtFiles with item 1 to -2 of tTry & "-*" into tSupport
949+
if the number of lines in tSupport is tFoundCount - 1 then
950+
put tTry into tMainFile
951+
exit repeat
952+
end if
953+
put empty into tSupport
954+
end repeat
955+
if tSupport is empty then
956+
return "Invalid extension folder" && pFolder & return & \
957+
"Must have one main module, with all support modules named" && \
958+
"<main-name>-<support-name>."
959+
end if
960+
else
961+
put tExtFiles into tMainFile
962+
end if
963+
928964
if tType is empty then
929965
put "none" into tType
930966
end if
931967

932-
put tExtFile into rSource
968+
put tMainFile into rSource
969+
put tSupport into rSupportFiles
933970
put tType into rType
971+
return empty
934972
end revIDEExtensionFetchSourceFromFolder
935973

936974
private command __FindExtensionsInFolderRecursive pFolder, pIsUserFolder, @xDataA
937-
local tExtSource, tArray, tFiles, tExtFile, tType
938-
revIDEExtensionFetchSourceFromFolder pFolder, tExtFile, tType
939-
940-
local tNumExtensions
941-
put the number of lines in tExtFile into tNumExtensions
942-
if tNumExtensions > 1 then
943-
get __revIDEError("Invalid extension folder" && pFolder & ": require exactly one extension per folder")
944-
exit __FindExtensionsInFolderRecursive
945-
end if
975+
local tExtSource, tArray, tFiles, tMainSource, tSupportFiles, tType
976+
revIDEExtensionFetchSourceFromFolder pFolder, tMainSource, tSupportFiles, tType
946977

947978
-- If we found no extensions, recurse
948979
if tType is "none" then
@@ -955,12 +986,13 @@ private command __FindExtensionsInFolderRecursive pFolder, pIsUserFolder, @xData
955986
end if
956987

957988
if tType is "lcb" then
958-
put __fetchModuleData(pFolder, tExtFile) into tArray
989+
put __fetchModuleData(pFolder, tMainSource) into tArray
959990
else
960-
put __fetchScriptLibraryData(pFolder, tExtFile) into tArray
991+
put __fetchScriptLibraryData(pFolder, tMainSource) into tArray
961992
end if
962993

963-
put tExtFile into tArray["source_file"]
994+
put tMainSource into tArray["source_file"]
995+
put tSupportFiles into tArray["support_files"]
964996
put tType into tArray["source_type"]
965997
put not pIsUserFolder into tArray["ide"]
966998

@@ -1201,6 +1233,8 @@ private command __revIDELCBExtensionLoad pID, pFolder, pVersion, pStatus, \
12011233
__extensionPropertySet tCacheIndex, "install_path", pFolder
12021234
end if
12031235

1236+
local tSupportFiles
1237+
put pAdditionalInfoA["support_files"] into tSupportFiles
12041238
local tLoadOnStartup
12051239
if pError is empty then
12061240
put revIDEExtensionGetLoadOnStartup(pID) into tLoadOnStartup
@@ -1210,7 +1244,7 @@ private command __revIDELCBExtensionLoad pID, pFolder, pVersion, pStatus, \
12101244
-- If we have an error loading, try to recompile the extension
12111245
if pError is not empty then
12121246
if not pIsIDEExtension and pSourceFile is not empty then
1213-
revIDEExtensionCompile pFolder & slash & pSourceFile, pFolder
1247+
revIDEExtensionCompile pFolder & slash & pSourceFile, tSupportFiles, pFolder
12141248
if the result is empty then
12151249
local tNewError
12161250
__LoadExtension tCacheIndex, "lcb", pSourceFile, pFolder, pStatus, tNewError
@@ -1228,6 +1262,7 @@ private command __revIDELCBExtensionLoad pID, pFolder, pVersion, pStatus, \
12281262
__extensionPropertySet tCacheIndex, "ide", pIsIDEExtension
12291263
__extensionPropertySet tCacheIndex, "source_file", pSourceFile
12301264
__extensionPropertySet tCacheIndex, "source_type", "lcb"
1265+
__extensionPropertySet tCacheIndex, "support_files", tSupportFiles
12311266

12321267
# Check for sample stacks
12331268
__extensionPropertySet tCacheIndex, "samples", __extensionSampleStacks(pID,pFolder)
@@ -1337,6 +1372,7 @@ private command __revIDELCSExtensionLoad pFullPath, pFolder, pVersion, pStatus,
13371372
__extensionPropertySet tCacheIndex, "source_type", "lcs"
13381373
__extensionPropertySet tCacheIndex, "type", "library"
13391374
__extensionPropertySet tCacheIndex, "uservisible", true
1375+
__extensionPropertySet tCacheIndex, "support_files", pAdditionalInfoA["support_files"]
13401376

13411377
# Store the extension's property metadata
13421378
-- revIDEExtensionSetInfo pID
@@ -1598,7 +1634,7 @@ private function shellFormat pArg, pSwitch
15981634
return tOutput & quote & pArg & quote & " "
15991635
end shellFormat
16001636

1601-
command revIDEExtensionCompile pFile, pTargetFolder
1637+
command revIDEExtensionCompile pFile, pSupportFiles, pTargetFolder
16021638
# The manifest is currently always generated from the source
16031639
if there is a file (pTargetFolder & slash & "manifest.xml") then
16041640
delete file (pTargetFolder & slash & "manifest.xml")
@@ -1623,6 +1659,11 @@ command revIDEExtensionCompile pFile, pTargetFolder
16231659
# The output
16241660
put shellFormat(pTargetFolder & slash & "module.lcm", "output") after tShellCommand
16251661

1662+
# Support files must be dependency-ordered
1663+
repeat for each line tSupport in revIDEExtensionsOrderByDependency(pSupportFiles)
1664+
put shellFormat(pTargetFolder & slash &tSupport) after tShellCommand
1665+
end repeat
1666+
16261667
# The target .lcb file
16271668
put shellFormat(pFile) after tShellCommand
16281669

notes/bugfix-20862.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Fix multi-module assembly support
2+
The extension builder now supports multi-module assemblies properly.
3+
An extension folder can contain a main module, eg main.lcb, and any
4+
number of support modules, named <main name>-<suffix>.lcb, which are
5+
then compiled together into one bytecode file.
6+
7+
For example, it is useful when building cross-platform extensions to
8+
put the platform-specific code in a support module, so the extension
9+
folder would contain for example
10+
11+
button.lcb
12+
button-android.lcb
13+
button-ios.lcb
14+
...
15+
etc
16+

0 commit comments

Comments
 (0)