Skip to content

Commit 164babf

Browse files
committed
Merge pull request livecode#3505 from livecodefraser/mac64-standalones
[[64-bit Mac]] Update the standalone builder and engine for slicing 32-/64-bit Universal binaries
2 parents 5ba89ce + d6880c5 commit 164babf

6 files changed

Lines changed: 154 additions & 63 deletions

File tree

engine/src/deploy.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,36 @@ bool MCDeployParameters::InitWithArray(MCExecContext &ctxt, MCArrayRef p_array)
322322
return false;
323323
MCValueAssign(modules, t_temp_array);
324324
MCValueRelease(t_temp_array);
325+
326+
MCAutoStringRef t_architectures_string;
327+
if (!ctxt.CopyOptElementAsString(p_array, MCNAME("architectures"), false, &t_architectures_string))
328+
return false;
329+
if (!MCStringIsEmpty(*t_architectures_string))
330+
{
331+
// Split the string up into items
332+
MCAutoProperListRef t_architectures;
333+
if (!MCStringSplitByDelimiter(*t_architectures_string, MCSTR(","), kMCStringOptionCompareExact, &t_architectures))
334+
return false;
335+
336+
// Process the architectures
337+
MCValueRef t_architecture;
338+
for (uindex_t i = 0; i < MCProperListGetLength(*t_architectures); i++)
339+
{
340+
// Fetch this item and make sure it is a string
341+
t_architecture = MCProperListFetchElementAtIndex(*t_architectures, i);
342+
if (t_architecture == nil || MCValueGetTypeCode(t_architecture) != kMCValueTypeCodeString)
343+
return false;
344+
345+
// Map it to an architecture ID
346+
MCDeployArchitecture t_id;
347+
if (!MCDeployMapArchitectureString((MCStringRef)t_architecture, t_id))
348+
return false;
349+
350+
// Append it to the list of desired architectures
351+
if (!architectures.Push(t_id))
352+
return false;
353+
}
354+
}
325355

326356
return true;
327357
}

engine/src/deploy.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ struct MCDeployParameters
104104

105105
// The list of modules to include.
106106
MCArrayRef modules;
107+
108+
// List of architectures to retain when building universal binaries
109+
MCAutoArray<MCDeployArchitecture> architectures;
107110

108111

109112
MCDeployParameters()

engine/src/deploy_macosx.cpp

Lines changed: 86 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,29 +1130,37 @@ static void relocate_function_starts_command(linkedit_data_command *x, int32_t p
11301130

11311131
////////////////////////////////////////////////////////////////////////////////
11321132

1133-
static bool MCDeployToMacOSXFetchMinOSVersion(const MCDeployParameters& p_params, mach_header& p_header, uint32_t& r_version)
1133+
static MCDeployArchitecture MCDeployMachArchToDeployArchitecture(cpu_type_t p_type, cpu_subtype_t p_subtype)
11341134
{
1135-
// First work out what DeployArchitecture to look for.
11361135
MCDeployArchitecture t_arch;
1137-
if (p_header . cputype == CPU_TYPE_X86)
1136+
if (p_type == CPU_TYPE_X86)
11381137
t_arch = kMCDeployArchitecture_I386;
1139-
else if (p_header . cputype == CPU_TYPE_X86_64)
1138+
else if (p_type == CPU_TYPE_X86_64)
11401139
t_arch = kMCDeployArchitecture_X86_64;
1141-
else if (p_header . cputype == CPU_TYPE_ARM && p_header . cpusubtype == CPU_SUBTYPE_ARM_V6)
1140+
else if (p_type == CPU_TYPE_ARM && p_subtype == CPU_SUBTYPE_ARM_V6)
11421141
t_arch = kMCDeployArchitecture_ARMV6;
1143-
else if (p_header . cputype == CPU_TYPE_ARM && p_header . cpusubtype == CPU_SUBTYPE_ARM_V7)
1142+
else if (p_type == CPU_TYPE_ARM && p_subtype == CPU_SUBTYPE_ARM_V7)
11441143
t_arch = kMCDeployArchitecture_ARMV7;
1145-
else if (p_header . cputype == CPU_TYPE_ARM && p_header . cpusubtype == CPU_SUBTYPE_ARM_V7S)
1144+
else if (p_type == CPU_TYPE_ARM && p_subtype == CPU_SUBTYPE_ARM_V7S)
11461145
t_arch = kMCDeployArchitecture_ARMV7S;
1147-
else if (p_header . cputype == CPU_TYPE_ARM64)
1146+
else if (p_type == CPU_TYPE_ARM64)
11481147
t_arch = kMCDeployArchitecture_ARM64;
1149-
else if (p_header . cputype == CPU_TYPE_POWERPC)
1148+
else if (p_type == CPU_TYPE_POWERPC)
11501149
t_arch = kMCDeployArchitecture_PPC;
1151-
else if (p_header . cputype == CPU_TYPE_POWERPC64)
1150+
else if (p_type == CPU_TYPE_POWERPC64)
11521151
t_arch = kMCDeployArchitecture_PPC64;
11531152
else
11541153
t_arch = kMCDeployArchitecture_Unknown;
11551154

1155+
return t_arch;
1156+
}
1157+
1158+
static bool MCDeployToMacOSXFetchMinOSVersion(const MCDeployParameters& p_params, mach_header& p_header, uint32_t& r_version)
1159+
{
1160+
// First work out what DeployArchitecture to look for.
1161+
MCDeployArchitecture t_arch;
1162+
t_arch = MCDeployMachArchToDeployArchitecture(p_header.cputype, p_header.cpusubtype);
1163+
11561164
// Search for both the architecture in the mach header and for the 'unknown'
11571165
// architecture. If the real arch is found, then we use that version; otherwise
11581166
// if there is an unknown arch then we use that version. If neither are found we
@@ -1850,56 +1858,86 @@ static bool MCDeployToMacOSXFat(const MCDeployParameters& p_params, bool p_embed
18501858
t_output_offset = sizeof(fat_header);
18511859

18521860
// The fat_arch structures follow the fat header directly
1853-
uint32_t t_header_offset;
1854-
t_header_offset = sizeof(fat_header);
1861+
uint32_t t_header_read_offset, t_header_write_offset;
1862+
t_header_read_offset = t_header_write_offset = sizeof(fat_header);
18551863

18561864
// Loop through all the fat headers.
1865+
uint32_t t_slice_count = 0;
18571866
for(uint32_t i = 0; i < t_fat_header . nfat_arch && t_success; i++)
18581867
{
18591868
fat_arch t_fat_arch;
1860-
if (!MCDeployFileReadAt(p_engine, &t_fat_arch, sizeof(fat_arch), t_header_offset))
1869+
if (!MCDeployFileReadAt(p_engine, &t_fat_arch, sizeof(fat_arch), t_header_read_offset))
18611870
t_success = MCDeployThrow(kMCDeployErrorMacOSXBadHeader);
18621871

1863-
uint32_t t_last_output_offset;
1864-
if (t_success)
1865-
{
1872+
// Ensure the header has the appropriate byte order
1873+
if (t_success)
18661874
swap_fat_arch(true, t_fat_arch);
1867-
1868-
// Round the end of the last engine up to the nearest page boundary.
1869-
t_output_offset = (t_output_offset + ((1 << t_fat_arch . align))) & ~((1 << t_fat_arch . align) - 1);
1870-
1871-
// Record the end of the last engine.
1872-
t_last_output_offset = t_output_offset;
1873-
1874-
// Write out this arch's portion.
1875-
if (!p_embedded)
1876-
t_success = MCDeployToMacOSXMain(p_params, false, p_engine, t_fat_arch . offset, t_fat_arch . size, t_output_offset, p_output, p_validate_header_callback);
1877-
#if 0
1878-
else
1879-
t_success = MCDeployToMacOSXEmbedded(p_params, false, p_engine, 0, 0, t_output_offset, p_output);
1880-
#endif
1881-
}
1882-
1883-
if (t_success)
1884-
{
1885-
// Update the fat header.
1886-
t_fat_arch . offset = t_last_output_offset;
1887-
t_fat_arch . size = t_output_offset - t_last_output_offset;
1888-
1889-
// Put it back to network byte order.
1890-
swap_fat_arch(true, t_fat_arch);
1891-
1892-
// Write out the header.
1893-
t_success = MCDeployFileWriteAt(p_output, &t_fat_arch, sizeof(t_fat_arch), t_header_offset);
1894-
}
1875+
1876+
// Is this slice for an architecture we want to keep?
1877+
bool t_want_slice = true;
1878+
if (t_success && p_params.architectures.Size() > 0)
1879+
{
1880+
// Get the architecture for this slice and check whether it is
1881+
// in the list of desired slices or not
1882+
t_want_slice = false;
1883+
MCDeployArchitecture t_arch = MCDeployMachArchToDeployArchitecture(t_fat_arch.cputype, t_fat_arch.cpusubtype);
1884+
for (uindex_t j = 0; j < p_params.architectures.Size(); j++)
1885+
{
1886+
if (p_params.architectures[j] == t_arch)
1887+
{
1888+
t_want_slice = true;
1889+
break;
1890+
}
1891+
}
1892+
}
1893+
1894+
// Do we want to keep this architecture?
1895+
if (t_want_slice)
1896+
{
1897+
uint32_t t_last_output_offset;
1898+
if (t_success)
1899+
{
1900+
// Round the end of the last engine up to the nearest page boundary.
1901+
t_output_offset = (t_output_offset + ((1 << t_fat_arch . align))) & ~((1 << t_fat_arch . align) - 1);
1902+
1903+
// Record the end of the last engine.
1904+
t_last_output_offset = t_output_offset;
1905+
1906+
// Write out this arch's portion.
1907+
if (!p_embedded)
1908+
t_success = MCDeployToMacOSXMain(p_params, false, p_engine, t_fat_arch . offset, t_fat_arch . size, t_output_offset, p_output, p_validate_header_callback);
1909+
#if 0
1910+
else
1911+
t_success = MCDeployToMacOSXEmbedded(p_params, false, p_engine, 0, 0, t_output_offset, p_output);
1912+
#endif
1913+
}
1914+
1915+
if (t_success)
1916+
{
1917+
// Update the fat header.
1918+
t_fat_arch . offset = t_last_output_offset;
1919+
t_fat_arch . size = t_output_offset - t_last_output_offset;
1920+
1921+
// Put it back to network byte order.
1922+
swap_fat_arch(true, t_fat_arch);
1923+
1924+
// Write out the header.
1925+
t_success = MCDeployFileWriteAt(p_output, &t_fat_arch, sizeof(t_fat_arch), t_header_write_offset);
1926+
}
1927+
1928+
// We've written another slice
1929+
t_slice_count++;
1930+
t_header_write_offset += sizeof(fat_arch);
1931+
}
18951932

1896-
t_header_offset += sizeof(fat_arch);
1933+
t_header_read_offset += sizeof(fat_arch);
18971934
}
18981935

18991936
// Final step is to update the fat header.
19001937
if (t_success)
19011938
{
1902-
swap_fat_header(true, t_fat_header);
1939+
t_fat_header.nfat_arch = t_slice_count;
1940+
swap_fat_header(true, t_fat_header);
19031941
t_success = MCDeployFileWriteAt(p_output, &t_fat_header, sizeof(t_fat_header), 0);
19041942
}
19051943
}
@@ -1913,7 +1951,8 @@ static bool MCDeployValidateMacEngine(const MCDeployParameters& p_params, mach_h
19131951
{
19141952
// Check the CPU type is PowerPC or X86
19151953
if (p_header . cputype != CPU_TYPE_POWERPC &&
1916-
p_header . cputype != CPU_TYPE_X86)
1954+
p_header . cputype != CPU_TYPE_X86 &&
1955+
p_header . cputype != CPU_TYPE_X86_64)
19171956
return MCDeployThrow(kMCDeployErrorMacOSXBadCpuType);
19181957

19191958
// Check that Cocoa is one of the libraries linked to

ide-support/revsaveasstandalone.livecodescript

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ local sUserScriptLibraries
5858
-- MW-2013-11-06: [[ LinuxX64 ]] Add Linux x64 to the list of supported platforms.
5959
-- MM-2014-03-21: [[ PPC Support Dropped ]] Remove Mac PPC and Mac Universal from supported platforms.
6060
-- FG-2014-08-19: [[ RPi ]] Add Linux ARMv6-HF to the list of supported platforms
61-
constant kPlatforms = "Windows,MacOSX x86-32,Linux,Linux x64,Linux armv6-hf,Emscripten"
61+
constant kPlatforms = "Windows,MacOSX x86-32,MacOSX x86-64,Linux,Linux x64,Linux armv6-hf,Emscripten"
6262

6363
-- list of info fields for the windows engine
6464
constant kVersionFlds = "Comments,CompanyName,FileDescription,FileVersion,InternalName,LegalCopyright,LegalTrademarks,OriginalFilename,PrivateBuild,ProductName,ProductVersion,SpecialBuild"
@@ -581,6 +581,7 @@ private command revCreateStandalone pStack, pFolder
581581
case "MacOSX"
582582
case "MacOSX PowerPC-32"
583583
case "MacOSX x86-32"
584+
case "MacOSX x86-64"
584585
// SN-2015-07-09: [[ StandaloneDeployment ]] Gypified Standalone-<edition>.app building does not
585586
// allow to create broken applications, so that the executable file in it bears the edition.
586587
local tEdition
@@ -619,7 +620,7 @@ private command revCreateStandalone pStack, pFolder
619620
if tPlatform contains "MacOSX" and the platform is not "macos" or \
620621
tPlatform contains "Linux" and the platform is not "linux" or \
621622
tPlatform is "Windows" and the platform is not "win32" then
622-
put revEnvironmentNonNativeBinariesPath(tPlatform) into tBinariesPath
623+
put revEnvironmentNonNativeBinariesPath(tPlatform) into tBinariesPath
623624
else
624625
put revEnvironmentBinariesPath() into tBinariesPath
625626
end if
@@ -671,6 +672,14 @@ private command revCreateStandalone pStack, pFolder
671672
-- loop over the platforms to build
672673
put 1 into tCount
673674
repeat for each line tPlatform in sPlatformList
675+
-- Architectures
676+
local tArchitectures
677+
if tPlatform contains "MacOSX" then
678+
if sStandaloneSettingsA["MacOSX x86-32"] then put "i386," after tArchitectures
679+
if sStandaloneSettingsA["MacOSX x86-64"] then put "x86-64," after tArchitectures
680+
delete char -1 of tArchitectures
681+
end if
682+
674683
# OK-2007-08-09: Copy the script libraries to the stack on a per-platform basis, overwriting the old group each time.
675684
revCopyScriptLibraries tStackSourceFile[tPlatform], tPlatform
676685

@@ -688,7 +697,7 @@ private command revCreateStandalone pStack, pFolder
688697
put "com.livecode.widget.browser" is among the lines of sStandaloneSettingsA["extensions"] into tLibBrowser
689698
revCopyCEFResources tPlatform, tStandalonePath[tPlatform], tRevBrowser, tLibBrowser
690699

691-
revBuildStandaloneDeploy tPlatform, tStackSourceFile[tPlatform], tEngineSourceFile[tPlatform], tStandalonePath[tPlatform]
700+
revBuildStandaloneDeploy tPlatform, tArchitectures, tStackSourceFile[tPlatform], tEngineSourceFile[tPlatform], tStandalonePath[tPlatform]
692701

693702
add 1 to tCount
694703
end repeat
@@ -827,7 +836,7 @@ end restoreStackToMessagePath
827836

828837

829838
private command revOutputDirectories pFolder
830-
local tPlatform,tDirectory,tPlatforms,tCount
839+
local tPlatform,tDirectory,tPlatforms,tCount,tOSXCount
831840
revStandaloneProgress "Checking directories..."
832841
if there is a folder (pFolder & sStandaloneSettingsA["name"]) then
833842
put 1 into tCount
@@ -838,16 +847,27 @@ private command revOutputDirectories pFolder
838847
put 0 into tPlatforms
839848
repeat for each item tPlatform in kPlatforms
840849
if sStandaloneSettingsA[tPlatform] = true then
841-
add 1 to tPlatforms
850+
if tPlatform contains "MacOSX" then
851+
add 1 to tOSXCount
852+
else
853+
add 1 to tPlatforms
854+
end if
842855
end if
843856
end repeat
857+
if tOSXCount > 0 then add 1 to tPlatforms
844858
repeat for each item tPlatform in kPlatforms
845859
if sStandaloneSettingsA[tPlatform] = true then
846860
if not revDownloadEngine(tPlatform) then
847861
revStandaloneAddWarning "Could not build for " & tPlatform & " because required files are missing."
848862
next repeat
849863
end if
850864

865+
# Skip this platform if we've already done OSX building
866+
if tPlatform contains "MacOSX" then
867+
if tOSXCount is 0 then next repeat
868+
put 0 into tOSXCount -- Reset the count to zero to force other OSX platforms to be ignored
869+
end if
870+
851871
# OK-2010-02-17: Bug 8608 - Deploying stack with trailing whitespace in name fails on Windows
852872
# because the folder created doesn't match the name passed to create folder command.
853873
local tFolderName
@@ -2277,7 +2297,7 @@ end log
22772297
# the cRevStandaloneSettings into sStandaloneSettings
22782298
#####################################################################
22792299

2280-
private command revBuildStandaloneDeploy pPlatform, pStackFilePath, pEnginePath, pStandalonePath
2300+
private command revBuildStandaloneDeploy pPlatform, pArchitectures, pStackFilePath, pEnginePath, pStandalonePath
22812301
-- Make sure things like 'platform' are standard
22822302
local tPlatformDetailsA
22832303
put revStandalonePlatformDetails(pPlatform) into tPlatformDetailsA
@@ -2365,14 +2385,7 @@ private command revBuildStandaloneDeploy pPlatform, pStackFilePath, pEnginePath,
23652385
end repeat
23662386

23672387
if tPlatformDetailsA["platform"] is "MacOSX" then
2368-
-- MW-2013-06-13: [[ CloneAndRun ]] If installed do things in the usual way, otherwise pass
2369-
-- through in 'engine' (so it builds using archs present there).
2370-
if revEnvironmentIsInstalled() then
2371-
-- MM-2014-03-21: [[ PPC Support Dropped ]] We now only pass a single Intel engine path.
2372-
put pEnginePath into tDeployInfo["engine_x86"]
2373-
else
2374-
put pEnginePath into tDeployInfo["engine"]
2375-
end if
2388+
put pEnginePath into tDeployInfo["engine"]
23762389
-- Disabled for now - will enable when its been properly tested
23772390
//if line 1 of pEnginePath is not empty and line 2 of pEnginePath is not empty then
23782391
//put pStandalonePath & ".dat" into tDeployInfo["spill"]
@@ -2381,6 +2394,10 @@ private command revBuildStandaloneDeploy pPlatform, pStackFilePath, pEnginePath,
23812394
put pEnginePath into tDeployInfo["engine"]
23822395
end if
23832396

2397+
if pArchitectures is not empty then
2398+
put pArchitectures into tDeployInfo["architectures"]
2399+
end if
2400+
23842401
-- Set windows-specific info
23852402
if tPlatformDetailsA["platform"] is "Windows" then
23862403
-- Make sure we include the app icon if any
@@ -2568,7 +2585,8 @@ function revRedirectMacOSResourcesIsExecutable pFile
25682585
read from file pFile for 1 int4
25692586
if the result is not "eof" then
25702587
if it is 0xCAFEBABE or it is 0xBEBAFECA or \
2571-
it is 0xFEEDFACE or it is 0xCEFAEDFE then
2588+
it is 0xFEEDFACE or it is 0xCEFAEDFE or \
2589+
it is 0xFEEDFACF or it is 0xCFFAEDFE then
25722590
put true into tIsExecutable
25732591
end if
25742592
end if

ide-support/revsblibrary.livecodescript

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,7 @@ function revEngineCheck pEngine
812812
case "MacOSX"
813813
case "MacOSX PowerPC-32"
814814
case "MacOSX x86-32"
815+
case "MacOSX x86-64"
815816
return there is a directory (tPath & "/Mac OS X/x86-32/Standalone.app")
816817
case "Windows"
817818
if there is a file (tPath & "/Windows/x86-32/Standalone") then

libfoundation/include/foundation-auto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ template<typename T> class MCAutoArray
10351035
return m_ptr;
10361036
}
10371037

1038-
uindex_t Size()
1038+
uindex_t Size() const
10391039
{
10401040
return m_size;
10411041
}

0 commit comments

Comments
 (0)