MisterDA / love-release

:love_letter: Lua script that makes LÖVE game release easier
MIT License
448 stars 27 forks source link

Packaging native libraries #41

Open Alloyed opened 8 years ago

Alloyed commented 8 years ago

If you're interested in handling the native library thing, I've already thought a bit about how I would implement it. This stuff never made its way into loverocks mostly because it exists in a scope bigger than loverocks itself, so maybe this is the right place for it. This is basically a copy-paste from my existing notes, so sorry it's not as clear as it should be.

native libs are loadable from

It's actually impossible to statically determine which external dependencies a lib links to, because they can always use a makefile/cmake. You can probably parse the output of ldd once you've made it but how do you make that cross platform/avoid packing things like libc with your game?

Java approach

have a single mega-.love file that holds all the binaries you can find, put them each under a subtree, for examplerocks/win_x86/lib/..., extract as needed

pros:

cons:

Leave the binaries out of the love file, put them in next to your fused_game.exe, and then just pack everything up afterward

pros:

cons:

No binaries allowed. If a user wants to play a game with a native lib, they install loverocks and run loverocks deps themselves on your .love file.

pros:

cons:

pablomayobre commented 7 years ago

I'll tell you what I usually do when I have binary modules, first I don't make .love files with everything, since that is too bloated and you need to extract the specific binary from the .love file into the save directory and you end up with an extra copy of the binary inside the .love and also additional unneeded files for the other OSes.

I instead deploy to services like AppVeyor and TravisCI, AppVeyor builds my Windows distributable, makes an .exe, compiles the binary module into a .dll and packages everything into a .zip then that is turned into a Github release. TravisCI does the same thing for Mac OSX, while, for Linux I usually make a .tar.gz containing the .love file, the binary's source and build file (this is something that can be improved)

This means that no OS must do cross-compilation and that helps a lot, it also means that I can compile to OSes that I don't have available (currently Linux and Mac OSX)

For mobile that is a little bit different, mobile doesn't use dynamically linked binaries, instead they should be statically compiled so that they end up in the same .apk or whatever file iOS uses, and the build should end up being part of the Makefile used for said platform so that it gets built with the rest of the LÖVE binary.

Note here: For building binaries you will probably need header files that depend on the Lua version, same with linking, so in order to build binaries for LÖVE 0.10.2 you would need to have the source for LuaJIT 2.0.4 in order to get the needed header files, and you should also compile LuaJIT 2.0.4 in order to get the file you would link to (lua51.lib in Windows and liblua51.a in Linux/MacOSX I think) so all this files should be available somewhere. If Luarocks is used to build the library then Luarocks itself should be using LuaJIT 2.0.4 (issue #25)

Second note: Luarocks can't currently target the mobile LÖVE since that is statically and uses yet another LuaJIT version (2.1)

Alloyed commented 7 years ago

Future-me agrees with dumping the jar-related (1) stuff. If you're making binaries in the first place, there's no reason not to go all the way and provide everything. The source-only method (3) should work right now by using loverocks deps --game game.love, but I don't think I tested it that thoroughly. Doing (2) is still out-of-scope for loverocks, but I do want to see it happen.

Bytecode-wise, yeah, you need the appropriate luajit version, but in terms of compiling libraries, lua 5.1 and all versions of luajit should be ABI/API compatible. This means that lua 5.1 binaries should work everywhere, and all luajit binaries are also 5.1 binaries. Since bytecode itself is portable, you just need one copy of luajit 2.0, and one copy of luajit 2.1 on any machine to generate bytecode, and every other device can do what it wants.

I haven't looked into targeting mobile platforms yet. Luarocks doesn't support cross-compiling by default, but supposedly it's possible (http://lua-users.org/lists/lua-l/2013-10/msg00338.html), the only question from there is integration with the existing build tools (ant? xcode? Are you allowed to dlopen on ios?).

Side note: are those CI build scripts publicly available somewhere? I'd like to link them in the loverocks docs.