From 24b9ce2319b4c983c827564ebfc5aba5270b8261 Mon Sep 17 00:00:00 2001 From: livecodealex Date: Mon, 10 Dec 2018 12:53:23 +0000 Subject: [PATCH 01/10] [[ Win x86_64 ]] Update _internal deploy for 64 bit executables This patch enables building standalones with the Windows 64 bit standalone engine. --- engine/src/deploy.h | 1 + engine/src/deploy_windows.cpp | 334 ++++++++++++++++++++++++++-------- 2 files changed, 264 insertions(+), 71 deletions(-) diff --git a/engine/src/deploy.h b/engine/src/deploy.h index 1e4ce162e47..20e966718d8 100644 --- a/engine/src/deploy.h +++ b/engine/src/deploy.h @@ -427,6 +427,7 @@ enum MCDeployError kMCDeployErrorWindowsBadDocIcon, kMCDeployErrorWindowsBadManifest, kMCDeployErrorWindowsBadSecuritySection, + kMCDeployErrorWindowsUnkownPlatform, kMCDeployErrorLinuxNoHeader, kMCDeployErrorLinuxBadHeaderMagic, diff --git a/engine/src/deploy_windows.cpp b/engine/src/deploy_windows.cpp index 505846ddb14..4647086cc72 100644 --- a/engine/src/deploy_windows.cpp +++ b/engine/src/deploy_windows.cpp @@ -31,6 +31,17 @@ along with LiveCode. If not see . */ #include "deploy.h" +// Define the two platforms for which we build Windows binaries +enum MCWindowsDeployPlatform { + Windows_x64, + Windows_x32 +}; + +constexpr uint32_t kAddressToPEAddress = 60; +constexpr uint32_t kPEAddressSize = 4; +constexpr uint32_t kMagicOffset = 0x18; +constexpr uint16_t kMagicSize = 2; + //////////////////////////////////////////////////////////////////////////////// // // This section contains definitions for the various structures needed to @@ -43,7 +54,8 @@ along with LiveCode. If not see . */ #define FIELD_OFFSET(type, field) ((LONG)(intptr_t)&(((type *)0)->field)) #endif -#if !defined(_WIN32) +// Defining common types for 32 and 64 bit +#if !defined(_WIN32) && !defined(_WIN64) typedef char CHAR; typedef unsigned short WCHAR; @@ -157,65 +169,6 @@ typedef struct _IMAGE_DATA_DIRECTORY { #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 -// -// Optional header format. -// - -typedef struct _IMAGE_OPTIONAL_HEADER { - // - // Standard fields. - // - - WORD Magic; - BYTE MajorLinkerVersion; - BYTE MinorLinkerVersion; - DWORD SizeOfCode; - DWORD SizeOfInitializedData; - DWORD SizeOfUninitializedData; - DWORD AddressOfEntryPoint; - DWORD BaseOfCode; - DWORD BaseOfData; - - // - // NT additional fields. - // - - DWORD ImageBase; - DWORD SectionAlignment; - DWORD FileAlignment; - WORD MajorOperatingSystemVersion; - WORD MinorOperatingSystemVersion; - WORD MajorImageVersion; - WORD MinorImageVersion; - WORD MajorSubsystemVersion; - WORD MinorSubsystemVersion; - DWORD Win32VersionValue; - DWORD SizeOfImage; - DWORD SizeOfHeaders; - DWORD CheckSum; - WORD Subsystem; - WORD DllCharacteristics; - DWORD SizeOfStackReserve; - DWORD SizeOfStackCommit; - DWORD SizeOfHeapReserve; - DWORD SizeOfHeapCommit; - DWORD LoaderFlags; - DWORD NumberOfRvaAndSizes; - IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; - -typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; -typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; -#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC - -typedef struct _IMAGE_NT_HEADERS { - DWORD Signature; - IMAGE_FILE_HEADER FileHeader; - IMAGE_OPTIONAL_HEADER32 OptionalHeader; -} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; - -typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; -typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; // Directory Entries @@ -442,9 +395,155 @@ typedef struct tagVS_FIXEDFILEINFO DWORD dwFileDateMS; /* e.g. 0 */ DWORD dwFileDateLS; /* e.g. 0 */ } VS_FIXEDFILEINFO; +#endif + +#if !defined(_WIN32) +// +// Optional header format. +// +typedef struct _IMAGE_OPTIONAL_HEADER_32 { + // + // Standard fields. + // + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + + // + // NT additional fields. + // + + DWORD ImageBase; // l + DWORD SectionAlignment; // l + DWORD FileAlignment; // l + WORD MajorOperatingSystemVersion; // s + WORD MinorOperatingSystemVersion; // s + WORD MajorImageVersion; // s + WORD MinorImageVersion; // s + WORD MajorSubsystemVersion; // s + WORD MinorSubsystemVersion; // s + DWORD Win32VersionValue; // l + DWORD SizeOfImage; // l + DWORD SizeOfHeaders; // l + DWORD CheckSum; // l + WORD Subsystem; // s + WORD DllCharacteristics; // s + DWORD SizeOfStackReserve; // l + DWORD SizeOfStackCommit; // l + DWORD SizeOfHeapReserve; // l + DWORD SizeOfHeapCommit; // l + DWORD LoaderFlags; // l + DWORD NumberOfRvaAndSizes; // l + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + +// The following section should move to the template args +// in the templated version of MCDeployWindows + +/* +typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; +*/ +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC + + +typedef struct _IMAGE_NT_HEADERS { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + +// The following section should move to the template args +// in the templated version of MCDeployWindows + +/* +typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +*/ #endif // if !defined(_WIN32) +#if !defined(_WIN64) && !defined(_WINNT_) + +typedef uint64_t ULONGLONG; + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER_64 { + // Standard fields + + WORD Magic; // s + BYTE MajorLinkerVersion; // b + BYTE MinorLinkerVersion; // b + DWORD SizeOfCode; // l + DWORD SizeOfInitializedData; // l + DWORD SizeOfUninitializedData; // l + DWORD AddressOfEntryPoint; // l + DWORD BaseOfCode; // l + + // NT Fields + + ULONGLONG ImageBase; // q + DWORD SectionAlignment; // l + DWORD FileAlignment; // l + WORD MajorOperatingSystemVersion; // s + WORD MinorOperatingSystemVersion; // s + WORD MajorImageVersion; // s + WORD MinorImageVersion; // s + WORD MajorSubsystemVersion; // s + WORD MinorSubsystemVersion; // s + DWORD Win32VersionValue; // l + DWORD SizeOfImage; // l + DWORD SizeOfHeaders; // l + DWORD CheckSum; // l + WORD Subsystem; // s + WORD DllCharacteristics; // s + ULONGLONG SizeOfStackReserve; // q + ULONGLONG SizeOfStackCommit; // q + ULONGLONG SizeOfHeapReserve; // q + ULONGLONG SizeOfHeapCommit; // q + DWORD LoaderFlags; // l + DWORD NumberOfRvaAndSizes; // l + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + + // sbbl lll l q ll ss ss ss l l l l s s q q q q l l +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +// The following section should move to the template args +// in the templated version of MCDeployWindows + +/* +typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; +*/ +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC + + +typedef struct _IMAGE_NT_HEADERS_64 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +// The following section should move to the template args +// in the templated version of MCDeployWindows + +/* +typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +*/ + +#endif // if !defined(_WIN64) + // The following structures are for those used in ICO files and in ICON and // GROUP_ICON resources. These (for some reason) do not appear in any of the // windows headers, so we replicate them for all platforms here. @@ -570,10 +669,10 @@ static inline void swap_format(const char *f, void *p, uint32_t s) // wrapping these in __BIG_ENDIAN__ switches, since (hopefully) even the poorest // of optimizers will notice that the functions they are calling are no-ops :o) -static inline void swap_IMAGE_NT_HEADERS(IMAGE_NT_HEADERS& x) +template +static inline void swap_IMAGE_NT_HEADERS(typename DeployPlatformTrait::IMAGE_NT_HEADERS& x) { - swap_format("l sslllss", &x, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)); - swap_format("sbbllllll lllssssssllllssllllll ll ll ll ll ll ll ll ll ll ll ll ll ll ll ll ll", &x . OptionalHeader, x . FileHeader . SizeOfOptionalHeader); + DeployPlatformTrait::swap_IMAGE_NT_HEADERS(x); } static inline void swap_IMAGE_DOS_HEADER(IMAGE_DOS_HEADER& x) @@ -629,6 +728,36 @@ static inline void swap_GRPICONDIRENTRY(GRPICONDIRENTRY& x) // This section contains methods for operating on a Windows PE resource tree. // +struct MCWindowsPE32Traits +{ + typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; + typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; + + typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; + typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; + + static inline void swap_IMAGE_NT_HEADERS(IMAGE_NT_HEADERS& x) + { + swap_format("l sslllss", &x, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)); + swap_format("sbbllllll lllssssssllllssllllll ll ll ll ll ll ll ll ll ll ll ll ll ll ll ll ll", &x.OptionalHeader, x.FileHeader.SizeOfOptionalHeader); + } +}; + +struct MCWindowsPE64Traits +{ + typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; + typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; + + typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; + typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; + + static inline void swap_IMAGE_NT_HEADERS(IMAGE_NT_HEADERS& x) + { + swap_format("l sslllss", &x, FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)); + swap_format("sbblllll qllssssssllllssqqqqll ll ll ll ll ll ll ll ll ll ll ll ll ll ll ll ll", &x.OptionalHeader, x.FileHeader.SizeOfOptionalHeader); + } +}; + struct MCWindowsResources { // The id of the resource @@ -1597,7 +1726,8 @@ static bool MCWindowsResourcesWrite(MCWindowsResources& self, uint32_t p_address // PE, appropriately munge it and write out a new one. // -static bool MCDeployToWindowsReadHeaders(MCDeployFileRef p_file, IMAGE_DOS_HEADER& r_dos_header, IMAGE_NT_HEADERS& r_nt_header, IMAGE_SECTION_HEADER*& r_section_headers) +template +static bool MCDeployToWindowsReadHeaders(MCDeployFileRef p_file, IMAGE_DOS_HEADER& r_dos_header, typename DeployPlatformTrait::IMAGE_NT_HEADERS& r_nt_header, IMAGE_SECTION_HEADER*& r_section_headers) { if (!MCDeployFileRead(p_file, &r_dos_header, sizeof(IMAGE_DOS_HEADER))) return MCDeployThrow(kMCDeployErrorWindowsNoDOSHeader); @@ -1610,15 +1740,15 @@ static bool MCDeployToWindowsReadHeaders(MCDeployFileRef p_file, IMAGE_DOS_HEADE if (!MCDeployFileSeekSet(p_file, r_dos_header . e_lfanew)) return MCDeployThrow(kMCDeployErrorWindowsBadDOSHeader); - if (!MCDeployFileRead(p_file, &r_nt_header, sizeof(IMAGE_NT_HEADERS))) + if (!MCDeployFileRead(p_file, &r_nt_header, sizeof(typename DeployPlatformTrait::IMAGE_NT_HEADERS))) return MCDeployThrow(kMCDeployErrorWindowsNoNTHeader); - swap_IMAGE_NT_HEADERS(r_nt_header); + DeployPlatformTrait::swap_IMAGE_NT_HEADERS(r_nt_header); if (r_nt_header . Signature != IMAGE_NT_SIGNATURE) return MCDeployThrow(kMCDeployErrorWindowsBadNTSignature); - if (!MCDeployFileSeekSet(p_file, r_dos_header . e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + r_nt_header . FileHeader . SizeOfOptionalHeader)) + if (!MCDeployFileSeekSet(p_file, r_dos_header . e_lfanew + FIELD_OFFSET(typename DeployPlatformTrait::IMAGE_NT_HEADERS, OptionalHeader) + r_nt_header . FileHeader . SizeOfOptionalHeader)) return MCDeployThrow(kMCDeployErrorWindowsBadSectionHeaderOffset); r_section_headers = new (nothrow) IMAGE_SECTION_HEADER[r_nt_header . FileHeader . NumberOfSections]; @@ -1653,8 +1783,11 @@ static bool MCDeployToWindowsReadHeaders(MCDeployFileRef p_file, IMAGE_DOS_HEADE // section, and that (as is usual) the '.rsrc' section is at the end of the // executable. // +template Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) { + typedef typename DeployPlatformTrait::IMAGE_NT_HEADERS IMAGE_NT_HEADERS; + bool t_success; t_success = true; @@ -1677,8 +1810,8 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) IMAGE_SECTION_HEADER *t_section_headers; t_section_headers = NULL; if (t_success) - t_success = MCDeployToWindowsReadHeaders(t_engine, t_dos_header, t_nt_header, t_section_headers); - + t_success = MCDeployToWindowsReadHeaders(t_engine, t_dos_header, t_nt_header, t_section_headers); + IMAGE_SECTION_HEADER *t_payload_section, *t_project_section, *t_resource_section; t_payload_section = t_project_section = t_resource_section = nil; @@ -1841,7 +1974,7 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) if (t_success) { t_optional_header_size = MCU_min(sizeof(t_nt_header . OptionalHeader), (uint4)t_nt_header . FileHeader . SizeOfOptionalHeader); - t_optional_header_offset = t_dos_header . e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader); + t_optional_header_offset = t_dos_header . e_lfanew + FIELD_OFFSET(typename DeployPlatformTrait::IMAGE_NT_HEADERS, OptionalHeader); t_section_headers_offset = t_optional_header_offset + t_nt_header . FileHeader . SizeOfOptionalHeader; uint32_t t_payload_section_size, t_payload_section_delta; @@ -1908,7 +2041,7 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) t_nt_header . OptionalHeader . DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] . Size = t_resource_section_size; // Byte swap everything we are about to write out - swap_IMAGE_NT_HEADERS(t_nt_header); + DeployPlatformTrait::swap_IMAGE_NT_HEADERS(t_nt_header); for(uint32_t i = 0; i < t_section_count; i++) swap_IMAGE_SECTION_HEADER(t_section_headers[i]); } @@ -1935,3 +2068,62 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) return t_success ? ES_NORMAL : ES_ERROR; } + +bool MCDeployToWindowsExtractPlatform(MCDeployParameters const &p_params, MCWindowsDeployPlatform &r_platform) +{ + bool t_success; + t_success = true; + + // AB-2018-12-18: [[ Win64 ]] Identify the engine type from the PE header + MCDeployFileRef t_engine; + t_engine = nullptr; + if (t_success && !MCDeployFileOpen(p_params.engine, kMCOpenFileModeRead, t_engine)) + t_success = MCDeployThrow(kMCDeployErrorNoEngine); + + char t_ident[kAddressToPEAddress + kPEAddressSize]; + if (t_success && !MCDeployFileRead(t_engine, t_ident, kAddressToPEAddress + kPEAddressSize)) + t_success = MCDeployThrow(kMCDeployErrorLinuxNoHeader); + + uint32_t *t_header_offset = reinterpret_cast(&t_ident[kAddressToPEAddress]); + /* + The address of the magic is + 1.) The offset of the PE header in th file + 2.) The offset to the magic number : 0x18 + */ + uint32_t t_magic_address = *t_header_offset + kMagicOffset; + char t_magic[kMagicSize]; + + if (t_success && !MCDeployFileReadAt(t_engine, t_magic, kMagicSize, t_magic_address)) + { + t_success = MCDeployThrow(kMCDeployErrorNoEngine); + } + + uint16_t *t_magic_number = reinterpret_cast(t_magic); + + r_platform = *t_magic_number == 0x10b ? MCWindowsDeployPlatform::Windows_x32 : MCWindowsDeployPlatform::Windows_x64; + + return t_success; +} + +Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) +{ + bool t_success = true; + MCWindowsDeployPlatform t_platform; + if (!MCDeployToWindowsExtractPlatform(p_params, t_platform)) + { + t_success = MCDeployThrow(kMCDeployErrorNoEngine); + } + switch(t_platform) + { + case Windows_x32: { + return MCDeployToWindows(p_params); + } + case Windows_x64:{ + return MCDeployToWindows(p_params); + } + default: { + MCDeployThrow(kMCDeployErrorWindowsUnkownPlatform); + return ES_ERROR; + } + } +} From 772991e694926bf9152d565a8cf0d44b0bb7536e Mon Sep 17 00:00:00 2001 From: livecodealex Date: Tue, 11 Dec 2018 16:08:35 +0000 Subject: [PATCH 02/10] [[ Win 64 Standalone ]] Create x64 VS Soln. --- configure.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.bat b/configure.bat index cab2d7d1932..01a589bab79 100644 --- a/configure.bat +++ b/configure.bat @@ -13,7 +13,7 @@ REM When calling configure.bat from the command line, BUILD_EDITION is not defin IF NOT DEFINED BUILD_EDITION SET BUILD_EDITION="community" REM Target architecture currently defaults to 32-bit x86 -IF NOT DEFINED TARGET_ARCH SET TARGET_ARCH=x86 +IF NOT DEFINED TARGET_ARCH SET TARGET_ARCH=x64 REM Make sure TARGET_ARCH is always x86 or x86_64 From 0d59caf8c164fd2838bbfb0d03435cec65d6b023 Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Mon, 29 Apr 2019 20:36:20 +1000 Subject: [PATCH 03/10] [[ Win x86_64 ]] Enable building Windows x86_64 installer This patch adds support to the build tools for building the x86_64 installer for Windows. --- builder/builder_tool.livecodescript | 4 ++- builder/builder_utilities.livecodescript | 18 ++++++++++--- builder/server_builder.livecodescript | 12 +++++---- builder/tools_builder.livecodescript | 33 ++++++++++++++---------- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/builder/builder_tool.livecodescript b/builder/builder_tool.livecodescript index e5b245f71d3..007f932ab1b 100644 --- a/builder/builder_tool.livecodescript +++ b/builder/builder_tool.livecodescript @@ -44,8 +44,10 @@ on startup if it is "linux" then put true into tPlatforms["linux-x86"] put true into tPlatforms["linux-x86_64"] + else if it is "win" then + put true into tPlatforms["win-x86"] + put true into tPlatforms["win-x86_64"] else - if it begins with "win" then get "windows" if it is "mac" then get "macosx" put true into tPlatforms[it] end if diff --git a/builder/builder_utilities.livecodescript b/builder/builder_utilities.livecodescript index 69215f8b3ff..a61b6544f99 100644 --- a/builder/builder_utilities.livecodescript +++ b/builder/builder_utilities.livecodescript @@ -133,7 +133,13 @@ function builderPlatform end if throw "Unknown Linux architecture:" && the processor case "win32" - return "windows" + if the processor is "x86" then + return "win-x86" + end if + if the processor is "x86_64" then + return "win-x86_64" + end if + throw "Unknown Windows architecture:" && the processor case "macos" return "macosx" case "iphone" @@ -153,8 +159,10 @@ command builderFetchEngine pVersion, pPlatform end if if sEngineDir is not empty then switch pPlatform - case "windows" + case "win-x86" return sEngineDir & slash & "win-x86-bin" + case "win-x86_64" + return sEngineDir & slash & "win-x86_64-bin" case "linux-x86" return sEngineDir & slash & "linux-x86-bin" case "linux-x86_64" @@ -183,7 +191,8 @@ command builderFetchEngine pVersion, pPlatform end if local tPlatform switch pPlatform - case "windows" + case "win-x86" + case "win-x86_64" get "windows/release" break case "linux-x86" @@ -453,7 +462,8 @@ function builderInstallerEngine pPlatform put the result into tEngineFolder switch pPlatform - case "windows" + case "win-x86" + case "win-x86_64" return tEngineFolder & slash & "installer.exe" case "linux-x86" return tEngineFolder & slash & "installer" diff --git a/builder/server_builder.livecodescript b/builder/server_builder.livecodescript index 2bc37a1c0e1..5e33b17fe69 100644 --- a/builder/server_builder.livecodescript +++ b/builder/server_builder.livecodescript @@ -36,7 +36,7 @@ command serverBuilderRun pPlatform, pEdition -- Clean up any existing output file delete file tOutputFile - if pPlatform is "windows" then + if pPlatform begins with "win-" then repeat for each word tExternal in "revdb revzip revxml dbsqlite dbmysql dbpostgresql dbodbc" get "server-" & tExternal & ".dll" if there is not a file (tEngineFolder & slash & it) then @@ -61,7 +61,7 @@ command serverBuilderRun pPlatform, pEdition end if local tExeExtension, tOutExeExtension - if pPlatform is "windows" then + if pPlatform begins with "win-" then put ".exe" into tExeExtension put ".exe" into tOutExeExtension --else if pPlatform is "linux" then @@ -73,7 +73,7 @@ command serverBuilderRun pPlatform, pEdition end if local tLibExtension - if pPlatform is "windows" then + if pPlatform begins with "win-" then put ".dll" into tLibExtension else if pPlatform is "macosx" then put ".dylib" into tLibExtension @@ -173,8 +173,10 @@ function getZipFilenameStub pVersion, pPlatform, pEdition replace "." with "_" in pVersion if pPlatform is "macosx" then put "Mac" into pPlatform - else if pPlatform is "windows" then - put "Windows" into pPlatform + else if pPlatform is "win-x86" then + put "Windows-x86" into pPlatform + else if pPlatform is "win-x86_64" then + put "Windows-x86_64" into pPlatform else if pPlatform is "linux-x86" then put "Linux" into pPlatform else if pPlatform is "linux-x86_64" then diff --git a/builder/tools_builder.livecodescript b/builder/tools_builder.livecodescript index 4a6bf468e7e..4732a6f866c 100644 --- a/builder/tools_builder.livecodescript +++ b/builder/tools_builder.livecodescript @@ -15,7 +15,7 @@ command toolsBuilderRun pPlatform, pEdition, pVersion -- If on windows or linux, we can't do anything macosxy due to lack of lipo/strip :o( local tEngineFolders - get "windows linux-x86 linux-x86_64 linux-armv6hf macosx ios android-armeabi-v7a android-arm64-v8a android-x86 android-x86_64 emscripten" + get "win-x86 win-x86_64 linux-x86 linux-x86_64 linux-armv6hf macosx ios android-armeabi-v7a android-arm64-v8a android-x86 android-x86_64 emscripten" repeat for each word tPlatform in it builderFetchEngine pVersion, tPlatform @@ -112,9 +112,6 @@ private command toolsBuilderFilterExternals pFolder, pPlatform end repeat end if - -- remove windows 64 bit builds only required for filemaker - get shell("rm -fv *x86_64.dll") - -- If the directory contains no code any more, remove it put the files & return & the folders into tFiles filter lines of tFiles with regex pattern "^.*\.(so|dylib|bundle|dll|lcext)$" @@ -195,7 +192,8 @@ private command toolsBuilderMakePackage pVersion, pEdition, pPlatform, pEngineFo packageCompilerConfigureSource tPackager, "linux-x86", pEngineFolders["linux-x86"] packageCompilerConfigureSource tPackager, "linux-x86_64", pEngineFolders["linux-x86_64"] packageCompilerConfigureSource tPackager, "linux-armv6-hf", pEngineFolders["linux-armv6hf"] - packageCompilerConfigureSource tPackager, "windows", pEngineFolders["windows"] + packageCompilerConfigureSource tPackager, "win-x86", pEngineFolders["win-x86"] + packageCompilerConfigureSource tPackager, "win-x86_64", pEngineFolders["win-x86_64"] packageCompilerConfigureSource tPackager, "ios", pEngineFolders["ios"] packageCompilerConfigureSource tPackager, "android-armeabi-v7a", pEngineFolders["android-armeabi-v7a"] packageCompilerConfigureSource tPackager, "android-arm64-v8a", pEngineFolders["android-arm64-v8a"] @@ -223,6 +221,8 @@ private command toolsBuilderMakePackage pVersion, pEdition, pPlatform, pEngineFo end if if pPlatform begins with "linux" then packageCompilerConfigureVariable tPackager, "TargetPlatform", "linux" + else if pPlatform begins with "win" then + packageCompilerConfigureVariable tPackager, "TargetPlatform", "windows" else packageCompilerConfigureVariable tPackager, "TargetPlatform", pPlatform end if @@ -231,11 +231,11 @@ private command toolsBuilderMakePackage pVersion, pEdition, pPlatform, pEngineFo packageCompilerConfigureVariable tPackager, "EscapedVersionTag", tVersionEscaped packageCompilerConfigureVariable tPackager, "ProductBranch", char 1 to 3 of pVersion packageCompilerConfigureVariable tPackager, "TargetArchitectures", "i386" - if pPlatform is "linux-x86" then + if pPlatform ends with "-x86" then packageCompilerConfigureVariable tPackager, "TargetArchitecture", "x86" - else if pPlatform is "linux-x86_64" then + else if pPlatform ends with "-x86_64" then packageCompilerConfigureVariable tPackager, "TargetArchitecture", "x86_64" - else if pPlatform is "linux-armv6hf" then + else if pPlatform ends with "-armv6hf" then packageCompilerConfigureVariable tPackager, "TargetArchitecture", "armv6-hf" end if @@ -423,7 +423,8 @@ private command toolsBuilderMakeInstaller pVersion, pEdition, pPlatform, pIdeFol put return & "insert script of stack" && quote & "InstallerUtilities" & quote && "into back" after tParams["startup_script"] switch pPlatform - case "windows" + case "win-x86" + case "win-x86_64" -- Process the manifest appropriately local tManifestFile get windowsManifest() @@ -434,7 +435,7 @@ private command toolsBuilderMakeInstaller pVersion, pEdition, pPlatform, pIdeFol put tManifestFile into tParams["manifest"] -- First we deploy the installer unsigned - put abstractPinFile(builderInstallerEngine("windows")) into tParams["engine"] + put abstractPinFile(builderInstallerEngine(pPlatform)) into tParams["engine"] put tInstallerStackfile into tParams["stackfile"] put pPackageFile into tParams["payload"] put tOutputFileStub & ".unsigned.exe" into tParams["output"] @@ -938,8 +939,10 @@ function getInstallerFilenameStub pVersion, pPlatform, pEdition replace "." with "_" in pVersion if pPlatform is "macosx" then put "Mac" into pPlatform - else if pPlatform is "windows" then - put "Windows" into pPlatform + else if pPlatform is "win-x86" then + put "Windows-x86" into pPlatform + else if pPlatform is "win-x86_64" then + put "Windows-x86_64" into pPlatform else if pPlatform begins with "linux" then put "Linux" into pPlatform end if @@ -956,8 +959,10 @@ function getDmgFilenameStub pVersion, pPlatform, pEdition replace "." with "_" in pVersion if pPlatform is "macosx" then put "Mac" into pPlatform - else if pPlatform is "windows" then - put "Windows" into pPlatform + else if pPlatform is "win-x86" then + put "Windows-x86" into pPlatform + else if pPlatform is "win-x86_64" then + put "Windows-x86_64" into pPlatform else if pPlatform is "linux" or pPlatform is "linux-x64" or pPlatform is "linux-armv6hf" then put "Linux" into pPlatform end if From 66ba523ca716d588a757bb9ceac20d1d55b61e06 Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Mon, 29 Apr 2019 20:40:01 +1000 Subject: [PATCH 04/10] [[ Win x86_64 ]] Update package script for x86_64 Windows installer This patch updates the package script to allow for multiple windows architectures to be built. --- Installer/package.txt | 94 +++++++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/Installer/package.txt b/Installer/package.txt index 0500cf6e3fe..519931b61fe 100644 --- a/Installer/package.txt +++ b/Installer/package.txt @@ -42,6 +42,12 @@ installer LiveCode include Externals with TargetFolder as [[ToolsFolder]]/Runtime/Windows/x86-32 do set TargetPlatform to Windows + set TargetArchitecture to x86 + include Runtime + include Externals + with TargetFolder as [[ToolsFolder]]/Runtime/Windows/x86-64 do + set TargetPlatform to Windows + set TargetArchitecture to x86_64 include Runtime include Externals with TargetFolder as [[ToolsFolder]]/Runtime/Linux/x86-32 do @@ -492,10 +498,10 @@ component Toolchain.MacOSX component Toolchain.Windows into [[ToolsFolder]]/Toolchain place - executable windows:lc-compile.exe as lc-compile.exe - executable windows:lc-run.exe as lc-run.exe - executable windows:lc-compile-ffi-java.exe as lc-compile-ffi-java.exe - rfolder windows:modules + executable win-[[TargetArchitecture]]:lc-compile.exe as lc-compile.exe + executable win-[[TargetArchitecture]]:lc-run.exe as lc-run.exe + executable win-[[TargetArchitecture]]:lc-compile-ffi-java.exe as lc-compile-ffi-java.exe + rfolder win-[[TargetArchitecture]]:modules component Toolchain.Linux into [[ToolsFolder]]/Toolchain place @@ -520,13 +526,13 @@ component Mobile.Linux component Engine.Windows into [[TargetFolder]] place - executable windows:LiveCode[[EditionTagUpper]].exe as [[ProductName]].exe - executable windows:revpdfprinter.dll - executable windows:revsecurity.dll + executable win-[[TargetArchitecture]]:LiveCode[[EditionTagUpper]].exe as [[ProductName]].exe + executable win-[[TargetArchitecture]]:revpdfprinter.dll + executable win-[[TargetArchitecture]]:revsecurity.dll component Mobile.Windows into "[[ToolsFolder]]/Externals" place - executable windows:revandroid.dll + executable win-[[TargetArchitecture]]:revandroid.dll ////////// @@ -571,13 +577,13 @@ component Runtime.Linux component Runtime.Windows into [[TargetFolder]] place - executable windows:standalone[[BaseEditionTagLower]].exe as Standalone - file "windows:w32-manifest-template.xml" - file "windows:w32-manifest-template-dpiaware.xml" - file "windows:w32-manifest-template-trustinfo.xml" + executable win-[[TargetArchitecture]]:standalone[[BaseEditionTagLower]].exe as Standalone + file "win-[[TargetArchitecture]]:w32-manifest-template.xml" + file "win-[[TargetArchitecture]]:w32-manifest-template-dpiaware.xml" + file "win-[[TargetArchitecture]]:w32-manifest-template-trustinfo.xml" into [[TargetFolder]]/Support place - executable windows:revpdfprinter.dll - executable windows:revsecurity.dll + executable win-[[TargetArchitecture]]:revpdfprinter.dll + executable win-[[TargetArchitecture]]:revsecurity.dll into "[[TargetFolder]]/Support/Sample Icons" place file "ide:Resources/Sample Icons/genericapp.ico" file "ide:Resources/Sample Icons/genericdoc.ico" @@ -812,10 +818,10 @@ component Externals.Linux component Externals.Windows into [[TargetFolder]]/Externals place - executable windows:revspeech.dll - executable windows:revxml.dll - executable windows:revbrowser.dll - executable windows:revzip.dll + executable win-[[TargetArchitecture]]:revspeech.dll + executable win-[[TargetArchitecture]]:revxml.dll + executable win-[[TargetArchitecture]]:revbrowser.dll + executable win-[[TargetArchitecture]]:revzip.dll declare external "Speech" using revspeech.dll declare external "XML" using revxml.dll declare external "Browser" using revbrowser.dll @@ -856,26 +862,26 @@ component Externals.CEF.Linux component Externals.CEF.Windows into [[TargetFolder]]/Externals/CEF place - executable windows:libbrowser-cefprocess.exe - executable windows:revbrowser-cefprocess.exe - executable windows:Externals/CEF/libcef.dll - executable windows:Externals/CEF/d3dcompiler_43.dll - executable windows:Externals/CEF/d3dcompiler_47.dll - executable windows:Externals/CEF/libEGL.dll - executable windows:Externals/CEF/libGLESv2.dll - executable windows:Externals/CEF/chrome_elf.dll - rfolder windows:Externals/CEF/locales - file windows:Externals/CEF/cef.pak - file windows:Externals/CEF/cef_100_percent.pak - file windows:Externals/CEF/cef_200_percent.pak - file windows:Externals/CEF/cef_extensions.pak - file windows:Externals/CEF/icudtl.dat - file windows:Externals/CEF/natives_blob.bin - file windows:Externals/CEF/snapshot_blob.bin - file windows:Externals/CEF/v8_context_snapshot.bin + executable win-[[TargetArchitecture]]:libbrowser-cefprocess.exe + executable win-[[TargetArchitecture]]:revbrowser-cefprocess.exe + executable win-[[TargetArchitecture]]:Externals/CEF/libcef.dll + executable win-[[TargetArchitecture]]:Externals/CEF/d3dcompiler_43.dll + executable win-[[TargetArchitecture]]:Externals/CEF/d3dcompiler_47.dll + executable win-[[TargetArchitecture]]:Externals/CEF/libEGL.dll + executable win-[[TargetArchitecture]]:Externals/CEF/libGLESv2.dll + executable win-[[TargetArchitecture]]:Externals/CEF/chrome_elf.dll + rfolder win-[[TargetArchitecture]]:Externals/CEF/locales + file win-[[TargetArchitecture]]:Externals/CEF/cef.pak + file win-[[TargetArchitecture]]:Externals/CEF/cef_100_percent.pak + file win-[[TargetArchitecture]]:Externals/CEF/cef_200_percent.pak + file win-[[TargetArchitecture]]:Externals/CEF/cef_extensions.pak + file win-[[TargetArchitecture]]:Externals/CEF/icudtl.dat + file win-[[TargetArchitecture]]:Externals/CEF/natives_blob.bin + file win-[[TargetArchitecture]]:Externals/CEF/snapshot_blob.bin + file win-[[TargetArchitecture]]:Externals/CEF/v8_context_snapshot.bin into [[TargetFolder]]/Externals/CEF/swiftshader place - executable windows:Externals/CEF/swiftshader/libEGL.dll - executable windows:Externals/CEF/swiftshader/libGLESv2.dll + executable win-[[TargetArchitecture]]:Externals/CEF/swiftshader/libEGL.dll + executable win-[[TargetArchitecture]]:Externals/CEF/swiftshader/libGLESv2.dll //////////////////////////////////////////////////////////////////////////////// @@ -897,12 +903,12 @@ component Databases.Linux component Databases.Windows into "[[TargetFolder]]/Externals" place - executable windows:revdb.dll + executable win-[[TargetArchitecture]]:revdb.dll into "[[TargetFolder]]/Externals/Database Drivers" place - executable windows:dbmysql.dll - executable windows:dbodbc.dll - executable windows:dbpostgresql.dll - executable windows:dbsqlite.dll + executable win-[[TargetArchitecture]]:dbmysql.dll + executable win-[[TargetArchitecture]]:dbodbc.dll + executable win-[[TargetArchitecture]]:dbpostgresql.dll + executable win-[[TargetArchitecture]]:dbsqlite.dll declare external "Database" using revdb.dll declare dbdriver "MySQL" using dbmysql.dll declare dbdriver "ODBC" using dbodbc.dll @@ -977,7 +983,9 @@ component TimeZone into [[ToolsFolder]]/Extensions/com.livecode.library.timezone place rfolder ios:iphoneos12.1/packaged_extensions/com.livecode.library.timezone/code into [[ToolsFolder]]/Extensions/com.livecode.library.timezone place - rfolder windows:packaged_extensions/com.livecode.library.timezone/code + rfolder win-x86:packaged_extensions/com.livecode.library.timezone/code + into [[ToolsFolder]]/Extensions/com.livecode.library.timezone place + rfolder win-x86_64:packaged_extensions/com.livecode.library.timezone/code into [[ToolsFolder]]/Extensions/com.livecode.library.timezone place rfolder linux-x86_64:packaged_extensions/com.livecode.library.timezone/code into [[ToolsFolder]]/Extensions/com.livecode.library.timezone place From 35f09ba48aed88fac681d5aaec48cf152e5e56df Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Mon, 29 Apr 2019 20:43:24 +1000 Subject: [PATCH 05/10] [[ Win x86_64 ]] Add support to standalone builder for Windows x86_64 This patch amends the standalone builder scripts to allow building of a Windows x86_64 standalone. --- .../revsaveasstandalone.livecodescript | 22 +++++++++++++------ ide-support/revsblibrary.livecodescript | 14 ++++++++++-- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/ide-support/revsaveasstandalone.livecodescript b/ide-support/revsaveasstandalone.livecodescript index 5c98c9f3b30..365d3a7635a 100644 --- a/ide-support/revsaveasstandalone.livecodescript +++ b/ide-support/revsaveasstandalone.livecodescript @@ -436,10 +436,15 @@ private function revStandalonePlatformDetails pTarget put "x86-32" into tDetailsA["architecture"] break case "Windows" - put "Windows/x86-32" into tArchFolder + if pTarget is "Windows" then + put "Windows/x86-32" into tArchFolder + put "x86-32" into tDetailsA["architecture"] + else if pTarget is "Windows x86-64" then + put "Windows/x86-64" into tArchFolder + put "x86-64" into tDetailsA["architecture"] + end if put ".dll" into tDetailsA["loadable_extension"] put "Windows" into tDetailsA["platform"] - put "x86-32" into tDetailsA["architecture"] break case "Linux" if pTarget is "Linux" then @@ -774,13 +779,16 @@ command revSaveAsWindowsStandalone pStack, pRestoreFileName, pFolder, @xStandalo -- Ensure standalone settings script local is reset when building for subsequent targets put tStandaloneSettingsA into sStandaloneSettingsA - local tArch + local tArch, tRuntimeDir if word 2 of tTarget is among the items of "x64,x86-64,x86_64" then put "x86_64" into tArch + put "x86-64" into tRuntimeDir else if word 2 of tTarget is not empty then put word 2 of tTarget into tArch + put word 2 of tTarget into tRuntimeDir else put "x86" into tArch + put "x86-32" into tRuntimeDir end if revStandalonePreBuild pStack, pFolder, "windows", tArch, tStackName, tStackFileList if the result is not empty then @@ -849,7 +857,7 @@ command revSaveAsWindowsStandalone pStack, pRestoreFileName, pFolder, @xStandalo put empty into tManifestData put false into tManifestNeeded - put revEnvironmentRuntimePath() & "/Windows/x86-32/w32-manifest-template.xml" into tManifestPath + put revEnvironmentRuntimePath() & "/Windows/" & tRuntimeDir & "/w32-manifest-template.xml" into tManifestPath if there is not a file tManifestPath then revStandaloneAddWarning "Windows, manifest template not found: " & quote & tManifestPath & quote else @@ -863,7 +871,7 @@ command revSaveAsWindowsStandalone pStack, pRestoreFileName, pFolder, @xStandalo if sStandaloneSettingsA["Windows,uacExecutionLevel"] is not empty and sStandaloneSettingsA["Windows,uacExecutionLevel"] is not "default" then local tManifestTrustInfoPath - put revEnvironmentRuntimePath() & "/Windows/x86-32/w32-manifest-template-trustinfo.xml" into tManifestTrustInfoPath + put revEnvironmentRuntimePath() & "/Windows/" & tRuntimeDir & "/w32-manifest-template-trustinfo.xml" into tManifestTrustInfoPath if there is not a file tManifestTrustInfoPath then revStandaloneAddWarning "Windows, manifest trustinfo template not found: " & quote & tManifestTrustInfoPath & quote @@ -879,7 +887,7 @@ command revSaveAsWindowsStandalone pStack, pRestoreFileName, pFolder, @xStandalo // IM-2014-08-15: [[ Bug 13118 ]] Pull in dpiAware section if set. if sStandaloneSettingsA["Windows,usePixelScaling"] is empty or sStandaloneSettingsA["Windows,usePixelScaling"] is true then local tManifestApplicationPath - put revEnvironmentRuntimePath() & "/Windows/x86-32/w32-manifest-template-dpiaware.xml" into tManifestApplicationPath + put revEnvironmentRuntimePath() & "/Windows/" & tRuntimeDir & "/w32-manifest-template-dpiaware.xml" into tManifestApplicationPath if there is not a file tManifestApplicationPath then revStandaloneAddWarning "Windows, manifest dpiaware template not found: " & quote & tManifestApplicationPath & quote @@ -2202,7 +2210,7 @@ private command revCopyCEFResources pPlatform, pStandalonePath, pCopyRevBrowserR set the itemdel to slash put item 1 to -2 of pStandalonePath into tCurrentLocation switch - case pPlatform = "Windows" + case pPlatform begins with "Windows" put (item 1 to -2 of tExternalPath) & "/CEF" into tCEFResources put tCurrentLocation & slash & "Externals/CEF" into tCEFDest diff --git a/ide-support/revsblibrary.livecodescript b/ide-support/revsblibrary.livecodescript index 0ba97c25714..4931befa250 100644 --- a/ide-support/revsblibrary.livecodescript +++ b/ide-support/revsblibrary.livecodescript @@ -709,7 +709,7 @@ function revFolderNameMakeLegal pName end revFolderNameMakeLegal // List of all desktop target platforms + architecture -constant kDesktopTargets = "Windows,MacOSX x86-32,MacOSX x86-64,Linux,Linux x64,Linux armv6-hf" +constant kDesktopTargets = "Windows,Windows x86-64,MacOSX x86-32,MacOSX x86-64,Linux,Linux x64,Linux armv6-hf" function revSBDesktopTargets return kDesktopTargets end revSBDesktopTargets @@ -724,13 +724,15 @@ function revSBTargetToPlatform pTarget return "MacOSX" else if pTarget begins with "Linux" then return "Linux" + else if pTarget begins with "Windows" then + return "Windows" else return pTarget end if end revSBTargetToPlatform -- item 1 of the architectures should be the default architecture -constant kWindowsArchitectures = "x86-32" +constant kWindowsArchitectures = "x86-32,x86-64" constant kMacOSXArchitectures = "x86-32,x86-64" constant kLinuxArchitectures = "x86-32,x86-64,armv6-hf" constant kAndroidArchitectures = "armv7,arm64,x86,x86_64" @@ -1020,6 +1022,11 @@ function revEngineCheck pEngine return true end if break + case "Windows x86-64" + if there is a file (tPath & "/Windows/x86-64/Standalone") then + return true + end if + break # OK-2007-08-07 : Added linux support case "Linux" if there is a file (tPath & "/Linux/x86-32/Standalone") then @@ -3006,6 +3013,9 @@ function revSBEnginePath pPlatform case "Windows" return tRuntimePath & "/Windows/x86-32/Standalone" break + case "Windows x86-64" + return tRuntimePath & "/Windows/x86-64/Standalone" + break case "Linux" return tRuntimePath & "/Linux/x86-32/Standalone" break From 2e1dc23ff89889976ec720e22fcdaecc9624cabb Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Mon, 29 Apr 2019 20:46:32 +1000 Subject: [PATCH 06/10] [[ Win x86_64 ]] Upload Windows x86_64 Installer and Server This patch adds the Windows x86_64 Installer and Server for each edition to the upload to staging. It also updates the x86 builds with their new names. --- buildbot.mk | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/buildbot.mk b/buildbot.mk index d7c37f8a371..93c1635d0ef 100644 --- a/buildbot.mk +++ b/buildbot.mk @@ -191,11 +191,13 @@ distmac-bundle-business: dist-upload-files.txt sha1sum.txt: set -e; \ find . -maxdepth 1 -name 'LiveCode*-*-Mac.dmg' \ - -o -name 'LiveCode*Installer-*-Windows.exe' \ + -o -name 'LiveCode*Installer-*-Windows-x86.exe' \ + -o -name 'LiveCode*Installer-*-Windows-x86_64.exe' \ -o -name 'LiveCode*Installer-*-Linux.*' \ -o -name 'LiveCode*Server-*-Linux*.zip' \ -o -name 'LiveCode*Server-*-Mac.zip' \ - -o -name 'LiveCode*Server-*-Windows.zip' \ + -o -name 'LiveCode*Server-*-Windows-x86.zip' \ + -o -name 'LiveCode*Server-*-Windows-x86_64.zip' \ -o -name 'LiveCode*Docs-*.zip' \ -o -name '*-bin.tar.xz' \ -o -name '*-bin.tar.bz2' \ From 96ce1abf00b08d96cb6251f6bea0ef6cf5df931d Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Mon, 29 Apr 2019 20:51:58 +1000 Subject: [PATCH 07/10] [[ Bug ]] Remove lcidlc encode_support sources from gyp GYP seems to be choking on the the java source listed in sources in the encode_support target. Removing them resolves the issue and the files were already listed in the target action inputs etc. --- lcidlc/lcidlc.gyp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lcidlc/lcidlc.gyp b/lcidlc/lcidlc.gyp index 986e45e3268..af4cc659f59 100644 --- a/lcidlc/lcidlc.gyp +++ b/lcidlc/lcidlc.gyp @@ -76,12 +76,6 @@ 'target_name': 'encode_support', 'type': 'none', - 'sources': - [ - 'src/Support.java', - 'src/Support.mm', - ], - 'actions': [ { From 107e816bd545d9b95577397fa9b6d08b44333769 Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Tue, 30 Apr 2019 14:01:54 +1000 Subject: [PATCH 08/10] [[ Win x86_64 ]] Add release note --- docs/notes/feature-win64-deployment.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/notes/feature-win64-deployment.md diff --git a/docs/notes/feature-win64-deployment.md b/docs/notes/feature-win64-deployment.md new file mode 100644 index 00000000000..4f7cb282f2a --- /dev/null +++ b/docs/notes/feature-win64-deployment.md @@ -0,0 +1,5 @@ +# Deploy 64-bit Windows standalones + +You can now deploy 64-bit standalones for Windows. The `Standalone Settings` +dialog now has a `Windows x86` and a `Windows x86_64` checkbox allowing you to +choose to build either or both 32-bit and 64-bit executables. From fcd5a440344015b4238832f3947ddc5f3cdebba7 Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Wed, 1 May 2019 12:44:32 +1000 Subject: [PATCH 09/10] [[ Win x86_64 ]] Update _internal sign for 64 bit executables This patch updates the `_internal sign windows` command for 64 bit executables. The patch also updates the deploy command to reuse: - `MCDeployWindowsPEHeaderOffset` which does some basic DOS header checking and extraction of the PE header offset. - `MCDeployWindowsArchitecture` which does some basic NT header checking and determiniation of the executable architecture. --- engine/src/deploy.h | 6 +- engine/src/deploy_sign.cpp | 111 ++++++++++++++++++----------- engine/src/deploy_windows.cpp | 130 ++++++++++++++++++++++++---------- 3 files changed, 164 insertions(+), 83 deletions(-) diff --git a/engine/src/deploy.h b/engine/src/deploy.h index 20e966718d8..76db8486562 100644 --- a/engine/src/deploy.h +++ b/engine/src/deploy.h @@ -427,7 +427,6 @@ enum MCDeployError kMCDeployErrorWindowsBadDocIcon, kMCDeployErrorWindowsBadManifest, kMCDeployErrorWindowsBadSecuritySection, - kMCDeployErrorWindowsUnkownPlatform, kMCDeployErrorLinuxNoHeader, kMCDeployErrorLinuxBadHeaderMagic, @@ -538,4 +537,9 @@ bool MCDeployWritePayload(const MCDeployParameters& p_params, bool p_to_network, //////////////////////////////////////////////////////////////////////////////// +bool MCDeployWindowsPEHeaderOffset(MCDeployFileRef p_file, uint32_t &r_pe_offset); +bool MCDeployWindowsArchitecture(MCDeployFileRef p_file, uint32_t p_pe_offset, MCDeployArchitecture &r_platform); + +//////////////////////////////////////////////////////////////////////////////// + #endif diff --git a/engine/src/deploy_sign.cpp b/engine/src/deploy_sign.cpp index fb5a7103162..d495d1f77d0 100644 --- a/engine/src/deploy_sign.cpp +++ b/engine/src/deploy_sign.cpp @@ -627,51 +627,45 @@ static bool MCDeployBuildSpcIndirectDataContent(BIO *p_hash, SpcIndirectDataCont return t_success; } +constexpr uint32_t kSecurityEntryOffset32 = 152; +constexpr uint32_t kSecurityEntryOffset64 = 168; + // This method checks to see if the input file is a valid Windows EXE (well, as // valid as we need it to be). It then returns the offset to the PE header if // successful. Additionally, we return the offset of the certificate entry, or // the length of the file (if no current cert). -static bool MCDeploySignCheckWindowsExecutable(MCDeployFileRef p_input, uint32_t& r_pe_offset, uint32_t& r_cert_offset) +static bool MCDeploySignCheckWindowsExecutable(MCDeployFileRef p_input, uint32_t& r_pe_offset, uint32_t& r_cert_offset, MCDeployArchitecture &r_architecture) { // First get the length of the input file uint32_t t_length; if (!MCDeployFileMeasure(p_input, t_length)) return false; - // Now check the first two bytes - these should be MZ - char t_buffer[4]; - if (!MCDeployFileReadAt(p_input, t_buffer, 2, 0) || - !MCMemoryEqual(t_buffer, "MZ", 2)) - return MCDeployThrow(kMCDeployErrorWindowsBadDOSSignature); - - // Now read in the offset to the pe header - this resides at - // byte offset 60 (member e_lfanew in IMAGE_DOS_HEADER). uint32_t t_offset; - if (t_length < 64 || - !MCDeployFileReadAt(p_input, &t_offset, 4, 60)) - return MCDeployThrow(kMCDeployErrorWindowsBadDOSHeader); - - // Swap from non-network to host byte order - MCDeployByteSwap32(false, t_offset); - - // Check the NT header is big enough - here 160 is the minimum size of the - // NT header we need. This is: - // 4 byte signature - // 20 byte file header - // 28 byte standard header - // 68 byte optional header - // 40 byte data directory (i.e. up to and including SECURITY entry). - if (t_length < t_offset + 160) - return MCDeployThrow(kMCDeployErrorWindowsNoNTHeader); - - // Now make sure the NT Signature is correct and read in the existing cert - // fields. Note that the offset here is that of the 5th data directory entry - // (4 + 20 + 28 + 64 + 5 * 8). + if (!MCDeployWindowsPEHeaderOffset(p_input, t_offset)) + return false; + + MCDeployArchitecture t_arch; + if (!MCDeployWindowsArchitecture(p_input, t_offset, t_arch)) + return false; + + uint32_t t_security_offset = t_offset; + if (t_arch == kMCDeployArchitecture_I386) + { + t_security_offset += kSecurityEntryOffset32; + } + else + { + t_security_offset += kSecurityEntryOffset64; + } + + // Now read in the existing cert fields. Note that the offset here is + // that of the 5th data directory entry uint32_t t_cert_section[2]; - if (!MCDeployFileReadAt(p_input, t_buffer, 4, t_offset) || - !MCMemoryEqual(t_buffer, "PE\0\0", 4) || - !MCDeployFileReadAt(p_input, t_cert_section, 2 * sizeof(uint32_t), t_offset + 152)) + if (!MCDeployFileReadAt(p_input, t_cert_section, 2 * sizeof(uint32_t), t_security_offset)) + { return MCDeployThrow(kMCDeployErrorWindowsBadNTSignature); + } MCDeployByteSwap32(false, t_cert_section[0]); MCDeployByteSwap32(false, t_cert_section[1]); @@ -687,6 +681,7 @@ static bool MCDeploySignCheckWindowsExecutable(MCDeployFileRef p_input, uint32_t r_cert_offset = t_length; r_pe_offset = t_offset; + r_architecture = t_arch; return true; } @@ -720,7 +715,7 @@ static bool MCDeploySignCopyFileAt(BIO *p_output, MCDeployFileRef p_input, uint3 // This method reconstructs the output executable from the input executable // while computing the hash of the critical parts of the file. -static bool MCDeploySignHashWindowsExecutable(MCDeployFileRef p_input, BIO *p_output, uint32_t p_pe_offset, uint32_t p_cert_offset, BIO*& r_hash) +static bool MCDeploySignHashWindowsExecutable(MCDeployFileRef p_input, BIO *p_output, uint32_t p_pe_offset, uint32_t p_cert_offset, MCDeployArchitecture p_architecture, BIO*& r_hash) { bool t_success; t_success = true; @@ -742,8 +737,9 @@ static bool MCDeploySignHashWindowsExecutable(MCDeployFileRef p_input, BIO *p_ou // the input executable as we go. // The first part of the output file is everything up to the start of the - // 'CheckSum' field of the IMAGE_OPTIONAL_HEADER32 structure. This is at - // offset 88 in said structure. This part is part of the hash. + // 'CheckSum' field of the IMAGE_OPTIONAL_HEADER structure. This is at + // offset 88 in both IMAGE_OPTIONAL_HEADER32 and IMAGE_OPTIONAL_HEADER64. + // This part is part of the hash. if (t_success) t_success = MCDeploySignCopyFileAt(t_hash, p_input, 0, p_pe_offset + 88); @@ -757,20 +753,30 @@ static bool MCDeploySignHashWindowsExecutable(MCDeployFileRef p_input, BIO *p_ou t_success = MCDeployThrowOpenSSL(kMCDeployErrorBadWrite); } + uint32_t t_security_offset = p_pe_offset; + if (p_architecture == kMCDeployArchitecture_I386) + { + t_security_offset += kSecurityEntryOffset32; + } + else + { + t_security_offset += kSecurityEntryOffset64; + } + // Next is the section of the header after the CheckSum field and up to - // the 'Security' data directory entry. This entry is at offset 152. + // the 'Security' data directory entry. if (t_success) - t_success = MCDeploySignCopyFileAt(t_hash, p_input, p_pe_offset + 92, 60); + t_success = MCDeploySignCopyFileAt(t_hash, p_input, p_pe_offset + 92, t_security_offset - (p_pe_offset + 92)); // Now write out the (current) value of the Security data directory entry, // but not into the hash. if (t_success) - t_success = MCDeploySignCopyFileAt(p_output, p_input, p_pe_offset + 152, 8); + t_success = MCDeploySignCopyFileAt(p_output, p_input, t_security_offset, 8); // After the Security data directory, everything up to the cert offset is // hashed. if (t_success) - t_success = MCDeploySignCopyFileAt(t_hash, p_input, p_pe_offset + 160, p_cert_offset - (p_pe_offset + 160)); + t_success = MCDeploySignCopyFileAt(t_hash, p_input, t_security_offset + 8, p_cert_offset - (t_security_offset + 8)); // Finally we round the output up to the nearest 8 bytes. if (t_success && (p_cert_offset % 8 != 0)) @@ -1047,6 +1053,8 @@ static bool MCDeploySignWindowsAddTimeStamp(const MCDeploySignParameters& p_para return t_success; } +static bool s_objects_created = false; + bool MCDeploySignWindows(const MCDeploySignParameters& p_params) { bool t_success; @@ -1094,13 +1102,14 @@ bool MCDeploySignWindows(const MCDeploySignParameters& p_params) // Next we check the input file, and compute the hash, writing out the new // version of the executable as we go. uint32_t t_pe_offset, t_cert_offset; + MCDeployArchitecture t_arch; if (t_success) - t_success = MCDeploySignCheckWindowsExecutable(t_input, t_pe_offset, t_cert_offset); + t_success = MCDeploySignCheckWindowsExecutable(t_input, t_pe_offset, t_cert_offset, t_arch); BIO *t_hash; t_hash = nil; if (t_success) - t_success = MCDeploySignHashWindowsExecutable(t_input, t_output, t_pe_offset, t_cert_offset, t_hash); + t_success = MCDeploySignHashWindowsExecutable(t_input, t_output, t_pe_offset, t_cert_offset, t_arch, t_hash); // Next we create a PKCS#7 object ready for filling with the stuff we need for // Authenticode. @@ -1145,12 +1154,18 @@ bool MCDeploySignWindows(const MCDeploySignParameters& p_params) // The various ASN.1 structures we are going to use require a number of ObjectIDs. // We register them all here, to save having to check the return value of OBJ_txt2obj. - if (t_success) + if (t_success && !s_objects_created) + { if (!OBJ_create(SPC_INDIRECT_DATA_OBJID, SPC_INDIRECT_DATA_OBJID, SPC_INDIRECT_DATA_OBJID) || !OBJ_create(SPC_PE_IMAGE_DATA_OBJID, SPC_PE_IMAGE_DATA_OBJID, SPC_PE_IMAGE_DATA_OBJID) || !OBJ_create(SPC_STATEMENT_TYPE_OBJID, SPC_STATEMENT_TYPE_OBJID, SPC_STATEMENT_TYPE_OBJID) || !OBJ_create(SPC_SP_OPUS_INFO_OBJID, SPC_SP_OPUS_INFO_OBJID, SPC_SP_OPUS_INFO_OBJID)) + { t_success = MCDeployThrowOpenSSL(kMCDeployErrorBadSignature); + } + + s_objects_created = true; + } // Authenticode signatures require a single SignerInfo structure to be present. // To create this we add a signature for the certificate we just located. @@ -1305,6 +1320,16 @@ bool MCDeploySignWindows(const MCDeploySignParameters& p_params) // ... And update the SECURITY table entry in the PE header appropraitely. if (t_success) { + uint32_t t_security_offset = t_pe_offset; + if (t_arch == kMCDeployArchitecture_I386) + { + t_security_offset += kSecurityEntryOffset32; + } + else + { + t_security_offset += kSecurityEntryOffset64; + } + uint32_t t_entry[2]; // First entry is the offset of the cert, making sure it is padded to 8 @@ -1315,7 +1340,7 @@ bool MCDeploySignWindows(const MCDeploySignParameters& p_params) t_entry[1] = 8 + t_signature_size + (t_signature_size % 8 != 0 ? (8 - (t_signature_size % 8)) : 0); MCDeployByteSwapRecord(false, "ll", t_entry, sizeof(t_entry)); - if (BIO_seek(t_output, t_pe_offset + 152) == -1 || + if (BIO_seek(t_output, t_security_offset) == -1 || BIO_write(t_output, t_entry, sizeof(t_entry)) != sizeof(t_entry)) t_success = MCDeployThrowOpenSSL(kMCDeployErrorBadWrite); } diff --git a/engine/src/deploy_windows.cpp b/engine/src/deploy_windows.cpp index 4647086cc72..36bcd6a4ba7 100644 --- a/engine/src/deploy_windows.cpp +++ b/engine/src/deploy_windows.cpp @@ -31,16 +31,11 @@ along with LiveCode. If not see . */ #include "deploy.h" -// Define the two platforms for which we build Windows binaries -enum MCWindowsDeployPlatform { - Windows_x64, - Windows_x32 -}; - constexpr uint32_t kAddressToPEAddress = 60; constexpr uint32_t kPEAddressSize = 4; constexpr uint32_t kMagicOffset = 0x18; -constexpr uint16_t kMagicSize = 2; +constexpr uint16_t kHeaderMagic32 = 0x10b; +constexpr uint16_t kHeaderMagic64 = 0x20b; //////////////////////////////////////////////////////////////////////////////// // @@ -2069,38 +2064,72 @@ Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) return t_success ? ES_NORMAL : ES_ERROR; } -bool MCDeployToWindowsExtractPlatform(MCDeployParameters const &p_params, MCWindowsDeployPlatform &r_platform) +bool MCDeployWindowsPEHeaderOffset(MCDeployFileRef p_file, uint32_t &r_pe_offset) +{ + // Now check the first two bytes - these should be MZ + char t_buffer[4]; + if (!MCDeployFileReadAt(p_file, t_buffer, 2, 0) || + !MCMemoryEqual(t_buffer, "MZ", 2)) + { + return MCDeployThrow(kMCDeployErrorWindowsBadDOSSignature); + } + + // Now read in the offset to the pe header - this resides at + // byte offset 60 (member e_lfanew in IMAGE_DOS_HEADER). + uint32_t t_offset; + if (!MCDeployFileReadAt(p_file, &t_offset, kPEAddressSize, kAddressToPEAddress)) + { + return MCDeployThrow(kMCDeployErrorWindowsBadDOSHeader); + } + + // Swap from non-network to host byte order + MCDeployByteSwap32(false, t_offset); + r_pe_offset = t_offset; + + return true; +} + +// Do some basic validation on the NT header and return the file architecture +bool MCDeployWindowsArchitecture(MCDeployFileRef p_file, uint32_t p_pe_offset, MCDeployArchitecture &r_platform) { bool t_success; t_success = true; - // AB-2018-12-18: [[ Win64 ]] Identify the engine type from the PE header - MCDeployFileRef t_engine; - t_engine = nullptr; - if (t_success && !MCDeployFileOpen(p_params.engine, kMCOpenFileModeRead, t_engine)) - t_success = MCDeployThrow(kMCDeployErrorNoEngine); + uint32_t t_length; + if (!MCDeployFileMeasure(p_file, t_length)) + return false; - char t_ident[kAddressToPEAddress + kPEAddressSize]; - if (t_success && !MCDeployFileRead(t_engine, t_ident, kAddressToPEAddress + kPEAddressSize)) - t_success = MCDeployThrow(kMCDeployErrorLinuxNoHeader); - - uint32_t *t_header_offset = reinterpret_cast(&t_ident[kAddressToPEAddress]); - /* - The address of the magic is - 1.) The offset of the PE header in th file - 2.) The offset to the magic number : 0x18 - */ - uint32_t t_magic_address = *t_header_offset + kMagicOffset; - char t_magic[kMagicSize]; - - if (t_success && !MCDeployFileReadAt(t_engine, t_magic, kMagicSize, t_magic_address)) + // Confirm NT Signature at offset + char t_buffer[4]; + if (t_success && (!MCDeployFileReadAt(p_file, t_buffer, 4, p_pe_offset) || + !MCMemoryEqual(t_buffer, "PE\0\0", 4))) { - t_success = MCDeployThrow(kMCDeployErrorNoEngine); + t_success = MCDeployThrow(kMCDeployErrorWindowsNoNTHeader); } - uint16_t *t_magic_number = reinterpret_cast(t_magic); - - r_platform = *t_magic_number == 0x10b ? MCWindowsDeployPlatform::Windows_x32 : MCWindowsDeployPlatform::Windows_x64; + uint16_t t_magic; + if (t_success && !MCDeployFileReadAt(p_file, &t_magic, sizeof(uint16_t), p_pe_offset + kMagicOffset)) + { + t_success = MCDeployThrow(kMCDeployErrorWindowsNoNTHeader); + } + + if (t_success) + { + swap_uint16(t_magic); + + switch (t_magic) + { + case kHeaderMagic32: + r_platform = kMCDeployArchitecture_I386; + break; + case kHeaderMagic64: + r_platform = kMCDeployArchitecture_X86_64; + break; + default: + t_success = MCDeployThrow(kMCDeployErrorWindowsNoNTHeader); + break; + } + } return t_success; } @@ -2108,22 +2137,45 @@ bool MCDeployToWindowsExtractPlatform(MCDeployParameters const &p_params, MCWind Exec_stat MCDeployToWindows(const MCDeployParameters& p_params) { bool t_success = true; - MCWindowsDeployPlatform t_platform; - if (!MCDeployToWindowsExtractPlatform(p_params, t_platform)) + + MCDeployFileRef t_engine; + t_engine = nullptr; + if (t_success && !MCDeployFileOpen(p_params.engine, kMCOpenFileModeRead, t_engine)) { t_success = MCDeployThrow(kMCDeployErrorNoEngine); } - switch(t_platform) + + uint32_t t_pe_offset; + if (t_success) { - case Windows_x32: { + t_success = MCDeployWindowsPEHeaderOffset(t_engine, t_pe_offset); + } + + MCDeployArchitecture t_arch; + if (t_success) + { + t_success = MCDeployWindowsArchitecture(t_engine, t_pe_offset, t_arch); + } + + if (t_engine != nullptr) + { + MCDeployFileClose(t_engine); + } + + if (t_success) + { + switch (t_arch) + { + case kMCDeployArchitecture_I386: { return MCDeployToWindows(p_params); } - case Windows_x64:{ + case kMCDeployArchitecture_X86_64: { return MCDeployToWindows(p_params); } - default: { - MCDeployThrow(kMCDeployErrorWindowsUnkownPlatform); - return ES_ERROR; + default: + MCUnreachableReturn(ES_ERROR) } } + + return ES_ERROR; } From 78bd9579f2737aa246d42710b3740b41471fa57e Mon Sep 17 00:00:00 2001 From: Monte Goulding Date: Thu, 2 May 2019 14:14:30 +1000 Subject: [PATCH 10/10] [[ Win x86_64 ]] Load 64 bit COMCTL32.dll This patch updates the windows manifest for the installer so that it will load the correct architecture version of COMCTL32.dll. --- builder/windows_manifest.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/windows_manifest.xml b/builder/windows_manifest.xml index 00484d48e0f..e4e9fdc809d 100644 --- a/builder/windows_manifest.xml +++ b/builder/windows_manifest.xml @@ -18,6 +18,6 @@ - +