In this section, we describe some advanced building scenarios. Basic building instructions are available elsewhere.
Install and run Docker for Windows (tested with version 18.06.1-ce-win73
),
enable Windows containers,
increase maximum container disk size
and run docker-compose up
. If you change Dockerfile
, you'll need to run
docker-compose up --build
to rebuild the Docker image. To run some other
commands instead of build.ps1
, run
docker-compose run --rm ipasim powershell
. To re-build, delete the folder
cmake
(rm -r cmake
from PowerShell). To build manually, just execute the
script build.ps1
(.\scripts\build.ps1
from PowerShell inside the container).
To run commands in a container repeatedly, first run
docker-compose run --name ipasim ipasim powershell
(i.e., without option
--rm
) and then (after exiting the container) run docker start -ai ipasim
.
When we have our Docker machine up and running, we can start building. First,
run .\scripts\build.ps1
inside C:\ipaSim\src
. That script creates build
directory C:\ipaSim\build
. Inside that directory, run
ninja config-ipaSim-x86-Debug
to prepare building of that configuration (x86
Debug). Then, move to C:\ipaSim\build\ipaSim-x86-Debug
and continue using
Ninja from there (e.g., run ninja -t targets
to see list of possible build
targets). To enable incremental builds across Docker builds, use scripts
C:\ipaSim\src\scripts\backup.ps1
and C:\ipaSim\src\scripts\restore.ps1
. See
issue #3 for more details.
We use a concept of issues. They are contained in folder /docs/issues/
and
can be referenced from code by hashtag and number, e.g., #1
.
Before we started using issues, we also used tags, i.e., unique short identifiers that were referenced from code and documented elsewhere. Below are documented those that can still be found in code.
[docker-script]
: This script is referenced fromDockerfile
. It's not meant to be run manually.
TAPI sources are located in /deps/tapi/
.
[must-quote]
: Changedbool
->QuotingType
,false
->QuotingType::None
,true
->QuotingType::Double
. LLVM API probably evolved.[no-dynamic]
:ObjCProperty
does not contain methodisDynamic
and it seems it never did.[sort]
: Inspired by Swift'sTBDGen
.[no-cmake]
: In the original code, this was built with CMake. But we don't use CMake, so we crafted it manually.
WinObjC sources are located in /deps/WinObjC/
.
[objc-class]
- We replace_OBJC_CLASS__NSCF...
symbol references (those were generated by the GNUstep runtime) withOBJC_CLASS_$__NSCF...
symbol references (which are generated by our Apple-like runtime).[class-symbols]
- Changed_OBJC_CLASS_*
toOBJC_CLASS_$_*
and__objc_class_name_*
toOBJC_METACLASS_$_*
. This reflects the difference between how our runtime and the GNUstep runtime name those symbols. Although symbols__objc_class_name_*
andOBJC_METACLASS_$_*
probably doesn't mean the same thing, we only replace those symbols in.def
files so it only causes them to be exported which is exactly what we want. Note that this "tag" is not actually used, because it would be virtually in every.def
file inside/deps/WinObjC/build/
. TODO: Write a script that will do this automatically (without the need for manually changing those.def
files).[ehtype]
- So that it is not an error to have multiple occurrences of symbol_OBJC_EHTYPE_$_NSException
. TODO: Instead makeclang
to not generate those symbols.[no-nsobject]
-NSObject
is implemented in our runtime, so we disabled it in WinObjC'sFoundation
framework.[uikit-autolayout]
- There is a circular dependency between projectsAutoLayout
andUIKit
.
See its documentation.
LLVM's sources are located in /deps/llvm/
, /deps/clang/
, /deps/lld/
and
/deps/lldb/
.
[ipasim-objc-runtime]
: We are adding a new runtime calledipasim
that derives from theios
runtime and introduces changes that themicrosoft
runtime introduced.[dllimport]
: See section "Objective-C symbols across DLLs".[mhdr]
: We are patching linker (lld-link
) to add a section named.mhdr
which will contain Mach-O header. This Mach-O header will then be used by ourlibobjc
to initialize the image.[fixbind]
: See[dllimport]
- we are fixing some symbols to use__declspec(dllimport)
semantics, but that introduces another level of indirection in data pointers. Unfortunately, Windows loader cannot bind symbols directly, so we need to fix those bindings at runtime. In Clang, we create a new section called.fixbind
which contains addresses to all the bindings that need to be fixed. At runtime, we then fix those addresses in ourdyld
.[pretty-print]
: We improved pretty printing of functions to match our needs inHeadersAnalyzer
.[emit-all-decls]
: SeeHeadersAnalyzer
.[irt]
: We renamed folderInstrumentationRuntime
toIRt
because the former was too long for Windows. TODO: Obviously, don't do this. Rather move our sources near the root (e.g.,C:\src\
). But then also mention that in build instructions.[macho]
: We want to read Mach-O object files on Windows, too. Alternative to this would be to emit PE/COFF instead, or just DWARF (-gsplit-dwarf
). Then, we wouldn't have to read Mach-O object files.[no-lsystem]
: We added option-no_lsystem
which, when used, tells Clang driver not to pass option-lSystem
to linker. We use this option inside ourHeadersAnalyzer
to generate.dylib
s on Windows (where is nolibSystem.dylib
for linker to use).[emit-bodies]
: We don't want to emit bodies in ourHeadersAnalyzer
since we are only interested in declarations. So we added and used this option to speed up the compilation by skipping body emission. If ever pushed upstream, this should be changed to emit just declarations, though. Because now it emits invalid almost-empty definitions.
LIEF's sources are located in /deps/LIEF/
.
[lief-mt]
: We link LIEF statically, because we need only substantial portion of it. But UWP apps need to link to CRT dynamically, so we need to use/MD
compiler option instead of/MT
.