godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.38k stars 21.26k forks source link

3.2.2 Linux headless version exports invalid Mac app #39931

Closed firebelley closed 4 years ago

firebelley commented 4 years ago

Godot version:

3.2.2 Linux Headless

OS/device including version:

Ubuntu 18.04 for building, Mac OS Catalina (10.15.5) for running the app

Issue description:

When exporting a Mac build with the Linux headless version of Godot 3.2.2 the result is an .app file that cannot be run.

I'm using my GitHub workflow that runs the Linux headless version of Godot to export projects. After updating the workflow to use Godot 3.2.2, this workflow no longer outputs a valid Mac app. When attempting to run the app on my Mac I receive a dialog that states:

Screen Shot 2020-06-29 at 8 18 42 AM

Exporting the Mac app from the Windows version of Godot 3.2.2 produces an app that can be run without issue.

Steps to reproduce:

  1. Create an empty project
  2. Create a minimal Mac export
  3. Using the Linux Headless version of 3.2.2, export the Mac app from the command line
  4. Attempt to run the app on a Mac, observe the error

Minimal reproduction project:

ActionsTest-master.zip Please note that the standard project is the project directory. You can also try with the mono project in project-mono to see the same result.

If it helps, here is the output app for the standard build: https://drive.google.com/file/d/16aYbNx7ovtIKkqvgd_SAZ7ya-7uo6L93/view?usp=sharing

And here is the output app for the mono build: https://drive.google.com/file/d/1-HJnBxJ3-n8XokI-NBsz0QA3xBncPL7P/view?usp=sharing

This issue originally stated this was a mono-specific issue. After some more troubleshooting it was found that the issue also applies to the standard version.

neikeq commented 4 years ago

Does the Linux headless non-mono version produce a valid Mac app?

bruvzg commented 4 years ago

If it helps, here is the output app: https://drive.google.com/file/d/1-HJnBxJ3-n8XokI-NBsz0QA3xBncPL7P/view?usp=sharing

App is valid and running on macOS 10.15.5 (it's not signed and do trigger GateKeeper warning).

firebelley commented 4 years ago

@neikeq Good call, the headless non-mono version also produces an invalid app for me. That build is here: https://drive.google.com/file/d/16aYbNx7ovtIKkqvgd_SAZ7ya-7uo6L93/view?usp=sharing

I will update the issue to remove references to Mono.

@bruvzg I am also running on Mac OS 10.15.5. Here's a screenshot of what I am experiencing. This is when trying to run the build that I linked in the issue:

Screen Shot 2020-06-29 at 8 18 42 AM

I'm used to seeing the Gatekeeper warning for 3.2.1 and earlier, strange that now it's outright saying it can't be opened.

bruvzg commented 4 years ago

It's related to missing +x flag when extraction ZIP using specific software (Keka do it correctly, but macOS default Archive Utility do not) apparently file flag changes in #39700 and #33447 do not fully work, probably we should another library to export ZIPs.

akien-mga commented 4 years ago

CC @pouleyKetchoupp

pouleyKetchoupp commented 4 years ago

@firebelley What was the last godot version for which this scenario was working?

pouleyKetchoupp commented 4 years ago

Please specifically test on 3.2.2 RC1 if you have a chance, so we'll know if the regression was introduced in #39700

firebelley commented 4 years ago

@pouleyKetchoupp This was working in 3.2.1 stable, meaning that the app was recognized as a valid app. It still couldn't be executed because it was lacking the appropriate executable flags.

I just tested with 3.2.2 RC1 and it produced a valid Mac app. I can run the app without issue. Let me know if you'd like me to share that build.

pouleyKetchoupp commented 4 years ago

Thanks @firebelley! That means this regression is due to my changes in #39700.

I don't really understand why, but it seems the file type flags I've added are invalid when zipping from a linux system then. A possible hotfix might be to set zip flags differently depending on the platform we're exporting from. I'll try and reproduce it in the coming days to see if I can figure it out.

@bruvzg I agree it would be worth checking with a different zip library, although at this point I have no idea if the problems we're encountering are mostly coming from the library itself or some weirdness in macOS archivers :)

follower commented 4 years ago

FYI: Godot 3.2.2 stable/release also outputs broken Mac .zip exports on Mac.

zipinfo -l

Quick data points (exporting the non-mono project from OP) with Godot 3.2.1 on Mac:

$ zipinfo -l exports/from_3_2_1/test_export__from_3_2_1.zip 
Archive:  exports/from_3_2_1/test_export__from_3_2_1.zip   15371335   5
-rw-rw-r--  0.0 fat    27154 b-    11424 defN 10-Mar-20 13:28 Project.app/Contents/Resources/icon.icns
-rw----     0.0 fat     1211 t-      452 defN 10-Mar-20 13:28 Project.app/Contents/Info.plist
-rw-rw-r--  0.0 fat        9 t-        9 defN 10-Mar-20 13:28 Project.app/Contents/PkgInfo
-rw----     0.0 fat 42584980 b- 15337049 defN 10-Mar-20 13:28 Project.app/Contents/MacOS/Project
-rw----     0.0 fat   115216 b-    21649 defN  0-000-80 00:00 Project.app/Contents/Resources/Project.pck
5 files, 42728570 bytes uncompressed, 15370583 bytes compressed:  64.0%

vs with Godot 3.2.2 on Mac:

$ zipinfo -l exports/from_3_2_2/test_export__from_3_2_2.zip 
Archive:  exports/from_3_2_2/test_export__from_3_2_2.zip   15643058   5
?rwsrwsrwt  2.0 unx     1211 tx      452 defN 30-Jul-20 05:27 Project.app/Contents/Info.plist
?rwsrwsrwt  2.0 unx 43059220 bx 15508975 defN 30-Jul-20 05:27 Project.app/Contents/MacOS/Project
?rwsrwsrwt  2.0 unx        9 tx        9 defN 30-Jul-20 05:27 Project.app/Contents/PkgInfo
?rwsrwsrwt  2.0 unx   155421 bx   111223 defN 30-Jul-20 05:27 Project.app/Contents/Resources/icon.icns
?rwsrwsrwt  2.0 unx   115216 bx    21647 defN 30-Jul-20 05:27 Project.app/Contents/Resources/Project.pck
5 files, 43331077 bytes uncompressed, 15642306 bytes compressed:  63.9%

Note: According to man zipinfo (in relation to an example output mentioned):

The second and third fields indicate that the file was zipped under Unix with version 1.9 of zip. Since it comes from Unix, the file permissions at the beginning of the line are printed in Unix format.

and :

The fifth field consists of two characters, either of which may take on several values. The first character may be either t or b, indicating that zip believes the file to be text or binary, respectively; [...]

The second character may also take on four values, depending on whether there is an extended local header and/or an "extra field" associated with the file (fully explained in PKWare's APPNOTE.TXT, [...]). If neither exists, the character will be a hyphen (-); if there is an extended local header but no extra field, l; if the reverse, x; and if both exist, X.

zipinfo -v

In addition, the verbose mode of zipinfo provides this additional information for the (should be) executable file:

$ zipinfo -v exports/from_3_2_1/test_export__from_3_2_1.zip

[...]

Central directory entry #4:
---------------------------

  Project.app/Contents/MacOS/Project

  offset of local header from start of archive:     12074 (00002F2Ah) bytes
  file system or operating system of origin:        MS-DOS, OS/2 or NT FAT
  version of encoding software:                     0.0
  minimum file system compatibility required:       MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:     2.0
  compression method:                               deflated
  compression sub-type (deflation):                 normal
  file security status:                             not encrypted
  extended local header:                            no
  file last modified on (DOS date/time):            2020 Mar 10 13:28:14
  32-bit CRC value (hex):                           35c6abea
  compressed size:                                  15337049 bytes
  uncompressed size:                                42584980 bytes
  length of filename:                               34 characters
  length of extra field:                            0 bytes
  length of file comment:                           0 characters
  disk number on which file begins:                 disk 1
  apparent file type:                               binary
  non-MSDOS external file attributes:               81ED00 hex
  MS-DOS file attributes (00 hex):                  none

[...]

(Note: 0x81ED00 is--according to my quick calculations--correct value for (note: octal--I'm using Python syntax here) 0o0100755 << 16.)

and

$ zipinfo -v exports/from_3_2_2/test_export__from_3_2_2.zip
[...]

Central directory entry #2:
---------------------------

  There are an extra -12 bytes preceding this file.

  Project.app/Contents/MacOS/Project

  offset of local header from start of archive:     513 (00000201h) bytes
  file system or operating system of origin:        Unix
  version of encoding software:                     2.0
  minimum file system compatibility required:       MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:     2.0
  compression method:                               deflated
  compression sub-type (deflation):                 normal
  file security status:                             not encrypted
  extended local header:                            no
  file last modified on (DOS date/time):            2020 Jul 30 05:27:46
  32-bit CRC value (hex):                           6a8db63c
  compressed size:                                  15508975 bytes
  uncompressed size:                                43059220 bytes
  length of filename:                               34 characters
  length of extra field:                            0 bytes
  length of file comment:                           0 characters
  disk number on which file begins:                 disk 1
  apparent file type:                               binary
  Unix file attributes (177777 octal):              ?rwsrwsrwt
  MS-DOS file attributes (FF hex):                  rdo hid sys lab dir arc lnk exe

  There is a local extra field with ID 0x5855 (old Info-ZIP Unix/OS2/NT) and
  12 data bytes (GMT modification/access times and Unix UID/GID).

  There is no file comment.

[...]

So, oddly, it seems that original fat ("file"/disk format, not executable format (Yay, Apple, what's old is new again!)) non-unix variant lead to the correct results. I haven't yet checked what 3.2.1 headless on Linux produces.

follower commented 4 years ago

These are the (.zip for Mac) exported files produced with Godot v3.2.1 & Godot v3.2.2 on Mac:

When the .zip files are expanded via the system archive handler the results (for the executable named Project) are:

$ ls -l exports/from_3_2_1/Project.app/Contents/MacOS/Project 
-rwxr-xr-x  1 user  staff  42584980 10 Mar 14:28 exports/from_3_2_1/Project.app/Contents/MacOS/Project
$ ls -l exports/from_3_2_2/Project.app/Contents/MacOS/Project 
-rw-------  1 user  staff  43059220 30 Jul  2020 exports/from_3_2_2/Project.app/Contents/MacOS/Project

Interestingly, I just noticed the latter says "30 Jul 2020" but here today is actually "30 June 2020",

follower commented 4 years ago

Additionally, with my own project when I first tried to open the exported app via Finder I noticed the following in /var/log/system.log:

Jun 30 03:27:45 hostname com.apple.launchd.peruser.501[289] ([0x0-0x713713].<ProjectName>[87339]): Job failed to exec(3) for weird reason: 13
Jun 30 03:27:45 hostname.local Finder[402]: 8837325: Attempting to SIGCONT to pid #87339 failed, with errno=#3, or the process failed to actually start
Jun 30 03:27:45 hostname.local Dock[400]: no information back from LS about running process LSASN:{hi=0x0;lo=0x713713}
Jun 30 03:27:45 hostname.local Finder[402]: 8837325: Attempting to SIGCONT to pid #87339 failed, with errno=#3, or the process failed to actually start
Jun 30 03:28:15 --- last message repeated 98 times ---

Apparently permissions errors count as "weird reasons" these days: https://superuser.com/questions/478768/running-app-on-macosx-mountain-lion-job-failed-to-exec3-for-weird-reason-13 :D

follower commented 4 years ago

A thought that occurs to me:

So, if the Linux/Windows exports didn't work going on the same code path, where does it differ from what's run on Mac?

follower commented 4 years ago

Ummm, when was the last time (pre-3.2.2) someone verified Mac exports to .zip from Linux didn't work?

Because I just generated 3 exports with Godot v3.2.1 on a Linux machine (which were all identical--matching size, matching md5 and appeared to match at least one .zip I'd generated on the Mac), scp'd them to a Mac and opening one resulted in a correctly permissioned executable within the .app structure and the app ran successfully (when opened via right-click & "Open").

Here's one of the files:

Interestingly, I also generated (via wine on Mac) a .zip export from Godot Windows version and it also worked for me--but didn't seem to match the size (the .pck size is different?)--I'm not 100% sure about this because I wasn't being entirely methodical, so maybe I missed something with the Windows one: :D

bruvzg commented 4 years ago

If it helps, here is the output app: https://drive.google.com/file/d/1-HJnBxJ3-n8XokI-NBsz0QA3xBncPL7P/view?usp=sharing

I have rechecked this ZIP and it seems to have +x on executable when extracting with both Archive Utility and Keka, but result of Archive Utility contains only 0x00 in all files (size is valid)!

bruvzg commented 4 years ago

Also checked it on the current 3.2 head, same effect, files full of 0x00 when extracted with Archive Util, normal when extracting with Keka. Reverting #39700 do fix it and extracted files have correct permissions with both Archive Util and Keka.

follower commented 4 years ago

I used https://ide.kaitai.io/ to view the .zip files with a "structured" look at the content and...


Edit: Add some related links:

follower commented 4 years ago

@pouleyKetchoupp Do you have more details on the "some software" mentioned in "causing the file to lose executable permissions when unzipped with some software" you mentioned in https://github.com/godotengine/godot/pull/39700#issue-437382677?

bruvzg commented 4 years ago

Some extra info:

follower commented 4 years ago

Given the confusion that's resulted from https://github.com/godotengine/godot/issues/527 still being open despite https://github.com/godotengine/godot/pull/33447 & https://github.com/godotengine/godot/issues/527#issuecomment-500594602, would it be good to:

  1. Close #527 (Assuming that pre this regression, Linux+Windows export to Mac did work).
  2. Re-title this issue to be "3.2.2 exports invalid Mac app .zip on all platforms".
  3. Revert #39700 and then close this? (Ideally with a hotfix release?)
  4. Create new dedicated issue(s) for any other outstanding variations on this issue such as that mentioned by @pouleyKetchoupp?

BTW @pouleyKetchoupp during my research I discovered this project which seems to document some of the issues they encountered with Mac + Zip support:

(It was described in https://github.com/sindresorhus/gulp-zip/issues/38#issuecomment-75138908 as "...spent about 6 hours today working with every zip library for node. [It was] The only one that has worked..." )

pouleyKetchoupp commented 4 years ago

It's strange. I'm not getting the same results as you do, and my change is only setting some standard "normal file" flag on all files :/ I agree it makes sense to revert #39700 for now though, and if needed we'll make another fix later.

The next thing I'll do is testing again with the official 3.2.2 release to see if my problem could be specific to my compilation of godot somehow.

Here's my previous test case scenario:

Zip export created on Windows 10 (godot master, compiled with vs 2019) Zip extracted on OSX, version: 10.13.6 (High Sierra)

Before #39700: Doesn't work with default Archive Utility (file not executable) Works when extracted using unzip in command line

After #39700: Works with both Archive Utility & unzip in command line

bruvzg commented 4 years ago

Actually it's just constant size issue, changed it to:

zipfi.external_fa = (uint32_t)(is_executable ? 0100755 : 0100644) << 16L;

(results in following output by zip-info, and is extracted correctly by all apps I have tested):

  Unix file attributes (100755 octal):            -rwxr-xr-x
  MS-DOS file attributes (00 hex):                none

instead of


zipfi.external_fa = (is_executable ? 0100755 : 0100644) << 16L;

(results in following output by zip-info, and have broken files when extracted by Archive Util)

  Unix file attributes (177777 octal):            ?rwsrwsrwt
  MS-DOS file attributes (FF hex):                rdo hid sys lab dir arc lnk exe

or


zipfi.external_fa = (is_executable ? 0755 : 0644) << 16L;

(results in following output by zip-info, and seems to be extracted correctly)

  Unix file attributes (000755 octal):            ?rwxr-xr-x
  MS-DOS file attributes (00 hex):                none

Also, I have checked info-zip source and it's setting attributes as following (result seems to be the same, not sure why it's done it this way):

uint32_t _mode = (is_executable ? 0100755 : 0100644);

zipfi.external_fa = (_mode << 16L) | !(_mode & 0200);
zipfi.internal_fa = 0;
pouleyKetchoupp commented 4 years ago

Good catch! That makes a lot of sense. Bit-wise operators on signed integers are undefined and probably made the result compiler specific.

raffomania commented 3 years ago

Skimming this thread, am I correct to assume that we'll have to wait for 4.0 until headless export to OSX works, and will have to export using the normal editor build in the meantime?

ok-ikaros commented 2 years ago

Bumping this as well, need to know if we'll be able to export to OSX with linux headless

Calinou commented 2 years ago

@raffomania @lelandhwu https://github.com/godotengine/godot/pull/39977 was cherry-picked to 3.2.3, so this should be fixed in Godot 3.2.3 and later. If this is not the case on Godot 3.4.3, please open a new issue with a minimal reproduction project attached (while also attaching the invalid export if possible).