You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libshit/COMPILE.md

235 lines
10 KiB
Markdown

Compilation
===========
First: the compilation script is only really tested under Linux, even though it
should compile on any POSIX system. The official windows versions are
cross-compiled on Linux. I avoid using that piece of shit as much as possible.
Requirements:
* Compiler: gcc-8 (?) or clang-8
* Python 3+ (for the compile script)
* boost-1.84 (might work with older, also see notes below)
* Optional: lua-5.3
A note on boost: if you're using a system/your own compiled boost, make sure
it's compiled with the c++17 ABI. It might work in c++11/14 mode as boost
doesn't really use noexcept, but it's better to be safe than sorry. If you don't
want to deal with this problem, just use the `get_boost.sh` to download a recent
boost tarball and let the build system handle it.
Compiling
---------
Make sure submodules are checked out:
git submodule update --init --recursive
If you're not going to use your own boost, make sure to get it too:
libshit/get_boost.sh
Alternatively just make sure a recent boost tarball is extracted/symlinked to
`libshit/ext/boost/boost`.
In an ideal world, you can just run:
./waf configure
./waf
You can specify compile flags on configure:
CXX=g++ CXXFLAGS="-O3 -DNDEBUG" LINKFLAGS="-whatever" ./waf configure
You can use `CXXFLAGS_<appname>`, `LINKFLAGS_<appname>`, etc. to add flags only
used during compiling <appname> (e.g. `NEPTOOLS`), and `CXXFLAGS_EXT` etc. to
add flags only used during compiling bundled libs.
Some useful flags for configure:
* `--optimize`: produce some default optimization, but keep assertions enabled.
* `--optimize-ext`: optimize ext libs even if Neptools itself is not optimized
(will also remove debug info).
* `--release`: `--optimize` + no asserts
* `--system-boost`: use external Boost, see next section for warnings
* `--with-lua`, `--luac-mode`, `--lua-dll`: see section about lua
Vita
----
There is some experimental vita support, mostly in neptools. You need to get
[v1033][vitasdk] of Vita SDK (it might work with slightly newer version, but
don't try the latest, unless you want to fix the bugs and submit PRs).
mkdir -p /usr/local/vitasdk
cd /usr/local/vitasdk/
curl -L https://github.com/vitasdk/autobuilds/releases/download/master-linux-v1033/vitasdk-x86_64-linux-gnu-2019-04-28_16-30-10.tar.bz2 | tar xj --strip-components=1
You'll also need my patched vita-elf-create. Clone
https://git.neptards.moe/neptards/vita-toolchain or
https://gitgud.io/neptards/vita-toolchain, checkout `variable-import` branch,
compile, then overwrite `/usr/local/vitasdk/bin/vita-elf-create` with the
freshly compiled `vita-elf-create`.
Also, take `vita_db.patch`, update `/usr/local/vitasdk/share/db.yml` and
regenerate (at least) `libSceLibc_stub.a` and `libSceLibc_stub_weak.a` with
`vita-libs-gen`. If you don't do this, neptools will compile but it will crash
your game (and likely your system too) on startup.
You also need taihen:
git clone https://github.com/vitasdk/vdpm
cd vdpm
VITASDK=/usr/local/vitasdk ./vdpm taihen
Note the build scripts doesn't automatically create .suprx yet. With neptools,
this means you need to run
vita-elf-create -e src/vita_plugin/plugin.yml build/vita_plugin build/vita_plugin.velf
vita-make-fself -c build/vita_plugin.velf build/vita_plugin.suprx
after `./waf`.
(Cross) Compiling to Windows
----------------------------
Currently only clang (probably patched, see next section) is supported, with
MSVC 2013 lib files. In case of Neptools, it's pretty much a requirement.
You'll also need [lld] if you want LTO or want to cross compile. I've only
tested cross compiling, but it should be possible to compile on Windows too.
Install MSVC 2013 on a Windows (virtual) machine. If you want to cross compile,
you'll need to copy directories named `include` and `lib` to your Linux box from
`Program Files (x86)/Microsoft Visual Studio 12.0/VC` and `Program Files
(x86)/Windows Kits/8.1` too (assuming default install location).
Pro tip #0: Open `include/stdarg.h`, and replace it with an `#error`. If this
file gets included, that means you fucked up the include order (since clang has
its own `stdarg.h`). In this case the program will compile, but vararg functions
will crash.
Problem #1: Linux filesystems are usually case-sensitive, but MSVC headers
pretty much expect a case-insensitive file lookup.
Solution 1: store the files on a case-insensitive fs (fat, ntfs, etc, or just
mount your Windows fs).
Solution 2: use [ciopfs]. Make sure you mount `ciopfs` first, and copy into that
directory, otherwise you'll manually have to convert all files to downcase.
Solution 3: use something like [icasefile] to make clang-cl and lld-link
case-insensitive.
Solution 4: convert all files and directories to downcase and fix the headers.
Something like this will do:
find path/to/msvc/files -name '*[A-Z]*' -print0 | sort -rz | xargs -0n1 sh -c 'mv "$0" "$(echo -n "$0" | awk -F/ "{ORS=\"/\"; for (i=1;i<NF;i++) print \$i; ORS=\"\"; print tolower(\$NF)}")"'
find path/to/msvc/includes -type f -exec sh -c 'echo "$(awk "/^[[:space:]]*#[[:space:]]*include/ {print tolower(\$0); next} {print \$0}" "$0")" > "$0"' {} \;
You'll also have to fix boost in this case... open
`libs/filesystem/src/unique_path.cpp` inside boost (inside `ext/boost` if you
use the bundled one) and replace `Advapi32.lib` with `advapi32.lib` in
`# pragma comment(lib, "Advapi32.lib")`. I personally use solution 2 and 4,
the other two solutions may or may not work.
Problem #2: clang will default to compile for the host (we're using `clang` and
not `clang-cl`!) and it won't know where are your files, so you'll need some
compiler flags. For compiling you'll need: `-target i386-pc-windows-msvc18
-Xclang -internal-system -Xclang $vc/include -Xclang -internal-system -Xclang
$winkit/include/um -Xclang -internal-system -Xclang $winkit/include/shared`
where `$vc` and `$winkit` refers to the folders you previously copied. Using
`-internal-system` will make sure your include paths are correct (this is whan
`-imsvc` uses under the hood, but that only works with `clang-cl`, not `clang`).
For linking, you'll need `-fuse-ld=lld -L$vc/lib -L$winkit/lib/winv6.3/um/x86`.
In the end, you'll end up with something like this:
```
CC=$clangbin/clang CXX=$clangbin/clang AR=$clangbin/llvm-ar CFLAGS="-target i386-pc-windows-msvc18 -Xclang -internal-system -Xclang $vc/include -Xclang -internal-system -Xclang $winkit/include/um -Xclang -internal-system -Xclang $winkit/include/shared" CXXFLAGS="$CFLAGS" LINKFLAGS="-fuse-ld=lld -L$vc/lib -L$winkit/lib/winv6.3/um/x86" ./waf configure [--release] [--with-tests]
```
Some potential problems with the clang toolchain
------------------------------------------------
Using lld 8.0.0 to link, the generated executable will crash when the first
exception is thrown and it won't have icons. Use
`ebuilds/sys-devel/lld/files/lld-8.0-u3.patch` to fix this.
Second problem: llvm/clang doesn't support the `/EHsa` flag, only `/EHs`, but
that won't catch LuaJIT exceptions. The
`ebuilds/sys-devel/llvm/files/llvm-8.0-u3.patch` includes a quick hack that'll
at least make sure destructors are called when unwinding lua exceptions (and
exceptions are handled manually by `__try`/`__except`).
Lua
---
Libshit includes the most horrible lua binding generator that you'll ever see.
It officially supports plain lua 5.3, but it might work with LuaJIT, LJX or
whatever other lua variant you have.
Use `--with-lua=` to select a lua version:
* `none`: build without lua. Equivalent to `--without-lua`.
* `lua`: build plain lua 5.3.
* `system`: use a system lua. Specify the name of the correct pkg-config package
name with `--lua-pc-name=`. It should point to lua 5.3 (or something
compatible).
To run libshit, you have to embed a few lua scripts into the executable. There
are multiple methods to do this, use `--luac-mode=` to select it:
* `copy`: copy the lua source without changes. Use if you have no better option.
* `system-luajit`: use a system binary with `luajit` like command line to
compile lua to byte code. Select the binary by setting the `LUAC` environment
variable. Make sure the tool produces byte code that the selected lua
understands!
* `luac`: (only with `lua`) use the built lua's luac to compile scripts.
* `system-luac`: like `system-luac`, but expects a `luac` like binary.
* `luac-wrapper`: (only with `lua`) use the built luac, but use a wrapper to run
it. See below.
**Note** when using plain lua: unfortunately plain lua's byte code is not
portable, you can't use a luac built for platform A and load the byte code on
platform B. Here are your options:
* if you can run the binaries compiled for the target platform (for example
cross-compiling on `amd64` linux to 32-bit linux), just use `luac` if
compiling lua, or `system-luac` and make sure you specify the correct binary
(32-bit `luac` in the example).
* if you can run the compiled binaries with a wrapper (like `wine`, or the qemu
user emulation), use `luac-wrapper` and specify the wrapper if building lua.
In case of a system lua, you can use `LUAC=wrapper /path/to/luac` with
`system-luac`.
* For more complicated scenarios: either write a script that takes arguments
similar to luac and solves the problem somehow, or just use `--luac-mode=copy`
(which should be the default if the build script detects cross-compilation).
Lua binding generator
---------------------
This is only relevant if you want to develop code. The generated binding files
are checked into the repository, so you don't have to do anything with it if you
only want to compile.
Requirements:
* `ruby-3.1` + `ffi` gem
* patched clang: apply `ebuilds/sys-devel/clang/files/clang-8.0-u3.patch` to
clang 8.0.0.
Generate bindings:
./gen_binding.rb
If you have the patched clang in a non-standard location:
PREFIX=llvm/install/prefix ./gen_binding.rb
In the source, mark method which you do not want to export with `LIBSHIT_NOLUA`.
There's also `LIBSHIT_LUAGEN` which allows fine tuning of binding generation.
Edit `gen_binding.rb` if you need to generate binding for a new file.
TODO: write much more documentation
[vitasdk]: https://github.com/vitasdk/autobuilds/releases?q=master-linux-v1033
[lld]: http://lld.llvm.org/
[ciopfs]: http://www.brain-dump.org/projects/ciopfs/
[icasefile]: http://wnd.katei.fi/icasefile/