Building standalone for Windows 10 coming from Mac using a splashscreen

Carl Albrecht's icon

running max7.2.3 on win10

Hi there, (for short instructive version please scroll down!)
let s be honest - being able to compile on mac and windows with essentially the same code is awesome!
It saves a lot of work developing the code, and lets you work on your preferred platform.
But this kind of „advantage“ can absolutely fire back - let me share my story.
So I m a mac user since G3 times - never owned a pc, went straight from good ol Commodore 64 to G3 with about 10 years in between. Not being a programmer or it-expert or anything I m pretty comfortable with computers in general, and can code a bit in Applescript, Basic (yeah! C64!) and obviously Max since version 5. So now I have developed my app,
and it compiles easily on a mac, being portable and all - no problems.
Then I ported the code to windows - I don t have a distain for windows machines at all, and the one that I have for the task at hand really is ok taking into account that it costs a tenth (A TENTH!) of my MacBookPro. I don t expect it to perform like a porsche, and in a way this will be kind of the machines my app will end up to be running on anyway - but it got pretty ugly. I may have to say that my app is kind of complex, contains about 300mb of wav audio, tons of .txt files for coll-objects, javascripts, png-files and stuff like that. (NO JAVA!) And since I had to design a splashscreen as the startup-time
was seriously too long, this was a kind of special situation.

Splashscreen - how I did it:

I made a simple patch, essentially including a fpic-object to show the splashscreen png, and pccontrol-object to load my mainPatcher:
loadbang > delay 1000 > message(load mainPatch.maxpat) > pccontrol

The delay-object gives the splashscreen patcher time to start up completely, before all resources get directed to loading the mainPatch which in my case kind of „froze" Max while loading it.

Then I have an active-object in the mainPatch triggering back a message(wclose) via a send-object > thispatcher of the splashscreen.

Works great on mac, works great on win - EXCEPT that on windows THE TOP LEVEL PATCHER ( in this case the splashscreen) needs to stay open for the loaded mainPatch to access all the files compiled into the .mxf !
(I haven t experimented with compiling the mainPatch and telling the buildscript to open the splashscreen first, if that is a possibility, or to sequentially initialize all objects in order to close the top level patcher after the mainPatch is started up completely) So you need to check „can t close top level patcher“ in the standalone-object of the splashscreen. This can have the weird side-effect that you can not close the app at all, because if you choose to make your splashscreen a plain window only displaying the .png (using message(window notitle, window exec) > thispatcher) there will be no menu to exit the program!

.exe does not run on other machines… (DAMN!)

The lucky break for me was, that I was doing this splashscreen stuff, since when I opened the .mxf of the compiled application with max7 I could take a look at the list of used externals of the mainPatch. (you can not do that for the top level patcher, so it would have been impossible to track down if the mainPatch would ve been my top level patcher!)
It showed that the paths of the used externals were randomly to a location in the app and to the default location in the Programs/cycling74/Max7 folder…very interesting. It looked like they were essentially not found in the compiled version. So I actually tracked down every used external in the list and copied them into a seperate folder (yes! ALL OF THEM!) which I included in my buildscript. (include folder)
Worked like a charm! Now all paths pointed to the compiled location - even better, I could get rid of the „include C74 resources“ checkbox in the standalone-object!

NO javascript - AARARRRG!
still even though all externals were found and everything looked ok, some of the functions that were using javascript were not working at all…this could be fixed by copying the jsexternals folder from the C:/Programme/Cycling74/Max7/resources/… to the resources/support/… folder of my app.
You just don t have to forget about it every time you compile your app. (Do I have to tell you how annoying this gets after a while especially on a platform you are not working on every day?!)

Path to me in windows - VERY DIFFERENT from mac!

On a mac the ; max sendapppath gives you the location of the APP. You have to include the exact (!) appname.app into the path yourself (e.g. with sprintf object) and the following folder structure in order to find a file inside the app-folder-structure.

On a windows machine the ; max sendapppath gives you the location of the app-FOLDER. You do NOT have to include the exact appname and need only to add the following folder structure in order to find a file inside the app-folder-structure.

interface.json is in a different loaction.

OK, this is not surprising and very well documented once you read the great post by DanNigrin on building standalones.

PUNCHLINE:
Even though in retrospect finding out all about this was kind of entertaining, none of this was an issue on the mac. If I d developed this on a windows machine, it would have been probably the other way round?!

Short instructive version for building on windows 10:

- make sure that if you use ; max sendappath to point to a file in your appfolder that you have the correct path. on windows you do not have to include the exact appname, instead ; max sendappath points to your appfolder and you have to add the folder structure to your desired location without the appname.
- include all your abstractions with „include file“ manually.
- put all your resources (.txt, .png, .js, .json) in a designated folder and include it with „include folder“
- make a list of all your used externals Max menu > File > List Externals and Subpatcher Files and copy them into a designated folder and include it with „include folder“. (this is probably overkill, but in my case it was the only working solution)
- if you use javascript: copy C:/Programme/Cycling74/Max7/resources/jsextensions to appfolder/resources/support/...