Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,55 @@
The Hxcpp Cache
---------------
The hxcpp compile cache is used to share object files between projects. This can alleviate the need to ship static libraries with external projects, since developers who use the library can compile the library just once, and then reuse it between projects.
The cache uses a hashing mechanism to tell if the contents of a file or its dependencies has changed, and combines this with the compiler version and flags to make specific object files for each change and each compiler congiguration. This also allows some common haxe runtime and haxe generated files to share their object files between projects, even if in different directories.
Additional benefits include keeping some files outside the source tree, and being able to remove these temp files easily.
### Setup
A directory needs to be set aside to enable the cache. If possible, this should be on fast storage, such as a SSD. This is most easily done with an entry in the .hxcpp_config.xml file:
```xml
<set name="HXCPP_COMPILE_CACHE" value="c:/hxcpp/cache" />
<set name="HXCPP_CACHE_MB" value="4000" />
```
Keeping the path short can help in some border-line cases with some compilers where command-line length can become an issue.
The cache size defaults to 1 Gig. For many cases, this is big enough. However, on large projects, with several architectures and lots of debug information, this default can lead to "cache churn" where some files are evicted from the cache, even though they are likely to be used again. Increasing the number of mega-bytes allocated to the cache can help here.
### Using The Cache
To use the cashe with your own libraries, the files group should have 'cache' entry to tell hxcpp that you have considered dependency issues when designing the group.
```xml
<cache value="true" project="name" asLibrary="true" />
```
- project = name of project used to manage and group object files in the cache
- asLibrary = link the objs into a .lib file.
When linking a file group 'asLibrary', the object files are compiled and then the library tool is used to make a library from these object files. This library is then added to the linker. This has a few implications:
- Object files that to not resolve any symbols directly are not added to the final executable
+ Can make final exe size smaller
+ If the object file only contains a handler that is self-registering via static constructor,
then the constructor may not get called, leading to bugs.
- Can help on some systems where the linker command-line length is an issue.
### Management
When compiling normally, hxcpp will check the cache size and evict the least used files to maintain the specified cache size.
Object files in the cache are grouped into "projects" to make management easier, and the hxcpp build tool can be used to explicitly manage the object files.
```
haxelib run hxcpp cache [command] [project]
Perform command on cache, either on specific project or all. commands:
clear -- remove all files from cache
days #days -- remove files older than "days"
resize #megabytes -- Only keep #megabytes MB
list -- list cache usage
details -- list cache usage, per file
```
Start with
```
haxelib run hxcpp cache list
```
To get an idea of cache usage.

View File

@ -0,0 +1,152 @@
Threads And Stacks
-------------------
### Conservative, co-operation
Hxcpp uses conservative stop-the-world GC, where the threads need to co-operate.
- Threads must not change GC pointers in the collection phase
- The thread stacks/registers must be scanned for GC pointers
- Threads must not block without letting the GC system know not to wait for them, otherwise GC blocks until end of block
+ call hx::GCEnterBlocking() / gc_enter_blocking() / (cpp.vm.Gc.enterGCFreeZone() from Haxe) before potentially blocking system call (fs, network, etc)
+ call hx::GCExitBlocking() / gc_exit_blocking() / (cpp.vm.Gc.exitGCFreeZone() from Haxe) before making more GC calls
+ Might need to pre-allocate buffers
+ Don't forget the exit blocking on error condition
### Foreign Threads
When you create a thread from haxe, it starts attached. Before a non-haxe created thread can interact with hxcpp, some care must be taken, since GC allocations are done using a GC context per thread, and all threads must respect the stopped world.
- Foreign threads must be attached-detached
- SetTopOfStack(int * inTop,bool inPush)
- *inTop* = pointer to top of stack to attach, or '0' to remove stack
- *inPush* = usually true. recursive attachment/detachment
- Must not change things when the world is stopped
- Must define their stack range for scanning
- If you are attached, you may need to enter/exit gc free zone
- Must release context when done, if no more calls are going to be made
- Make sure local variables are covered in stack
- compiler may reorder, so be careful
- Read documentation because some things, eg audio callbacks, happen on other threads
- You can use other techniques, eg
- create a haxe thread, which blocks waiting for signal
- foreign thread generates request and signals haxe thread
- haxe thread performs job and generates data then signals foreign thread
- foreign picks up data and carries on
### Top of Stack
- To understand how to handle threads, you need a mental picture of the c++ stack
- The stack usually goes "down". That is, if the first stack location is 10000, the next one will be 9999 etc.
- Historical, but consistent. Except for emscripten which goes up - but still use same terminology/picture, just change the less-thans to greater-thans in code.
Say the system starts each program stack at 10000, the stack might look like this, with local variables and arguments pushed on the stack:
```
10000
-----------------------------------------------
9996 startup temp variable
9992 startup temp variable
-- main function --
9988 main return address - order and details of this are ABI specific
9984 char ** argv
9980 int argc
```
Hxcpp then runs it main code, which starts with the macro HX_TOP_OF_STACK, which expands to something like:
```
int t0 = 99;
hx::SetTopOfStack(&t0,false);
...
__boot_all();
__hxcpp_main();
-- main function --
9988 main return address order and details of this are ABI specific
9984 char ** argv
9980 int argc
9976 int t0
-- hx::SetTopOfStack --
records '9976' as top of stack for this thread
```
Later, many generated functions deep, `__hxcpp_main` generates an allocation call which
triggers a collection
```
...
8100 Array<Bullet> bullets
-- alloc Enemy --
...
-- Call collect --
8050 int bottomOfStackTemp
MarkConservative(&bottomOfStackTemp, 9976) -> scans stack from 8050 -> 9976
MarkConservative(Capture registers)
```
Enter/exit use similar technique, where the registers are captured and the bottomOfStack is 'locked-in' when the "enter gc free zone" call is made.
```
8100 Array<Bullet> bullets
-- EnterGCFreeZone --
8088 int bottomOfStackTemp
thread->setBottomOfStack(&bottomOfStackTemp)
thread->captureRegisters()
return
* any changes here will not affect GC
```
Now, when another thread does a collection, the gc-free thread can be scanned from 8088 to 9976, regardless of any stuff happening lower dowsn the stack.
### Not Called From Main
Top of stack can be tricky to get right when a gui framework does not really have a "main".
```
10000
-----------------------------------------------
9996 startup temp variable
9992 startup temp variable
-- main function --
setupWindows(onReadyCallback)......
...
8000
-- onReadyCallback --
7976 int t0
SetTopOfStack(&t0,false) -> 7966
__hxcpp_main();
setOnFrameCallack(haxeOnFrame)
return;
```
Later, the haxeOnFrame callback is trigger, but not "below" `__hxcpp_main`
```
9800 -- haxeOnFrame ---
// Top of stack will be below bottom of stack.
```
Solutions:
- Make sure you get in at top of main
+ may scan too much?
- Ratchet up top-of-stack in callbacks, inForce = false
+ gc_set_top_of_stack(void * inTopOfStack,bool inForce);
- Detach main thread after hxcpp_main and reattach each callback
+ android solution because render callbacks happen on different threads
+ gc_set_top_of_stack(&base,true); // attach
+ gc_set_top_of_stack(0,true); // detach
### Debugging.
- in debug mode, hxcpp will check for calls from unattached threads
- hxcpp can log conservative ranges. With a native debugger you can check the address of
your local variables and ensure they are included.
- hxcpp will scan native objects on the stack, but will not follow non-haxe pointers to other objects, so additional GC roots may be required.

View File

@ -0,0 +1,82 @@
Compiler
--------
Compilers are run over each of the changed files in each of the filegroups in a target to create object files, which are then linked into the target. Modification dates or hashes are used to tell if files need recompiling, of if the object file can be reused.
- *flag* - Add single arg to command-line.
```xml
<flag value="value" tag="tag" />
```
+ value = text for flag added to command line
+ tag = optional filter to restrict flag to files with matching tag. See [Tags.md](Tags.md).
- *cflag/cppflag/objcflag/mmflag* - Add flag when compiling specific file types.
```xml
<cflag value="value" />
<cppflag value="value" />
<objcflag value="value" />
<mmflag value="value" />
```
+ cflag = only added to .c files
+ cppflag = only added to .cpp files
+ objcflag = only added to .objc files
+ mmflag = only added to .mm objc++ files
- *pchflag* - Add flag when compiling precompiled header .h files.
```xml
<pchflag value="value" />
```
+ pchflag = Usually `["-x", "c++-header"]` for apple to specify the "identity" of the header
- *pch* - Set the precompiled header style - "gcc" or "msvc".
```xml
<pch value="gcc|msvc" />
```
- *objdir* - set name of directory used to store object files. Should be unique for given set of compiler flags to avoid linking against wrong architecture.
```xml
<objdir value="obj/somewhere" />
```
+ value = usually built programmatically, like `obj/msvc${MSVC_VER}-rt${OBJEXT}${OBJCACHE}${XPOBJ}`
- *output* - Flag used to specifying compiler output name.
```xml
<outflag value="-flag" />
```
+ value = flag value. Note that it should contain a space character
if the actual name should be a separate argument, like "-o ", or "-o"/"-out:" if it does not.
- *exe* = Override the executable command specified in the compiler attribute.
```xml
<exe name="command" />
```
+ name = command. Usually you would use 'path' to add the directory, then this is just the filename part.
- *ext* - Specify the object file extension
```xml
<ext name=".obj" />
```
+ name = extension, including ".". Usually ".o" or ".obj".
- *getversion* - The command-line used to create text describing the version of the compiler.
This is used for working out if the compiler has changed, and therefore the objs need recompiling.
```xml
<getversion value="command" />
```
+ value = command to run. It defaults to `compiler --version` which is usual for gcc based compilers.
Setting it empty will disable caching.
- *section* - Group entries - usually sharing common condition
```xml
<section > </section>
```
- *include* - include compiler options from another file. Most compilers should include `<include name="toolchain/common-defines.xml" />` to add defines used by hxcpp.
```xml
<include name="filename" />
```

View File

@ -0,0 +1,90 @@
Defines
-------
There are a number of standard defines you can use to control the hxcpp build. Some of these are used by the haxe compiler, and affect then generated code. Others apply to the build tool and affect how the code is compiled.
Defines affecting how the code is generated. These need to be in the command line when calling haxe.
| Define | Meaning |
|-------------------------|--------------------|
| *HXCPP_DEBUGGER* | Add extra macros required by debugger. Usually added automatically be debugger haxelib |
| *HXCPP_GC_GENERATIONAL* | Enable experimental generational garbage collector |
| *annotate_source* | Add additional annotations to source code - useful for developing hxcpp |
| *dll_export* | Export hxcpp runtime symbols |
| *file_extension* | Set the extension (without the dot) of generated files. eg "-D file_extension=mm" for objc++ code |
| *force_native_property* | Make dynamic access of fields call property getters/setters where appropriate |
| *include_prefix* | Place all generated include files in a sub-directory, eg "-D include_prefix=hxinc". Useful for avoiding name clashes |
| *no-compilation* | Generate the code, but do not compile it |
| *no-debug* | Do not generate debug macros in code |
| *nocppiaast* | Use legacy cppia generation instead of new more recent changes |
| *objc* | Generate objective-c++ classes |
| *scriptable* | Enable extra runtime information required for scripting |
Defines affecting how the code is compiled. These can be on the command line when calling haxe, or added via the hxcpp build environment.
| Define | Meaning |
|-------------------------|--------------------|
| *HXCPP_GC_MOVING* | Allow garbage collector to move memory to reduce fragmentation |
| *HXCPP_GC_SUMMARY* | Print small profiling summary at end of program |
| *HXCPP_GC_DYNAMIC_SIZE* | Monitor GC times and expand memory working space if required |
| *HXCPP_GC_BIG_BLOCKS* | Allow working memory greater than 1 Gig |
| *HXCPP_GC_DEBUG_LEVEL* | Number 1-4 indicating additional debugging in GC |
| *HXCPP_DEBUG_LINK* | Add symbols to final binary, even in release mode. |
| *HXCPP_STACK_TRACE* | Have valid function-level stack traces, even in release mode. |
| *HXCPP_STACK_LINE* | Include line information in stack traces, even in release mode. |
| *HXCPP_CHECK_POINTER* | Add null-pointer checks,even in release mode. |
| *HXCPP_PROFILER* | Add profiler support |
| *HXCPP_TELEMETRY* | Add telemetry support |
| *HXCPP_CPP11* | Use c++11 features and link libraries |
| *exe_link* | Generate executable file (rather than dynamic library on android) |
| *static_link* | Generate static library |
| *dll_link* | Generate dynamic library |
Other defines:
| Define | Meaning |
|-------------------------|--------------------|
| *HXCPP_VERBOSE* | Print extra output from build tool. |
| *HXCPP_TIMES* | Show some basic profiling information |
| *HXCPP_NEKO_BUILDTOOL* | Force use of hxcpp.n, rather than compiled BuildTool.exe
| *HXCPP_NO_COLOR* | Do not add colour-codes to tool output |
| *HXCPP_KEEP_TEMP* | Does not delete the files created for file 'embedName' option |
Defines affecting target architecture.
| Define | Meaning |
|-------------------------|--------------------|
| *HXCPP_M32* | Force 32-bit compile for current desktop |
| *HXCPP_M64* | Force 64-bit compile for current desktop |
| *HXCPP_ARMV6* | Compile arm-based devices for armv6 |
| *HXCPP_ARM64* | Compile arm-based devices for 64 bits |
| *HXCPP_ARMV7* | Compile arm-based devices for armv7 |
| *HXCPP_ARMV7S* | Compile arm-based devices for armv7s |
| *HXCPP_LINUX_ARMV7* | Run on a linux ARMv7 device |
| *HXCPP_LINUX_ARM64* | Run on a linux ARM64 device |
| *winrt* | Compile for windowsRt/windows UWP |
| *android* | Compile for android |
| *PLATFORM* | Specify the android platform for NDK compilation |
| *ANDROID_NDK_ROOT* | Specify the location of the android NDK toolchain |
| *ANDROID_NDK_DIR* | Specify the search location for finding the android NDK toolchain |
| *HXCPP_X86* | Compile android for x86 architecture |
| *iphoneos* | Compile for iphone iOS |
| *iphonesim* | Compile for iphone simulator |
| *appletvos* | Compile for apple tvOS |
| *appletvsim* | Compile for apple tvOS simulator |
| *watchos* | Compile for apple watchOS |
| *watchsimulator* | Compile for apple watchOS simulator |
| *webos* | Compile for webOS |
| *tizen* | Compile for Tizen |
| *blackberry* | Compile for Blackberry |
| *emscripten* | Compile for Emscripten |
| *cygwin* | Compile for windows using cygwin |
| *linux* | (Cross) Compile for linux |
| *rpi* | (Cross) Compile for raspberry pi |
| *mingw* | Compile for windows using mingw |
| *HXCPP_MINGW* | Compile for windows using mingw |
| *NO_AUTO_MSVC* | Do not detect msvc location, use the one already in the executable path |
| *HXCPP_WINXP_COMPAT* | Remain compatible with Windows XP. Disables condition variables. No effect on ARM. |

View File

@ -0,0 +1,94 @@
Files
------
The files node defines a group of files that all share the same attributes, including relative directory, default compiler flags and dependencies. The node can be used to define a set of header files on which other files can depend, or a set of source files to be compiled and included in a target.
- *depend* - Declare that all files in the group depend on another file or another file group.
```xml
<depend name="filename" />
<depend files="filesId" />
```
+ name = If the named file changes then then all the files in the group need recompiling.
+ files = If any of the files in the named group changes then then all the files in the group need recompiling.
- *options* - Name of file containing compiler flags. When the cache is not used, Options.txt helps detect when the options have changed, and therefore whether files need recompiling.
```xml
<options name="Options.txt" />
```
- *config* - Name of file to generate that contains the #defines that were active when code was compiled.
```xml
<config name="outfile.h" />
```
- *tag* - Add a default compiler flags tag to all files in group. See [Tags.md](Tags.md).
```xml
<tag value="tag" />
```
- *addTwice* - When compiled to a library, add the library twice to the link line - once at the beginning and once at then end to satisfy linux selective linking.
```xml
<addTwice value="tue" />
```
- *cache* - Use compiler cache for files in group. See [compile cache](../CompileCache.md) for more details.
```xml
<cache value="true" project="name" asLibrary="true" />
```
+ project = name of project used to manage and group object files in the cache
+ asLibrary = link the objs into a .lib file, which can skip unneeded objs, but
will also skip things that rely on static initializers to register handlers, so be careful.
- *include* - Include an external file list
```xml
<include name="filename.xml" />
```
- *section* - Groups block of elements - usually ones that all respect the same if/unless condition.
```xml
<section name="id" /> </section>
```
- *compilerflag* - Add a compilerflag when compiling files in group.
```xml
<compilerflag name="name" value="value" />
<compilerflag value="value" />
```
+ name, value = add 2 flags when compiling
+ value = add 1 flag when compiling
- *nvcc* - This group is compiled with nvcc.
```xml
<nvcc />
```
- *objprefix* - An id prepended to generated obj name to allow alphabetical grouping of similar objs.
```xml
<objprefix value="prefix" />
```
- *precompiledheader* - Use a precompiledheader of given name when compiling group
```xml
<precompiledheader name="name" dir="directory" />
```
+ name = the include used when precompiling these files (without the .h)
+ directory = the location of this file
eg, for `#include <lib/Header.h>`
+ name = "lib/Header"
+ directory = "${haxelib:somelib}/include"
- *file* - Add file to group, with optional attributes
```xml
<file name="filename" tags="tag,tag1" filterout="define" embedName="embed" >
<depend name="filename1" />
<depend name="filename2" />
</file>
```
+ name = name of file - may be absolute or relative to files.dir
+ tags = optional override of group tags. See [Tags.md](Tags.md).
+ filterout = allows files to be skipped at compile-time if the named define exists.
This is useful when the define is set sometime after the file list is parsed.
+ depend name = filename of additional dependency
+ embed = causes the file to be embedded as an extern c++ 'const char *' string constant of the specified name

View File

@ -0,0 +1,97 @@
The Haxe Target
---------------
When compiling from haxe, via hxcpp, a "Build.xml" file is generated in the output directory. The file lists the generated files and dependencies and ultimately includes the "toolchain/haxe-target.xml" file, which describes how to combine these files.
### Include Order
There are a few complications when setting the order in which things are configured, since a particular build might want to:
- set the compiler
- override some compiler settings
- make decisions based on the compiler or settings
- set or use standard file prefixes/suffixes
### Example Sequence
You can see which files are included by setting the HXCPP_VERBOSE define when compiling. One example is for a hypothetical user 'Hugh' on a windows platform:
```
Using makefile: Build.xml
No specified toolchain
- Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/setup.xml
- Parsing include: C:\Users\Hugh\.hxcpp_config.xml (section "vars")
Using Windows compiler: MSVC
- Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/finish-setup.xml
- Parsing makefile: C:\Users\Hugh\test\proj\cpp\Build.xml
- Parsing include: C:/Users/Hugh/dev/hxcpp/build-tool/BuildCommon.xml
- Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/haxe-target.xml
- Parsing include: C:/Users/Hugh/dev/hxcpp/toolchain/msvc-toolchain.xml
- Parsing compiler: C:/Users/Hugh/dev/hxcpp/toolchain/common-defines.xml
- Parsing include: C:\Users\Hugh\.hxcpp_config.xml (section "exes")
```
- setup.xml is read because no custom toolchain is specified, and this just include hxcpp_config
- the 'vars' section of hxcpp_config is read - mainly to setup SDK locations
- the hxcpp build tool then uses internal logic based on host and defines to work out which compiler/toolchain to use
- finish-setup then sets a bunch of standard defines for file-extensions and linking flags based on
the type of toolchain being used.
- The provided buildfile (Build.xml) is then processed. It can use the standard defines from finish-setup.
- Build.xml imports the standard haxe-target buildfile, which adds standard runtime files
- The toolchain file is then parsed - making use of any settings from the main Build.xml and finish-setup.
- This file includes the "common-defines.xml" from the compiler to inject standard haxe compiler flags
- hxcpp_config "exe" is parsed. Historically to add libraries or build-paths to targets.
### Standard Environment
finish-setup.xml is where the conventions are set. These variables include:
- haxelink = dll|static_link|exe
- LIBPREFIX = lib|""
- LIBEXTRA =
+ .iphonesim-64
+ .iphonesim
+ .iphoneos
+ .iphoneos-v7
+ .iphoneos-v7s
+ .iphoneos-64
+ .appletvsim-64
+ .appletvsim
+ .watchos
+ .watchsimulator
+ -x86
+ -v7
+ -64
- HX_LINK_SUFFIX = LIBEXTRA | -19 (msvc 19)
- LIBEXT = .a|.lib
- DBG = ""|"-debug"
- OBJEXT = "-list-of-config-ids" depending on available options
These variables are used by haxe-target - you can use them too. Haxe then builds the "haxe" target, which uses some code like:
```xml
<set name="HAXE_OUTPUT_FILE" value="${LIBPREFIX}${HAXE_OUTPUT_PART}${DBG}" />
<target id="haxe" tool="linker" toolid="${haxelink}" output="${HAXE_OUTPUT_FILE}">
<ext value="${LIBEXTRA}.a" if="static_link" />
<!-- ... -->
<files id="__main__" unless="static_link" />
<files id="__lib__" if="static_link"/>
<files id="__resources__" />
<files id="__externs__" />
<files id="runtime" unless="dll_import" />
<files id="cppia" if="scriptable" />
<lib name="-lpthread" if="linux" unless="static_link" />
<lib name="-ldl" if="linux" unless="static_link" />
</target>
```
Here you can see the various file groups, which are enabled or not depending on the compiler mode, and some standard libraries that are needed for Linux.
### Experimenting With Hxcpp Generated Code/Build.xml
If you are using external cpp code, or using meta-data to inject xml into the build process, and you are getting a compile or link error, then it can be useful to run the hxcpp build tool without re-running haxe. This lets you hand-edit the build file or generated c++ code until you get things to work. Once you have solved the issues using this technique, then you can move the changes back into the injected/external code.
First, compile haxe with '-v' flag. This gives quite a bit of debug, but will include a line like this:
```
haxelib run hxcpp Build.xml haxe -Dhaxe3="1" -Dhaxe_ver="4.000" -Dhxcpp_api_level="332" -Dsource-header="Generated by Haxe 4.0.0" -I"" -I"C:/Users/Hugh/dev/haxe/std/cpp/_std/" -I"C:/Users/Hugh/dev/haxe/std/"
```
To use this, first change directories to your output directory. This will be the one you specified with the "-cpp" haxe compiler option. Then, cut and paste this command into a shell, cmd or batch file.

View File

@ -0,0 +1,86 @@
Linker
------
Generally one linker is run per target to build a static library, dynamic library or exe. The 'id' attribute of the linker specifies whch type of linking is performed.
- *exe* - Overwrite the exe command for this linker.
```xml
<exe name="command" />
```
- *flag* - Add a single link flag.
```xml
<flag value="flag"/>
```
- *ext* - Default extension for generated files - if not overridden by target.
```xml
<ext value=".ext"/>
```
+ value = extension, including "."
- *outflag* - Flag for specifying linker output name.
```xml
<outflag value="-o"/>
```
+ value = linker flag. Note that it should contain a space character
if the actual name should be a separate argument, like "-o ", or "-o"/"-out:" if it does not.
- *section* - Group items - usually sharing common condition
```xml
<section > </section>
```
- *libdir* - A temp directory name to build into. This will capture the extra files the compiler
generates, and then the desired file will be copied to the correct location.
```xml
<libdir name="name"/>
```
- *lib* - Add a library to the link line.
```xml
<lib (name|hxbase|base)="libName" />
```
+ name = the complete name is specified
+ base = the name without compiler-specific extension (.a/.lib) is specified
+ hxbase = the name without extension and architecture (-v7/.iphoinesim) is specified
- *prefix* - Prefix for generated files.
```xml
<prefix value="lib"/>
```
+ value = prefix. This will usually be "lib" or nothing.
- *ranlib* - Whether ranlib needs to be run, and what command to use. Usually only for unix-style static libraries
```xml
<ranlib name="ranlib command"/>
```
- *libpathflag* - Flag used for adding library paths to command line. It will be combined with *lib* entries.
```xml
<libpathflag value="-L"/>
```
- *recreate* - Whether to delete the target file before re-running link command.
The archive "ar" command likes to add obj files to existing archives, so deleting first can help.
```xml
<recreate value="true"/>
```
- *expandAr* - Whether to extract the individual obj files from an archive and add these, rather than
add the archive as a single library. Can solve some link-order and static-initialization issues,
but may make final exe bigger.
```xml
<expandAr value="true"/>
```
- *fromfile* - If the linker supports taking a list of objs in a file, then this is flag for specifying the file.
```xml
<fromfile value="flag" needsQuotes="true" />
```
+ value = flag for specifying file.
If the filename should be a separate argument, then the flag should end with a space.
Usually `@` or `-filelist `. Use empty to disable.
+ needsQuotes = is whether to quote the obj names in the file

View File

@ -0,0 +1,79 @@
Build.xml
----------
The hxcpp build.xml build system is designed to make compiling, cross-compiling and linking easy on a large variety of operating systems and devices. It was originally designed to build the haxe-generated c++ code but has evolved to replace the need for configuration tools in many open source libraries.
### Running
The source code for the tool lives in "tools/hxcpp" in this repo. When compiled, it can be run with the haxe 'haxelib' library tool. This is usually done automatically by the haxe compiler after the cpp code has been generated. It can be done manually like:
```
haxelib run hxcpp build.xml key=value .... [target]
```
### Configuration
The hxcpp build tool is configured using key-value pairs, or just using keys, known internally as 'defines'. These can be set in several ways:
- From system environment variables
- From the command-line, with key=value
- From haxe. Keys defined in haxe with '-D key[=value]' are passed to the build too, where they can influence the build. Certain defines need to be set on the haxe command line so that they can influence the generated code.
- From the the .hxcpp_config.xml file in the users home(profile) directory. This is a good place to set values the apply to the whole machine, like the location of SDKs etc.
- The defines can be manipulated logically from within the build files themselves.
See [Defines.md](Defines.md) for a list of standard defines.
### Format
The compiler specification and target lists all use the same format.
- uses xml parser
- mostly declarative list of files and flags
- order is important
+ overriding values is a valid technique
+ "commands" are run as they are parsed (eg, 'echo')
- conditions via "if" and "unless" node attributes
- substitution via '${VAR}' syntax
- need to define 'default' target
### Conditions/Substitution
Most of the xml nodes support 'if' and 'unless' attributes. These will enable or disable the whole node according the existence or non-existence of a define. These can be combined with a space for "and" or two pipes for "or".
Substitution is supported via the dollars-brace syntax, and does simple text substitution. In addition, there are a few dynamic variables that can be used:
- "${VAR}" - normal replacement
- "${removeQuotes:VAR}" - strips surrounding quotes from VAR, it any
- "${dospath:VAR}" - converts VAR to backwards-slash path
- "${dir:PathWithFilename}" - just the directory part of filename
- "${this_dir}" - the location of the containing build.xml file
### Example
The following code is saved in [example.xml](example.xml) in this directory
```xml
<xml>
<echo value="Hello ${WHO}" if="WHO" unless="SILENT" />
<echo value="You are in ${haxelib:hxcpp}" unless="WHO||SILENT"/>
<error value="Silent and who both specified" if="WHO SILENT"/>
<target id="default" />
</xml>
```
and some example uses:
```
unsetenv SILENT
haxelib run hxcpp example.xml
haxelib run hxcpp example.xml WHO=world default
setenv SILENT 1
haxelib run hxcpp example.xml
haxelib run hxcpp example.xml WHO=world
```
### Details
The build.xml file contains configuration, targets, compilers, linkers and files. The details can be found in this directory.
- [Top Level](TopLevel.md)
- [Files](Files.md)
- [Targets](Targets.md)
- [Compiler](Compiler.md)
- [Linker](Linker.md)
- [Stripper](Stripper.md)
When building from haxe, the "haxe" target is built. You can see the details in [HaxeTarget](HaxeTarget.md).
You can extend the generated Build.xml from haxe code using [Xml injection](XmlInjection.md).

View File

@ -0,0 +1,15 @@
Stripper
--------
A stripper is used to remove debug information in release builds on gcc-like systems. It may contain entries:
- *exe* - Override stripper command
```xml
<exe name="command"/>
```
- *flag* - Add flag to stripper command
```xml
<flag value="flag"/>
```

View File

@ -0,0 +1,31 @@
Tags
----
Tags are identifiers that link compiler flags with specific files. Usually, they are defined in a files group with the 'tags' attribute as a comma separated list, and with the 'tag' attribute on a compiler 'flag' node. Files are then compiled with all the flags that have matching tags.
By restricting tags to certain files, only a sub-set of files needs to be recompiled when conditions change, and files without the relevant tags can reuse their object files. This can save a lot of time, since some flags only apply to a few files.
Files can override the group tags by specifying their own 'tags' attribute. Groups can add tags with the 'tag' node.
Some tags have standard meanings when compiling haxe code:
- *haxe* - The haxe tag adds all the required compiler flags to get haxe-generated code to compile correctly, and should be added to files that depend directly or indirectly on hxcpp.h.
- *static* - This will add the STATIC_LINK define when appropriate, which is used for generating cffi glue. It should be added to cffi code that might generate static libraries.
- *gc* - These flags only affect the garbage-collection files
- *hxstring* - These flags only affect String.cpp
- *optimization tags* - each file is assumed to have exactly 1 optimization tags. If none is explicitly specified, then the default is used depending on whether it is a debug or release build. They are:
+ optim-std = alias for 'debug' or 'release' depending on build
+ debug
+ release
+ optim-none
+ optim-size
Setting one of these tags is useful for compiling your library in release mode, even if haxe has -debug. Some very big files are slow to compile in release mode, so using a less optimized mode can be faster.
The tags attribute can be added to a haxe-generated file using the `@:fileXml` meta, eg:
```haxe
@:fileXml("tags='haxe,optim-none'")
class MyClass { ...
```
Here, the class is compiled with the normal haxe flags, but has the optimizations disabled, which can lead to much faster compiler times in some circumstances.

View File

@ -0,0 +1,82 @@
Targets
-------
Targets are used to produce binaries, or to group other targets. When compiling exes or dynamic libraries, they provide the additional link libraries.
By default, hxcpp will try to compile the 'default' target, so it is easiest to define this one - perhaps by simply adding a dependence on your other targets(s).
The target is defined with a 'toolid' attribute; exe, static_link or dll. This defines which linker is run, but many of the target entries will be the same even if the linker is changed.
Targets can contain the following nodes:
- *subTargetName* - Build another target before building this one.
```xml
<target id="subTargetName" />
```
- *merge* - Combine fields from another target. This is useful if you want a target to function as static library or dll when compiled in its own, but also allow it to be used as a list of object files if another target wants to link in the object files directly.
```xml
<merge id="otherTargetName" />
```
- *files* - Add a named group of compiled files to target.
```xml
<files id="filesId"/>
```
- *section* - Group items - usually sharing common condition
```xml
<section > </section>
```
- *lib* - Add a library to the link line.
```xml
<lib (name|hxbase|base)="libName" />
```
+ name = the complete name is specified
+ base = the name without compiler-specific extension (.a/.lib) is specified
+ hxbase = the name without extension and architecture (-v7/.iphoinesim) is specified
- *flag* - Add a single link flag.
```xml
<flag value="flag"/>
```
- *vflag* - Add a pair of link flags.
```xml
<vflag name="flag1" value="flag2"/>
```
- *depend* - Target depends on given filename.
```xml
<depend name="filename"/>
```
- *dir* - Add a directory to the targets directory list. These directories will get removed then the target is cleaned.
```xml
<dir name="tempPath"/>
```
- *outdir* - Directory for build results - including "copyFile" targets
```xml
<outdir name="path"/>
```
- *ext* - Extension for generated files.
```xml
<ext name=".ext"/>
```
+ ext = extension - should contain "."
- *builddir* - The directory from which the targets build commands are run, and therefore the
relative base for some filenames, and destination for some compiler generated temps.
```xml
<builddir name="path"/>
```
- *libpath* Add library search path to build command
```xml
<libpath name="directory"/>
```
+ name = directory. The particular linker will add the required flags

View File

@ -0,0 +1,139 @@
Structure of the top-level
---------------------------
The top-level nodes live inside an "xml" node, and can be:
- *set* - Set a "define", define being a general variable.
```xml
<set name="name" value="1" />
```
- *setenv* - Sets an hxcpp define and an environment variable for child processes.
```xml
<setenv name="name" value="1" />
```
- *unset* - Unset a define. if="name" will no longer be true
```xml
<unset name="name" />
```
- *setup* - Used internally to call custom setup code to find SDKs etc.
```xml
<setup name="androidNdk|blackberry|msvc|pdbserver|mingw|emscripten|nvcc" />
```
- *echo* - Print value to console. Good for debugging.
```xml
<echo value="text" />
```
- *error* - Print value to console and force error. Good for checking prerequisites.
```xml
<error value="error message" />
```
- *pleaseUpdateHxcppTool* - Used to tell people updating git version that they need to recompile the build tool.
```xml
<pleaseUpdateHxcppTool version="1" />
```
- *path* - Add an directory to the exe search path.
```xml
<path name="directory_to_add" />
```
- *mkdir* - Create a directory.
```xml
<mkdir name="directory" />
```
- *section* - Groups block of elements - usually ones that all respect the same if/unless condition.
```xml
<section name="id" /> </section>
```
- *copy* - Copy file when node is parsed.
```xml
<copy to="destination" from="src" />
```
- *import*/*include* - Read xml from another file. 'import' resets the relative base to the new file, include does not.
```xml
<import name="filename" section="filter" noerror="true" />
<include name="filename" section="filter" noerror="true" />
```
+ noerror - setting the optional noerror allows the file to be missing
+ section - setting the optional section will only read the named section from the xml file. Used by hxcpp_config.xml.
- *pragma* - Only include build file once, even with multiple include statements.
```xml
<pragma once="true" />
```
- *nvccflag* - Add flag to all nvcc compiles.
```xml
<nvccflag name="?name" value="-IincludePath" />
```
- *nvcclinkflag* - Add flag when linking with nvcc code.
```xml
<nvcclinkflag name="?name" value="-arch=sm_30" />
```
- *files* - Define a file group, and set default tags.
```xml
<files dir="dir" name="name" tags="tag1,tag2,tag3" >
...
</files>
```
+ dir = directory to which the filenames in the group are relative
+ tags = comma separated list of flags tags
- *target* - Define a target, and set its toolid(link mode) and output name.
```xml
<target name="name" overwrite="true" append="true" tool="linker" toolid="${haxelink}" output="filename" >
...
</target>
```
- *copyFile* - Copy a file after given toolId is run into target output directory
```xml
<copyFile name="destination" from="src" allowMissing="true" overwrite="true" toolId="filter" >
```
- *magiclib* - Internal for replacing dlls with object files
```xml
<magiclib name="libname" replace="old dll" />
```
- *compiler* - Define a compiler.
```xml
<compiler id="id" exe="command" replace="true" >
...
</compiler>
```
+ Use optional 'replace' to overwrite, otherwise append
+ It is assumed only 1 compiler is active
+ exe can be overridden in the body of the definition
- *stripper* - Define a stripper, to remove debug information for release from gcc executables
```xml
<stripper exe="command" replace="true" > </stripper>
```
+ Use optional 'replace' to overwrite, otherwise append
- *linker* - Define a linker.
```xml
<linker id="id" exe="command" replace="true" > </linker>
```
+ Use optional 'replace' to overwrite, otherwise append
+ id could be 'static_link', 'dll' or 'exe'. Usually all 3 linkers are defined.
+ exe can be overridden in the body of the definition
- *prelinker* - Define a prelinker.
```xml
<prelinker name="id" replace="true" />
...
</prelinker>
```

View File

@ -0,0 +1,23 @@
Xml Injection
-------------
When using external code in hxcpp, it is often useful to add libraries, include paths or compiler flags to the build process. This can be done with the `@:buildXml` class meta-data. eg,
```haxe
@:buildXml("
<target id='haxe'>
<lib name='${haxelib:nme}/lib/${BINDIR}/libnme${LIBEXTRA}${LIBEXT}'/>
</target>
")
@:keep
class StaticNme
{
...
```
So, by referencing a given class (you just 'import' the class, no need to use it because it has the @:keep meta-data), the xml fragment is also included.
Here, the xml fragment is copied verbatim into the generated Build.xml immediately after the standard file lists. This example adds a library to the haxe target, but you could also add flags to files nodes, or files to another files node or target. Another possibility is to add an include command to pull in a whole external xml file. This can help avoid some syntax awkwardness needed when quoting strings in meta-data, and allows a normal xml editor to be used.
It is also possible to replace the `__main__` file group to skip the standard initialization code and use a custom bootstrap procedure.

View File

@ -0,0 +1,6 @@
<xml>
<echo value="Hello ${WHO}" if="WHO" unless="SILENT" />
<echo value="You are in ${haxelib:hxcpp}" unless="WHO||SILENT"/>
<error value="Silent and who both specified" if="WHO SILENT"/>
<target id="default" />
</xml>