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.
235 lines
10 KiB
Markdown
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/
|