diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..50361afbf6
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+docs/changelog.txt merge=union
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000000..2367db6786
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,6 @@
+Thank you for your interest in contributing to DFHack! If you're reading this
+document, you're probably viewing it on GitHub. The DFHack docs are hosted
+on [ReadTheDocs](https://dfhack.readthedocs.io/) - in particular, contributing
+guidelines are [here](https://docs.dfhack.org/en/latest/docs/Contributing.html).
+Double-checking the style guidelines before submitting a pull request is
+always appreciated.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..e68a754c63
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1 @@
+If this PR makes an externally-visible change in behavior or API, please add an appropriate line to `docs/changelog.txt`.
diff --git a/.github/release_template.md b/.github/release_template.md
new file mode 100644
index 0000000000..2bfc7a3c04
--- /dev/null
+++ b/.github/release_template.md
@@ -0,0 +1,64 @@
+#### Q: How do I download DFHack?
+**A:** Either add to your Steam library from our [Steam page](https://store.steampowered.com/app/2346660/DFHack) or scroll to the latest release on our [GitHub releases page](https://github.com/DFHack/dfhack/releases), expand the "Assets" list, and download the file for your platform (e.g. `dfhack-XX.XX-rX-Windows-64bit.zip`. If you are on Windows and are manually installing from the zip file, please remember to right click on the file after downloading, open the file properties, and select the "Unblock" checkbox. This will prevent issues with Windows antivirus programs.
+
+-------------
+
+This release is compatible with all distributions of Dwarf Fortress: [Steam](https://store.steampowered.com/app/975370/Dwarf_Fortress/), [Itch](https://kitfoxgames.itch.io/dwarf-fortress), and [Classic](https://www.bay12games.com/dwarves/).
+
+- [Install DFHack from Steam](https://store.steampowered.com/app/2346660/DFHack)
+- [Manual install](https://docs.dfhack.org/en/stable/docs/Installing.html#installing)
+- [Quickstart guide (for players)](https://docs.dfhack.org/en/stable/docs/Quickstart.html#quickstart)
+- [Modding guide (for modders)](https://docs.dfhack.org/en/stable/docs/guides/modding-guide.html)
+
+Please report any issues (or feature requests) on the DFHack [GitHub issue tracker](https://github.com/DFHack/dfhack/issues). When reporting issues, please upload a zip file of your savegame and a zip file of your `mods` directory to the cloud and add links to the GitHub issue. Make sure your files are downloadable by "everyone with the link". We need your savegame to reproduce the problem and test the fix, and we need your active mods so we can load your savegame. Issues with savegames and mods attached get fixed first!
+
+Highlights
+----------------------------------
+
+
+Highlight 1, Highlight 2
+
+### Highlight 1
+
+Demo screenshot/vidcap
+
+Text
+
+### Highlight 2
+
+Demo screenshot/vidcap
+
+Text
+
+
+
+Announcements
+----------------------------------
+
+
+Annc 1, PSAs
+
+### Annc 1
+
+Text
+
+### PSAs
+
+As always, remember that, just like the vanilla DF game, DFHack tools can also have bugs. It is a good idea to **save often and keep backups** of the forts that you care about.
+
+Some DFHack tools that worked in previous (pre-Steam) versions of DF have not been updated yet and are marked with the "unavailable" tag in their docs. If you try to run them, they will show a warning and exit immediately. You can run the command again to override the warning (though of course the tools may not work). We make no guarantees of reliability for the tools that are marked as "unavailable".
+
+The in-game interface for running DFHack commands (`gui/launcher`) will not show "unavailable" tools by default. You can still run them if you know their names, or you can turn on dev mode by hitting Ctrl-D while in `gui/launcher` and they will be added to the autocomplete list. Some tools listed as "unavailable" in the docs do not compile yet and are not accessible at all, even when in dev mode.
+
+If you see a tool complaining about the lack of a cursor, know that it's referring to the **keyboard** cursor (which used to be the only real option in Dwarf Fortress). You can enable the keyboard cursor by entering mining mode or selecting the dump/forbid tool and hitting Alt-K (the DFHack keybinding for `toggle-kbd-cursor`). We're working on making DFHack tools more mouse-aware and accessible so this step isn't necessary in the future.
+
+
+
+Changelog
+====================
+
+
+New tools, fixes, and improvements
+
+%RELEASE_NOTES%
+
diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml
new file mode 100644
index 0000000000..c2d946e300
--- /dev/null
+++ b/.github/workflows/build-linux.yml
@@ -0,0 +1,205 @@
+name: Build linux64
+
+on:
+ workflow_call:
+ inputs:
+ dfhack_repo:
+ type: string
+ default: DFHack/dfhack
+ dfhack_ref:
+ type: string
+ scripts_repo:
+ type: string
+ default: DFHack/scripts
+ scripts_ref:
+ type: string
+ structures_repo:
+ type: string
+ default: DFHack/df-structures
+ structures_ref:
+ type: string
+ stonesense_repo:
+ type: string
+ default: DFHack/stonesense
+ stonesense_ref:
+ type: string
+ artifact-name:
+ type: string
+ append-date-and-hash:
+ type: boolean
+ default: false
+ cache-id:
+ type: string
+ default: ''
+ cache-readonly:
+ type: boolean
+ default: false
+ platform-files:
+ type: boolean
+ default: true
+ plugins:
+ type: boolean
+ default: true
+ common-files:
+ type: boolean
+ default: true
+ docs:
+ type: boolean
+ default: false
+ html:
+ type: boolean
+ default: true
+ stonesense:
+ type: boolean
+ default: false
+ launchdf:
+ type: boolean
+ default: false
+ extras:
+ type: boolean
+ default: false
+ tests:
+ type: boolean
+ default: false
+ xml-dump-type-sizes:
+ type: boolean
+ default: false
+ gcc-ver:
+ type: string
+ default: "11"
+
+jobs:
+ build-linux64:
+ name: Build linux64
+ runs-on: ubuntu-22.04
+ steps:
+ - name: Install basic build dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install ninja-build
+ - name: Install binary build dependencies
+ if: inputs.platform-files || inputs.xml-dump-type-sizes
+ run: |
+ sudo apt-get install \
+ ccache \
+ gcc-${{ inputs.gcc-ver }} \
+ g++-${{ inputs.gcc-ver }} \
+ libxml-libxslt-perl
+ - name: Install stonesense dependencies
+ if: inputs.stonesense
+ run: sudo apt-get install libgl-dev
+ - name: Install doc dependencies
+ if: inputs.docs
+ run: pip install 'sphinx'
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.dfhack_repo }}
+ ref: ${{ inputs.dfhack_ref }}
+ submodules: true
+ fetch-depth: ${{ !inputs.platform-files && 1 || 0 }}
+ - name: Clone scripts
+ if: inputs.scripts_ref
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.scripts_repo }}
+ ref: ${{ inputs.scripts_ref }}
+ path: scripts
+ - name: Clone structures
+ if: inputs.structures_ref
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.structures_repo }}
+ ref: ${{ inputs.structures_ref }}
+ path: library/xml
+ - name: Clone stonesense
+ if: inputs.stonesense_ref
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.stonesense_repo }}
+ ref: ${{ inputs.stonesense_ref }}
+ path: plugins/stonesense
+ - name: Get 3rd party SDKs
+ if: inputs.launchdf
+ uses: actions/checkout@v4
+ with:
+ repository: DFHack/3rdparty
+ ref: main
+ ssh-key: ${{ secrets.DFHACK_3RDPARTY_TOKEN }}
+ path: depends/steam
+ - name: Fetch ccache
+ if: inputs.platform-files
+ uses: actions/cache/restore@v4
+ with:
+ path: ~/.cache/ccache
+ key: linux-gcc-${{ inputs.gcc-ver }}-${{ inputs.cache-id }}-${{ github.sha }}
+ restore-keys: |
+ linux-gcc-${{ inputs.gcc-ver }}-${{ inputs.cache-id }}
+ linux-gcc-${{ inputs.gcc-ver }}
+ - name: Configure DFHack
+ env:
+ CC: gcc-${{ inputs.gcc-ver }}
+ CXX: g++-${{ inputs.gcc-ver }}
+ run: |
+ cmake \
+ -S . \
+ -B build \
+ -G Ninja \
+ -DCMAKE_INSTALL_PREFIX=build/image \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DDFHACK_RUN_URL='https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' \
+ ${{ inputs.platform-files && '-DCMAKE_C_COMPILER_LAUNCHER=ccache' || '' }} \
+ ${{ inputs.platform-files && '-DCMAKE_CXX_COMPILER_LAUNCHER=ccache' || '' }} \
+ -DBUILD_LIBRARY:BOOL=${{ inputs.platform-files }} \
+ -DBUILD_PLUGINS:BOOL=${{ inputs.platform-files && inputs.plugins }} \
+ -DBUILD_STONESENSE:BOOL=${{ inputs.stonesense }} \
+ -DBUILD_DFLAUNCH:BOOL=${{ inputs.launchdf }} \
+ -DBUILD_DEV_PLUGINS:BOOL=${{ inputs.extras }} \
+ -DBUILD_SIZECHECK:BOOL=${{ inputs.extras }} \
+ -DBUILD_SKELETON:BOOL=${{ inputs.extras }} \
+ -DBUILD_DOCS:BOOL=${{ inputs.docs }} \
+ -DBUILD_DOCS_NO_HTML:BOOL=${{ !inputs.html }} \
+ -DBUILD_TESTS:BOOL=${{ inputs.tests }} \
+ -DBUILD_XMLDUMP:BOOL=${{ inputs.xml-dump-type-sizes }} \
+ ${{ inputs.xml-dump-type-sizes && '-DINSTALL_XMLDUMP:BOOL=1' || ''}} \
+ -DINSTALL_DATA_FILES:BOOL=${{ inputs.common-files }} \
+ -DINSTALL_SCRIPTS:BOOL=${{ inputs.common-files }}
+ - name: Build DFHack
+ run: ninja -C build install
+ - name: Run cpp tests
+ if: inputs.platform-files
+ run: ninja -C build test
+ - name: Finalize ccache
+ if: inputs.platform-files
+ run: |
+ ccache --show-stats --verbose
+ ccache --max-size 40M
+ ccache --cleanup
+ ccache --max-size 500M
+ ccache --zero-stats
+ - name: Save ccache
+ if: inputs.platform-files && !inputs.cache-readonly
+ uses: actions/cache/save@v4
+ with:
+ path: ~/.cache/ccache
+ key: linux-gcc-${{ inputs.gcc-ver }}-${{ inputs.cache-id }}-${{ github.sha }}
+ - name: Format artifact name
+ if: inputs.artifact-name
+ id: artifactname
+ run: |
+ if test "false" = "${{ inputs.append-date-and-hash }}"; then
+ echo name=${{ inputs.artifact-name }} >> $GITHUB_OUTPUT
+ else
+ echo name=${{ inputs.artifact-name }}-$(date +%Y%m%d)-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
+ fi
+ - name: Prep artifact
+ if: inputs.artifact-name
+ run: |
+ cd build/image
+ tar cjf ../../${{ steps.artifactname.outputs.name }}.tar.bz2 .
+ - name: Upload artifact
+ if: inputs.artifact-name
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ steps.artifactname.outputs.name }}
+ path: ${{ steps.artifactname.outputs.name }}.tar.bz2
diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml
new file mode 100644
index 0000000000..1dec211117
--- /dev/null
+++ b/.github/workflows/build-windows.yml
@@ -0,0 +1,206 @@
+name: Build win64
+
+on:
+ workflow_call:
+ inputs:
+ dfhack_repo:
+ type: string
+ default: DFHack/dfhack
+ dfhack_ref:
+ type: string
+ scripts_repo:
+ type: string
+ default: DFHack/scripts
+ scripts_ref:
+ type: string
+ structures_repo:
+ type: string
+ default: DFHack/df-structures
+ structures_ref:
+ type: string
+ stonesense_repo:
+ type: string
+ default: DFHack/stonesense
+ stonesense_ref:
+ type: string
+ artifact-name:
+ type: string
+ append-date-and-hash:
+ type: boolean
+ default: false
+ cache-id:
+ type: string
+ default: ''
+ cache-readonly:
+ type: boolean
+ default: false
+ platform-files:
+ type: boolean
+ default: true
+ plugins:
+ type: boolean
+ default: true
+ common-files:
+ type: boolean
+ default: true
+ docs:
+ type: boolean
+ default: false
+ html:
+ type: boolean
+ default: true
+ stonesense:
+ type: boolean
+ default: false
+ tests:
+ type: boolean
+ default: false
+ xml-dump-type-sizes:
+ type: boolean
+ default: false
+ launchdf:
+ type: boolean
+ default: false
+
+
+jobs:
+ build-win64:
+ name: Build win64
+ runs-on: windows-2022
+ steps:
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '3.x'
+ - name: Install build dependencies
+ run: |
+ choco install sccache
+ pip install Jinja2
+ - name: Install doc dependencies
+ if: inputs.docs
+ run: |
+ pip install sphinx
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.dfhack_repo }}
+ ref: ${{ inputs.dfhack_ref }}
+ submodules: true
+ fetch-depth: 0
+ - name: Clone scripts
+ if: inputs.scripts_ref
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.scripts_repo }}
+ ref: ${{ inputs.scripts_ref }}
+ path: scripts
+ - name: Clone structures
+ if: inputs.structures_ref
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.structures_repo }}
+ ref: ${{ inputs.structures_ref }}
+ path: library/xml
+ - name: Clone stonesense
+ if: inputs.stonesense_ref
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.stonesense_repo }}
+ ref: ${{ inputs.stonesense_ref }}
+ path: plugins/stonesense
+ - name: Get 3rd party SDKs
+ if: inputs.launchdf
+ uses: actions/checkout@v4
+ with:
+ repository: DFHack/3rdparty
+ ref: main
+ ssh-key: ${{ secrets.DFHACK_3RDPARTY_TOKEN }}
+ path: depends/steam
+ - name: Prepare output directories
+ run: |
+ mkdir output
+ mkdir pdb
+ - name: Get sccache path
+ run: echo ("SCCACHE_DIR=" + $env:LOCALAPPDATA + "\Mozilla\sccache\cache") >> $env:GITHUB_ENV
+ - name: Fetch ccache
+ if: inputs.platform-files
+ uses: actions/cache/restore@v4
+ with:
+ path: ${{ env.SCCACHE_DIR }}
+ key: win-msvc-${{ inputs.cache-id }}-${{ github.sha }}
+ restore-keys: |
+ win-msvc-${{ inputs.cache-id }}
+ win-msvc
+ - uses: ilammy/msvc-dev-cmd@v1
+ - name: Configure DFHack
+ run: |
+ cmake `
+ -S . `
+ -B build `
+ -GNinja `
+ -DDFHACK_BUILD_ARCH=64 `
+ -DCMAKE_BUILD_TYPE=Release `
+ -DCMAKE_INSTALL_PREFIX=output `
+ -DCMAKE_C_COMPILER_LAUNCHER=sccache `
+ -DCMAKE_CXX_COMPILER_LAUNCHER=sccache `
+ -DBUILD_PDBS:BOOL=${{ inputs.cache-id == 'release' }} `
+ -DDFHACK_RUN_URL='https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' `
+ -DBUILD_LIBRARY=${{ inputs.platform-files }} `
+ -DBUILD_PLUGINS:BOOL=${{ inputs.platform-files && inputs.plugins }} `
+ -DBUILD_STONESENSE:BOOL=${{ inputs.stonesense }} `
+ -DBUILD_DOCS:BOOL=${{ inputs.docs }} `
+ -DBUILD_DOCS_NO_HTML:BOOL=${{ !inputs.html }} `
+ -DINSTALL_DATA_FILES:BOOL=${{ inputs.common-files }} `
+ -DBUILD_DFLAUNCH:BOOL=${{ inputs.launchdf }} `
+ -DBUILD_TESTS:BOOL=${{ inputs.tests }} `
+ -DBUILD_XMLDUMP:BOOL=${{ inputs.xml-dump-type-sizes }} `
+ ${{ inputs.xml-dump-type-sizes && '-DINSTALL_XMLDUMP:BOOL=1' || '' }}
+ - name: Build DFHack
+ env:
+ SCCACHE_CACHE_SIZE: 500M
+ run: |
+ ninja install -C build
+ - name: Finalize cache
+ run: |
+ cd build
+ sccache --show-stats
+ sccache --zero-stats
+ - name: Save ccache
+ if: inputs.platform-files && !inputs.cache-readonly
+ uses: actions/cache/save@v4
+ with:
+ path: ${{ env.SCCACHE_DIR }}
+ key: win-msvc-${{ inputs.cache-id }}-${{ github.sha }}
+ - name: Format artifact name
+ if: inputs.artifact-name
+ id: artifactname
+ run: |
+ if ("${{ inputs.append-date-and-hash }}" -eq "false") {
+ "name=${{ inputs.artifact-name }}" | Out-File -Append $env:GITHUB_OUTPUT
+ } else {
+ $date = Get-Date -Format "yyyMMdd"
+ $hash = git rev-parse --short HEAD
+ "name=${{ inputs.artifact-name}}-$date-$hash" | Out-File -Append $env:GITHUB_OUTPUT
+ }
+ - name: Prep pdbs
+ if: inputs.artifact-name && inputs.cache-id == 'release'
+ run: |
+ Get-ChildItem -Recurse -File -Path "build" -Filter *.pdb |
+ Copy-Item -Destination "pdb"
+ - name: Prep artifact
+ run: |
+ cd output
+ 7z a -ttar -so -an . |
+ 7z a -si -tbzip2 ../${{ steps.artifactname.outputs.name }}.tar.bz2
+ - name: Upload artifact
+ if: inputs.artifact-name
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ steps.artifactname.outputs.name }}
+ path: ${{ steps.artifactname.outputs.name }}.tar.bz2
+ - name: Upload PDBs
+ if: inputs.artifact-name && inputs.cache-id == 'release'
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ steps.artifactname.outputs.name }}_pdb
+ path: pdb
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000000..3767b42ba5
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,46 @@
+name: Build
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ uses: ./.github/workflows/test.yml
+ with:
+ dfhack_repo: ${{ github.repository }}
+ dfhack_ref: ${{ github.ref }}
+ secrets: inherit
+
+ package:
+ uses: ./.github/workflows/package.yml
+ with:
+ dfhack_repo: ${{ github.repository }}
+ dfhack_ref: ${{ github.ref }}
+ secrets: inherit
+
+ docs:
+ uses: ./.github/workflows/build-linux.yml
+ with:
+ dfhack_repo: ${{ github.repository }}
+ dfhack_ref: ${{ github.ref }}
+ platform-files: false
+ common-files: false
+ docs: true
+ secrets: inherit
+
+ lint:
+ uses: ./.github/workflows/lint.yml
+ with:
+ dfhack_repo: ${{ github.repository }}
+ dfhack_ref: ${{ github.ref }}
+ secrets: inherit
+
+ check-pr:
+ runs-on: ubuntu-latest
+ if: github.event_name == 'pull_request'
+ steps:
+ - name: Check that PR is based on develop branch
+ env:
+ BASE_BRANCH: ${{ github.base_ref }}
+ run: |
+ echo "PR base branch: $BASE_BRANCH"
+ test "$BASE_BRANCH" = develop
diff --git a/.github/workflows/clean-cache.yml b/.github/workflows/clean-cache.yml
new file mode 100644
index 0000000000..91d5675ad8
--- /dev/null
+++ b/.github/workflows/clean-cache.yml
@@ -0,0 +1,32 @@
+name: Clean up PR caches
+
+on:
+ workflow_call:
+ pull_request_target:
+ types:
+ - closed
+
+jobs:
+ cleanup:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v4
+ - name: Cleanup
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ gh extension install actions/gh-actions-cache
+
+ REPO=${{ github.repository }}
+ BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge"
+
+ echo "Fetching list of cache keys"
+ cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH -L 100 | cut -f 1)
+
+ set +e
+ echo "Deleting caches..."
+ for cacheKey in $cacheKeysForPR; do
+ gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
+ done
+ echo "Done"
diff --git a/.github/workflows/generate-symbols.yml b/.github/workflows/generate-symbols.yml
new file mode 100644
index 0000000000..f78da19e74
--- /dev/null
+++ b/.github/workflows/generate-symbols.yml
@@ -0,0 +1,421 @@
+name: Generate symbols
+
+on:
+ workflow_dispatch:
+ inputs:
+ structures_ref:
+ description: Structures branch to build from and update
+ required: true
+ default: master
+ version:
+ description: DF version (can be "auto" if channel is steam)
+ required: true
+ platform:
+ description: Target OS platform
+ type: choice
+ required: true
+ default: all
+ options:
+ - all
+ - windows
+ - linux
+ channel:
+ description: DF distribution channel
+ type: choice
+ required: true
+ default: all
+ options:
+ - all
+ - steam
+ - itch
+ - classic
+ df_steam_branch:
+ description: DF Steam branch to read from (if processing Steam distribution channel)
+ required: true
+ type: choice
+ default: default
+ options:
+ - default
+ - experimental
+ - testing
+ - adventure_test
+ - beta
+ steam_branch:
+ description: DFHack Steam branch to deploy to (leave blank to skip deploy)
+ type: string
+
+jobs:
+ package-linux:
+ uses: ./.github/workflows/build-linux.yml
+ if: inputs.platform == 'all' || inputs.platform == 'linux'
+ with:
+ dfhack_ref: ${{ github.ref }}
+ structures_ref: ${{ inputs.structures_ref }}
+ artifact-name: dfhack-symbols-linux64-build
+ append-date-and-hash: false
+ cache-id: test
+ cache-readonly: true
+ plugins: false
+ secrets: inherit
+
+ package-win64:
+ uses: ./.github/workflows/build-windows.yml
+ if: (inputs.platform == 'all' || inputs.platform == 'windows') && inputs.version == 'auto'
+ with:
+ dfhack_ref: ${{ github.ref }}
+ structures_ref: ${{ inputs.structures_ref }}
+ artifact-name: dfhack-symbols-windows64-build
+ append-date-and-hash: false
+ cache-id: test
+ cache-readonly: true
+ plugins: false
+ secrets: inherit
+
+ generate-linux:
+ name: Generate linux64 symbols
+ runs-on: ubuntu-latest
+ if: inputs.platform == 'all' || inputs.platform == 'linux'
+ needs:
+ - package-linux
+ steps:
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install \
+ ansifilter \
+ libsdl2-2.0-0 \
+ libsdl2-image-2.0-0
+ - name: Clone structures
+ uses: actions/checkout@v4
+ with:
+ repository: DFHack/df-structures
+ ref: ${{ inputs.structures_ref }}
+ token: ${{ secrets.DFHACK_GITHUB_TOKEN }}
+ path: xml
+ - name: Download DFHack
+ uses: actions/download-artifact@v4
+ with:
+ name: dfhack-symbols-linux64-build
+ - name: Start X server
+ run: Xvfb :0 -screen 0 1600x1200x24 &
+
+ # Steam
+ - name: Setup steamcmd
+ if: inputs.channel == 'all' || inputs.channel == 'steam'
+ id: steamcmd
+ uses: CyberAndrii/setup-steamcmd@v1
+ - name: Generate Steam symbols
+ if: inputs.channel == 'all' || inputs.channel == 'steam'
+ env:
+ DISPLAY: :0
+ STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
+ STEAM_CONFIG_VDF: ${{ secrets.STEAM_CONFIG_VDF }}
+ STEAM_DF_TESTING: ${{ secrets.STEAM_DF_TESTING }}
+ STEAM_DF_ADVENTURE_TEST: ${{ secrets.STEAM_DF_ADVENTURE_TEST }}
+ run: |
+ mkdir DF_steam
+ mkdir -p $HOME/Steam/config
+ echo "$STEAM_CONFIG_VDF" | base64 -d >$HOME/Steam/config/config.vdf
+ echo "DF steam branch: ${{ inputs.df_steam_branch }}"
+ if [ "${{ inputs.df_steam_branch }}" = "default" ]; then
+ BETA_PARAMS=""
+ elif [ "${{ inputs.df_steam_branch }}" = "testing" ]; then
+ BETA_PARAMS="-beta testing -betapassword $STEAM_DF_TESTING"
+ elif [ "${{ inputs.df_steam_branch }}" = "adventure_test" ]; then
+ BETA_PARAMS="-beta adventure_test -betapassword $STEAM_DF_ADVENTURE_TEST"
+ else
+ BETA_PARAMS="-beta ${{ inputs.df_steam_branch }}"
+ fi
+ ${{ steps.steamcmd.outputs.executable }} \
+ +@ShutdownOnFailedCommand 1 \
+ +force_install_dir $PWD/DF_steam \
+ +login $STEAM_USERNAME \
+ "+app_update 975370 $BETA_PARAMS validate" \
+ +quit
+ tar xjf dfhack-symbols-linux64-build.tar.bz2 -C DF_steam
+ xml/symbols_gen_linux.sh ${{ inputs.version == 'auto' && '50.0' || inputs.version }} STEAM DF_steam
+ if [ "${{ inputs.version }}" == "auto" ]; then
+ while pgrep dwarfort; do
+ echo "waiting for DF to exit"
+ sleep 0.5
+ done
+ cp xml/symbols.xml DF_steam/hack
+ cd DF_steam
+ DFHACK_DISABLE_CONSOLE=1 ./dfhack &
+ while ! ./dfhack-run lua 'print(scr)' | fgrep 'viewscreen_titlest' 2>/dev/null; do
+ echo "waiting for DF to start"
+ sleep 0.5
+ done
+ df_ver=`./dfhack-run lua 'print(dfhack.gui.getDFViewscreen(true).str_version)' | ansifilter`
+ echo "Found version string: '$df_ver'"
+ echo "DETECTED_DF_VER=$df_ver" >>$GITHUB_ENV
+ sed -i "s/v0.50.0 linux64 STEAM/v0.$df_ver linux64 STEAM/" ../xml/symbols.xml
+ ./dfhack-run die || true
+ fi
+
+ # Itch
+ - name: Generate Itch symbols
+ if: (inputs.channel == 'all' || inputs.channel == 'itch') && inputs.version != 'auto'
+ env:
+ DISPLAY: :0
+ ITCH_API_KEY: ${{ secrets.ITCH_API_KEY }}
+ run: |
+ mkdir DF_itch
+ pip install itch-dl
+ minor=$(echo "${{ inputs.version }}" | cut -d. -f1)
+ patch=$(echo "${{ inputs.version }}" | cut -d. -f2)
+ fname="dwarf_fortress_${minor}_${patch}_linux.tar.bz2"
+ itch-dl https://kitfoxgames.itch.io/dwarf-fortress --download-to . --api-key $ITCH_API_KEY --filter-files-glob "${fname}"
+ tar xjf "kitfoxgames/dwarf-fortress/files/${fname}" -C DF_itch
+ tar xjf dfhack-symbols-linux64-build.tar.bz2 -C DF_itch
+ xml/symbols_gen_linux.sh ${{ inputs.version }} ITCH DF_itch
+
+ # Classic
+ - name: Generate Classic symbols
+ if: (inputs.channel == 'all' || inputs.channel == 'classic') && inputs.version != 'auto'
+ env:
+ DISPLAY: :0
+ run: |
+ mkdir DF_classic
+ minor=$(echo "${{ inputs.version }}" | cut -d. -f1)
+ patch=$(echo "${{ inputs.version }}" | cut -d. -f2)
+ fname="df_${minor}_${patch}_linux.tar.bz2"
+ wget "https://www.bay12games.com/dwarves/${fname}"
+ tar xjf "${fname}" -C DF_classic
+ tar xjf dfhack-symbols-linux64-build.tar.bz2 -C DF_classic
+ xml/symbols_gen_linux.sh ${{ inputs.version }} CLASSIC DF_classic
+
+ # Finalize
+ - name: Merge updates
+ run: |
+ cd xml
+ if ! git diff --exit-code; then
+ git stash
+ git pull
+ git stash pop
+ fi
+ - name: Commit symbol updates
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: Auto-update symbols for Linux DF version ${{ env.DETECTED_DF_VER || inputs.version }}
+ repository: xml
+ commit_user_name: DFHack-Urist via GitHub Actions
+ commit_user_email: 63161697+DFHack-Urist@users.noreply.github.com
+
+ generate-windows:
+ name: Generate win64 symbols
+ runs-on: ubuntu-latest
+ if: inputs.platform == 'all' || inputs.platform == 'windows'
+ steps:
+ - name: Install dependencies
+ run: pip install pefile
+ - name: Clone structures
+ uses: actions/checkout@v4
+ with:
+ repository: DFHack/df-structures
+ ref: ${{ inputs.structures_ref }}
+ token: ${{ secrets.DFHACK_GITHUB_TOKEN }}
+ path: xml
+ - name: Clone df_misc
+ uses: actions/checkout@v4
+ with:
+ repository: DFHack/df_misc
+ path: df_misc
+ - name: Clone metasm
+ uses: actions/checkout@v4
+ with:
+ repository: jjyg/metasm
+ path: metasm
+
+ # Steam
+ - name: Setup steamcmd
+ if: inputs.channel == 'all' || inputs.channel == 'steam'
+ id: steamcmd
+ uses: CyberAndrii/setup-steamcmd@v1
+ - name: Generate Steam symbols
+ if: inputs.channel == 'all' || inputs.channel == 'steam'
+ env:
+ STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
+ STEAM_CONFIG_VDF: ${{ secrets.STEAM_CONFIG_VDF }}
+ STEAM_DF_TESTING: ${{ secrets.STEAM_DF_TESTING }}
+ STEAM_DF_ADVENTURE_TEST: ${{ secrets.STEAM_DF_ADVENTURE_TEST }}
+ run: |
+ mkdir DF_steam
+ mkdir -p $HOME/Steam/config
+ echo "$STEAM_CONFIG_VDF" | base64 -d >$HOME/Steam/config/config.vdf
+ echo "DF steam branch: ${{ inputs.df_steam_branch }}"
+ if [ "${{ inputs.df_steam_branch }}" = "default" ]; then
+ BETA_PARAMS=""
+ elif [ "${{ inputs.df_steam_branch }}" = "testing" ]; then
+ BETA_PARAMS="-beta testing -betapassword $STEAM_DF_TESTING"
+ elif [ "${{ inputs.df_steam_branch }}" = "adventure_test" ]; then
+ BETA_PARAMS="-beta adventure_test -betapassword $STEAM_DF_ADVENTURE_TEST"
+ else
+ BETA_PARAMS="-beta ${{ inputs.df_steam_branch }}"
+ fi
+ ${{ steps.steamcmd.outputs.executable }} \
+ +@ShutdownOnFailedCommand 1 \
+ +@sSteamCmdForcePlatformType windows \
+ +force_install_dir $PWD/DF_steam \
+ +login $STEAM_USERNAME \
+ "+app_update 975370 $BETA_PARAMS validate" \
+ +quit
+ xml/symbols_gen_windows.sh ${{ inputs.version == 'auto' && '50.0' || inputs.version }} STEAM DF_steam
+
+ # Itch
+ - name: Generate Itch symbols
+ if: (inputs.channel == 'all' || inputs.channel == 'itch') && inputs.version != 'auto'
+ env:
+ ITCH_API_KEY: ${{ secrets.ITCH_API_KEY }}
+ run: |
+ mkdir DF_itch
+ pip install itch-dl
+ minor=$(echo "${{ inputs.version }}" | cut -d. -f1)
+ patch=$(echo "${{ inputs.version }}" | cut -d. -f2)
+ fname="dwarf_fortress_${minor}_${patch}_windows.zip"
+ itch-dl https://kitfoxgames.itch.io/dwarf-fortress --download-to . --api-key $ITCH_API_KEY --filter-files-glob "${fname}"
+ unzip -d DF_itch "kitfoxgames/dwarf-fortress/files/${fname}"
+ xml/symbols_gen_windows.sh ${{ inputs.version }} ITCH DF_itch
+
+ # Classic
+ - name: Generate Classic symbols
+ if: (inputs.channel == 'all' || inputs.channel == 'classic') && inputs.version != 'auto'
+ run: |
+ mkdir DF_classic
+ minor=$(echo "${{ inputs.version }}" | cut -d. -f1)
+ patch=$(echo "${{ inputs.version }}" | cut -d. -f2)
+ fname="df_${minor}_${patch}_win.zip"
+ wget "https://www.bay12games.com/dwarves/${fname}"
+ unzip -d DF_classic "${fname}"
+ xml/symbols_gen_windows.sh ${{ inputs.version }} CLASSIC DF_classic
+
+ # Finalize
+ - name: Merge updates
+ run: |
+ cd xml
+ if ! git diff --exit-code; then
+ git stash
+ git pull
+ git stash pop
+ fi
+ - name: Commit symbol updates
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: Auto-update symbols for Windows DF version ${{ inputs.version }}
+ repository: xml
+ commit_user_name: DFHack-Urist via GitHub Actions
+ commit_user_email: 63161697+DFHack-Urist@users.noreply.github.com
+
+ auto-ver-windows:
+ name: Autodetect DF version string (Windows)
+ if: (inputs.platform == 'all' || inputs.platform == 'windows') && (inputs.channel == 'all' || inputs.channel == 'steam') && inputs.version == 'auto'
+ needs:
+ - package-win64
+ - generate-windows
+ runs-on: windows-latest
+ steps:
+ - name: Clone structures
+ uses: actions/checkout@v4
+ with:
+ repository: DFHack/df-structures
+ ref: ${{ inputs.structures_ref }}
+ token: ${{ secrets.DFHACK_GITHUB_TOKEN }}
+ path: xml
+ - name: Download DFHack
+ uses: actions/download-artifact@v4
+ with:
+ name: dfhack-symbols-windows64-build
+ - name: Setup steamcmd
+ id: steamcmd
+ uses: CyberAndrii/setup-steamcmd@v1
+ - name: Update DF version string
+ env:
+ STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
+ STEAM_CONFIG_VDF: ${{ secrets.STEAM_CONFIG_VDF }}
+ STEAM_DF_TESTING: ${{ secrets.STEAM_DF_TESTING }}
+ STEAM_DF_ADVENTURE_TEST: ${{ secrets.STEAM_DF_ADVENTURE_TEST }}
+ shell: bash
+ run: |
+ mkdir DF_steam
+ echo "$STEAM_CONFIG_VDF" | base64 -d >${{ steps.steamcmd.outputs.directory }}/config/config.vdf
+ echo "DF steam branch: ${{ inputs.df_steam_branch }}"
+ if [ "${{ inputs.df_steam_branch }}" = "default" ]; then
+ BETA_PARAMS=""
+ elif [ "${{ inputs.df_steam_branch }}" = "testing" ]; then
+ BETA_PARAMS="-beta testing -betapassword $STEAM_DF_TESTING"
+ elif [ "${{ inputs.df_steam_branch }}" = "adventure_test" ]; then
+ BETA_PARAMS="-beta adventure_test -betapassword $STEAM_DF_ADVENTURE_TEST"
+ else
+ BETA_PARAMS="-beta ${{ inputs.df_steam_branch }}"
+ fi
+ ${{ steps.steamcmd.outputs.executable }} \
+ +@ShutdownOnFailedCommand 1 \
+ +@sSteamCmdForcePlatformType windows \
+ +force_install_dir $PWD/DF_steam \
+ +login $STEAM_USERNAME \
+ "+app_update 975370 $BETA_PARAMS validate" \
+ +quit
+ tar xjf dfhack-symbols-windows64-build.tar.bz2 -C DF_steam
+ cp xml/symbols.xml DF_steam/hack
+ cd DF_steam
+ "./Dwarf Fortress.exe" &
+ while ! ./dfhack-run.exe lua 'print(scr)' | fgrep 'viewscreen_titlest' 2>/dev/null; do
+ echo "waiting for DF to start"
+ sleep 0.5
+ done
+ df_ver=`./dfhack-run.exe lua 'print(dfhack.gui.getDFViewscreen(true).str_version)'`
+ echo "Found version string: '$df_ver'"
+ echo "DETECTED_DF_VER=$df_ver" >>$GITHUB_ENV
+ sed -i "s/v0.50.0 win64 STEAM/v0.$df_ver win64 STEAM/" ../xml/symbols.xml
+ ./dfhack-run.exe die || true
+ - name: Merge updates
+ shell: bash
+ run: |
+ cd xml
+ if ! git diff --exit-code; then
+ git stash
+ git pull
+ git stash pop
+ fi
+ - name: Commit symbol updates
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: Auto-update Windows DF version to ${{ env.DETECTED_DF_VER }} in symbols
+ repository: xml
+ commit_user_name: DFHack-Urist via GitHub Actions
+ commit_user_email: 63161697+DFHack-Urist@users.noreply.github.com
+
+ update-ref:
+ name: Update structures ref
+ runs-on: ubuntu-latest
+ needs:
+ - generate-linux
+ - auto-ver-windows
+ if: ${{ ! failure() }}
+ steps:
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.DFHACK_GITHUB_TOKEN }}
+ - name: Update ref
+ shell: bash
+ run: |
+ git submodule update --init --no-single-branch library/xml
+ cd library/xml
+ git checkout ${{ inputs.structures_ref }}
+ git pull
+ df_ver=`grep -E 'symbol-table.*STEAM' symbols.xml | head -n1 | sed -r "s/.*name='v0.([^ ]+) .*/\1/"`
+ echo "using DF version: $df_ver"
+ echo "DETECTED_DF_VER=$df_ver" >>$GITHUB_ENV
+ - name: Commit ref update
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: Auto-update structures ref for ${{ env.DETECTED_DF_VER }}
+ commit_user_name: DFHack-Urist via GitHub Actions
+ commit_user_email: 63161697+DFHack-Urist@users.noreply.github.com
+ - name: Launch steam-deploy
+ if: inputs.steam_branch
+ shell: bash
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: gh workflow run steam-deploy.yml -R DFHack/dfhack -r ${{ github.ref }} -f version=${{ env.DETECTED_DF_VER }} -f steam_branch=${{ inputs.steam_branch }}
diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml
new file mode 100644
index 0000000000..16a4602141
--- /dev/null
+++ b/.github/workflows/github-release.yml
@@ -0,0 +1,81 @@
+name: Deploy to GitHub
+
+on:
+ push:
+ tags:
+ - '*-r*'
+
+ workflow_dispatch:
+ inputs:
+ ref:
+ description: Tag
+ required: true
+
+jobs:
+ package:
+ uses: ./.github/workflows/package.yml
+ with:
+ dfhack_ref: ${{ github.event.inputs && github.event.inputs.ref || github.event.ref }}
+ append-date-and-hash: false
+ cache-readonly: true
+ launchdf: true
+ secrets: inherit
+
+ create-update-release:
+ name: Draft GitHub release
+ needs: package
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Install doc dependencies
+ run: pip install 'sphinx'
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.inputs && github.event.inputs.ref || github.event.ref }}
+ submodules: true
+ - name: Get tag
+ id: gettag
+ run: |
+ TAG=$(git describe --tags --abbrev=0 --exact-match)
+ echo name="$TAG" >> $GITHUB_OUTPUT
+ echo type=$(echo "$TAG" | egrep 'r[0-9]+$' && echo "release" || echo "prerelease") >> $GITHUB_OUTPUT
+ - name: Generate release text
+ run: |
+ python docs/gen_changelog.py -a
+ CHANGELOG_FILE=docs/changelogs/${{ steps.gettag.outputs.name }}-github.txt
+ if ! test -f $CHANGELOG_FILE; then CHANGELOG_FILE=docs/changelogs/future-github.txt; fi
+ TOKEN_LINE=$(grep -Fhne '%RELEASE_NOTES%' .github/release_template.md | sed 's/:.*//')
+ head -n $((TOKEN_LINE - 1)) .github/release_template.md > release_body.md
+ CHANGELOG_LINES=$(wc -l <$CHANGELOG_FILE)
+ tail -n $((CHANGELOG_LINES - 3)) $CHANGELOG_FILE >> release_body.md
+ tail -n 1 .github/release_template.md >> release_body.md
+ cat release_body.md
+ - name: Stage release
+ uses: actions/download-artifact@v4
+ - name: Prep artifacts
+ run: |
+ mkdir artifacts
+ cd dfhack-windows64-build
+ tar xjf dfhack-windows64-build.tar.bz2
+ rm dfhack-windows64-build.tar.bz2
+ zip -qr ../artifacts/dfhack-${{ steps.gettag.outputs.name }}-Windows-64bit.zip .
+ cd ../dfhack-linux64-build
+ mv dfhack-linux64-build.tar.bz2 ../artifacts/dfhack-${{ steps.gettag.outputs.name }}-Linux-64bit.tar.bz2
+ - name: Create or update GitHub release
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: "artifacts/dfhack-*"
+ bodyFile: "release_body.md"
+ allowUpdates: true
+ artifactErrorsFailBuild: true
+ draft: true
+ name: "DFHack ${{ steps.gettag.outputs.name }}"
+ omitBodyDuringUpdate: true
+ omitDraftDuringUpdate: true
+ omitNameDuringUpdate: true
+ omitPrereleaseDuringUpdate: true
+ prerelease: ${{ steps.gettag.outputs.type == 'prerelease' }}
+ replacesArtifacts: true
+ tag: ${{ steps.gettag.outputs.name }}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000000..0b44747c01
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,50 @@
+name: Lint
+
+on:
+ workflow_call:
+ inputs:
+ dfhack_repo:
+ type: string
+ default: DFHack/dfhack
+ dfhack_ref:
+ type: string
+ scripts_repo:
+ type: string
+ default: DFHack/scripts
+ scripts_ref:
+ type: string
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install Lua
+ run: |
+ sudo apt-get update
+ sudo apt-get install lua5.3
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.dfhack_repo }}
+ ref: ${{ inputs.dfhack_ref }}
+ - name: Get scripts submodule ref
+ if: '!inputs.scripts_ref'
+ id: scriptssubmoduleref
+ run: echo ref=$(git submodule | fgrep scripts | cut -c2-41) >> $GITHUB_OUTPUT
+ - name: Clone scripts
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.scripts_repo }}
+ ref: ${{ inputs.scripts_ref || steps.scriptssubmoduleref.outputs.ref }}
+ path: scripts
+ - name: Check whitespace
+ run: python ci/lint.py --git-only --github-actions
+ - name: Check Authors.rst
+ if: always()
+ run: python ci/authors-rst.py
+ - name: Check for missing documentation
+ if: always()
+ run: python ci/script-docs.py
+ - name: Check Lua syntax
+ if: always()
+ run: python ci/script-syntax.py --ext=lua --cmd="luac5.3 -p" --github-actions
diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml
new file mode 100644
index 0000000000..41e72ea636
--- /dev/null
+++ b/.github/workflows/package.yml
@@ -0,0 +1,76 @@
+name: Package
+
+on:
+ workflow_call:
+ inputs:
+ dfhack_repo:
+ type: string
+ dfhack_ref:
+ type: string
+ scripts_repo:
+ type: string
+ scripts_ref:
+ type: string
+ structures_repo:
+ type: string
+ structures_ref:
+ type: string
+ append-date-and-hash:
+ type: boolean
+ default: true
+ cache-readonly:
+ type: boolean
+ default: false
+ launchdf:
+ type: boolean
+ default: false
+ include_windows:
+ type: boolean
+ default: true
+ include_linux:
+ type: boolean
+ default: true
+
+
+jobs:
+ package-win64:
+ name: Windows
+ uses: ./.github/workflows/build-windows.yml
+ if: inputs.include_windows
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ scripts_repo: ${{ inputs.scripts_repo }}
+ scripts_ref: ${{ inputs.scripts_ref }}
+ structures_repo: ${{ inputs.structures_repo }}
+ structures_ref: ${{ inputs.structures_ref }}
+ artifact-name: dfhack-windows64-build
+ append-date-and-hash: ${{ inputs.append-date-and-hash }}
+ cache-id: release
+ cache-readonly: ${{ inputs.cache-readonly }}
+ stonesense: true
+ docs: true
+ html: false
+ launchdf: ${{ inputs.launchdf }}
+ secrets: inherit
+
+ package-linux:
+ name: Linux
+ uses: ./.github/workflows/build-linux.yml
+ if: inputs.include_linux
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ scripts_repo: ${{ inputs.scripts_repo }}
+ scripts_ref: ${{ inputs.scripts_ref }}
+ structures_repo: ${{ inputs.structures_repo }}
+ structures_ref: ${{ inputs.structures_ref }}
+ artifact-name: dfhack-linux64-build
+ append-date-and-hash: ${{ inputs.append-date-and-hash }}
+ cache-id: release
+ cache-readonly: ${{ inputs.cache-readonly }}
+ stonesense: true
+ docs: true
+ html: false
+ launchdf: ${{ inputs.launchdf }}
+ secrets: inherit
diff --git a/.github/workflows/steam-deploy.yml b/.github/workflows/steam-deploy.yml
new file mode 100644
index 0000000000..2fbe6849e1
--- /dev/null
+++ b/.github/workflows/steam-deploy.yml
@@ -0,0 +1,96 @@
+name: Deploy to Steam
+
+on:
+ push:
+ tags:
+ - '*-r*'
+ workflow_dispatch:
+ inputs:
+ version:
+ description: Version or build description
+ type: string
+ required: true
+ steam_branch:
+ description: Steam release branch
+ type: string
+ required: true
+ default: staging
+
+jobs:
+ depot-common:
+ name: Common depot files
+ uses: ./.github/workflows/build-linux.yml
+ with:
+ artifact-name: common-depot
+ dfhack_ref: ${{ github.ref }}
+ platform-files: false
+ docs: true
+ html: false
+ stonesense: true
+ secrets: inherit
+
+ depot-win64:
+ name: Windows depot files
+ uses: ./.github/workflows/build-windows.yml
+ with:
+ artifact-name: win64-depot
+ dfhack_ref: ${{ github.ref }}
+ cache-id: release
+ cache-readonly: true
+ common-files: false
+ stonesense: true
+ launchdf: true
+ secrets: inherit
+
+ depot-linux64:
+ name: Linux depot files
+ uses: ./.github/workflows/build-linux.yml
+ with:
+ artifact-name: linux64-depot
+ dfhack_ref: ${{ github.ref }}
+ cache-id: release
+ cache-readonly: true
+ common-files: false
+ stonesense: true
+ launchdf: true
+ secrets: inherit
+
+ deploy-to-steam:
+ name: Deploy to Steam
+ needs:
+ - depot-common
+ - depot-win64
+ - depot-linux64
+ runs-on: ubuntu-latest
+ concurrency: steamdeploy
+ steps:
+ - name: Download depot files
+ uses: actions/download-artifact@v4
+ - name: Stage depot files
+ run: |
+ for name in common win64 linux64; do
+ cd ${name}-depot
+ tar xjf ${name}-depot.tar.bz2
+ rm ${name}-depot.tar.bz2
+ cd ..
+ done
+ - name: Get short SHA of commit
+ run: echo "SHORT_SHA=`echo ${{ github.sha }} | cut -c1-8`" >>$GITHUB_ENV
+ - name: steamcmd cache
+ uses: actions/cache@v4
+ with:
+ path: /home/runner/work/_temp/_github_home
+ key: steamcmd-${{ github.sha }}
+ restore-keys: steamcmd
+ - name: Steam deploy
+ uses: game-ci/steam-deploy@v3
+ with:
+ username: ${{ secrets.STEAM_USERNAME }}
+ configVdf: ${{ secrets.STEAM_CONFIG_VDF}}
+ appId: 2346660
+ buildDescription: ${{ github.event.inputs && github.event.inputs.version || github.ref_name }} (${{ env.SHORT_SHA }})
+ rootPath: .
+ depot1Path: common-depot
+ depot2Path: win64-depot
+ depot3Path: linux64-depot
+ releaseBranch: ${{ github.event.inputs && github.event.inputs.steam_branch || 'staging' }}
diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml
new file mode 100644
index 0000000000..3fbf683b63
--- /dev/null
+++ b/.github/workflows/test-suite.yml
@@ -0,0 +1,93 @@
+name: Test suite
+
+on:
+ workflow_call:
+ inputs:
+ dfhack_repo:
+ type: string
+ dfhack_ref:
+ type: string
+ os:
+ type: string
+ compiler:
+ type: string
+ plugins:
+ type: string
+ config:
+ type: string
+
+jobs:
+ run-tests:
+ name: Test (${{ inputs.os }}, ${{ inputs.compiler }}, ${{ inputs.plugins }} plugins, ${{ inputs.config }} config)
+ runs-on: ${{ inputs.os }}-latest
+ steps:
+ - name: Set env
+ shell: bash
+ run: echo "DF_FOLDER=DF" >>$GITHUB_ENV
+ - name: Install dependencies
+ if: inputs.os == 'ubuntu'
+ run: |
+ sudo apt-get update
+ sudo apt-get install \
+ libsdl2-2.0-0 \
+ libsdl2-image-2.0-0
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ inputs.dfhack_repo }}
+ ref: ${{ inputs.dfhack_ref }}
+ - name: Detect DF version
+ shell: bash
+ run: echo DF_VERSION="$(sh ci/get-df-version.sh)" >>$GITHUB_ENV
+ - name: Fetch DF cache
+ id: restore-df
+ uses: actions/cache/restore@v4
+ with:
+ path: ${{ env.DF_FOLDER }}
+ key: df-${{ inputs.os }}-${{ env.DF_VERSION }}-${{ hashFiles('ci/download-df.sh') }}
+ - name: Download DF
+ if: steps.restore-df.outputs.cache-hit != 'true'
+ run: sh ci/download-df.sh ${{ env.DF_FOLDER }} ${{ inputs.os }} ${{ env.DF_VERSION }}
+ - name: Save DF cache
+ if: steps.restore-df.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v4
+ with:
+ path: ${{ env.DF_FOLDER }}
+ key: df-${{ inputs.os }}-${{ env.DF_VERSION }}-${{ hashFiles('ci/download-df.sh') }}
+ - name: Install blank DFHack init scripts
+ if: inputs.config == 'empty'
+ shell: bash
+ run: |
+ mkdir -p ${{ env.DF_FOLDER }}/dfhack-config/init
+ cd data/dfhack-config/init
+ for fname in *.init; do touch ../../../${{ env.DF_FOLDER }}/dfhack-config/init/$fname; done
+ - name: Download DFHack
+ uses: actions/download-artifact@v4
+ with:
+ name: test-${{ inputs.compiler }}
+ - name: Install DFHack
+ shell: bash
+ run: tar xjf test-${{ inputs.compiler }}.tar.bz2 -C ${{ env.DF_FOLDER }}
+ - name: Start X server
+ if: inputs.os == 'ubuntu'
+ run: Xvfb :0 -screen 0 1600x1200x24 &
+ - name: Run lua tests
+ uses: nick-fields/retry@v3
+ env:
+ DISPLAY: :0
+ TERM: xterm-256color
+ with:
+ timeout_minutes: 1
+ command: python ci/run-tests.py --keep-status "${{ env.DF_FOLDER }}"
+ - name: Check RPC interface
+ run: python ci/check-rpc.py "${{ env.DF_FOLDER }}/dfhack-rpc.txt"
+ - name: Upload test artifacts
+ uses: actions/upload-artifact@v4
+ if: always()
+ continue-on-error: true
+ with:
+ name: test-output-${{ inputs.compiler }}-${{ inputs.plugins }}_plugins-${{ inputs.config }}_config
+ path: |
+ ${{ env.DF_FOLDER }}/dfhack-rpc.txt
+ ${{ env.DF_FOLDER }}/test*.json
+ ${{ env.DF_FOLDER }}/*.log
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000000..175a1adf48
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,113 @@
+name: Test
+
+on:
+ workflow_call:
+ inputs:
+ dfhack_repo:
+ type: string
+ default: DFHack/dfhack
+ dfhack_ref:
+ type: string
+ scripts_repo:
+ type: string
+ default: DFHack/scripts
+ scripts_ref:
+ type: string
+ structures_repo:
+ type: string
+ default: DFHack/df-structures
+ structures_ref:
+ type: string
+
+jobs:
+ build-windows:
+ name: Windows MSVC
+ uses: ./.github/workflows/build-windows.yml
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ scripts_repo: ${{ inputs.scripts_repo }}
+ scripts_ref: ${{ inputs.scripts_ref }}
+ structures_repo: ${{ inputs.structures_repo }}
+ structures_ref: ${{ inputs.structures_ref }}
+ artifact-name: test-msvc
+ cache-id: test
+ docs: true
+ html: false
+ tests: true
+
+ build-linux:
+ name: Linux gcc-${{ matrix.gcc }}
+ uses: ./.github/workflows/build-linux.yml
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ scripts_repo: ${{ inputs.scripts_repo }}
+ scripts_ref: ${{ inputs.scripts_ref }}
+ structures_repo: ${{ inputs.structures_repo }}
+ structures_ref: ${{ inputs.structures_ref }}
+ artifact-name: test-gcc-${{ matrix.gcc }}
+ cache-id: test
+ stonesense: ${{ matrix.plugins == 'all' }}
+ extras: ${{ matrix.plugins == 'all' }}
+ docs: true
+ html: false
+ tests: true
+ gcc-ver: ${{ matrix.gcc }}
+ secrets: inherit
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - gcc: 11 # baseline compatibility with ubuntu LTS 22.04
+ plugins: "default"
+ - gcc: 12 # highest available in ubuntu 22.04
+ plugins: "all"
+
+ test-windows:
+ name: Run Windows test suite
+ needs: build-windows
+ uses: ./.github/workflows/test-suite.yml
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ os: windows
+ compiler: msvc
+ plugins: default
+ config: default
+
+ test-windows-empty:
+ name: Run Windows test suite (empty config)
+ needs: build-windows
+ uses: ./.github/workflows/test-suite.yml
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ os: windows
+ compiler: msvc
+ plugins: default
+ config: empty
+
+ test-linux:
+ name: Run Linux test suite
+ needs: build-linux
+ uses: ./.github/workflows/test-suite.yml
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ os: ubuntu
+ compiler: gcc-11
+ plugins: default
+ config: default
+
+ test-linux-gcc-12-all-plugins:
+ name: Run Linux test suite (gcc-12, all plugins)
+ needs: build-linux
+ uses: ./.github/workflows/test-suite.yml
+ with:
+ dfhack_repo: ${{ inputs.dfhack_repo }}
+ dfhack_ref: ${{ inputs.dfhack_ref }}
+ os: ubuntu
+ compiler: gcc-12
+ plugins: all
+ config: default
diff --git a/.github/workflows/update-submodules.yml b/.github/workflows/update-submodules.yml
new file mode 100644
index 0000000000..c634e94d0a
--- /dev/null
+++ b/.github/workflows/update-submodules.yml
@@ -0,0 +1,29 @@
+name: Update submodules
+
+on:
+ schedule:
+ - cron: '0 7 * * *'
+ workflow_dispatch:
+
+jobs:
+ run:
+ if: ${{ github.event_name == 'workflow_dispatch' || github.repository_owner == 'DFHack' }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Clone DFHack
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ ref: ${{ github.ref }}
+ submodules: true
+ token: ${{ secrets.DFHACK_GITHUB_TOKEN }}
+ - name: Update submodules
+ run: |
+ git config user.name "DFHack-Urist via GitHub Actions"
+ git config user.email "63161697+DFHack-Urist@users.noreply.github.com"
+ if bash -x ci/update-submodules.bash; then
+ git push --recurse-submodules=check
+ elif ! git diff --exit-code HEAD; then
+ echo "update-submodules.bash failed to commit changes"
+ exit 1
+ fi
diff --git a/.github/workflows/watch-df-release.yml b/.github/workflows/watch-df-release.yml
new file mode 100644
index 0000000000..50950140d1
--- /dev/null
+++ b/.github/workflows/watch-df-release.yml
@@ -0,0 +1,159 @@
+name: Watch DF Releases
+
+on:
+ schedule:
+ - cron: '8/10 * * * *'
+ workflow_dispatch:
+
+jobs:
+ check-steam:
+ if: github.repository == 'DFHack/dfhack'
+ name: Check Steam (${{ matrix.df_steam_branch }}) for new DF releases
+ runs-on: ubuntu-latest
+ concurrency: watch-release-steam-${{ matrix.df_steam_branch }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # df_steam_branch: which DF Steam branch to watch
+ # platform: for symbols generation; leave blank to default to all
+ # structures_ref: leave blank to default to master
+ # dfhack_ref: leave blank if no structures update is desired
+ # steam_branch: leave blank if no DFHack steam push is desired
+ include:
+ - df_steam_branch: public
+# - df_steam_branch: beta
+# - df_steam_branch: experimental
+# structures_ref: experimental
+# dfhack_ref: experimental
+# steam_branch: experimental
+ steps:
+ - name: Fetch state
+ uses: actions/cache/restore@v4
+ with:
+ path: state
+ key: watch-release-steam-${{ matrix.df_steam_branch }}
+ - name: Compare branch metadata
+ uses: nick-fields/retry@v3
+ with:
+ timeout_minutes: 5
+ retry_wait_seconds: 60
+ command: |
+ blob=$(wget 'https://api.steamcmd.net/v1/info/975370?pretty=1' -O- | \
+ awk '/^ *"branches"/,0' | \
+ awk '/^ *"${{ matrix.df_steam_branch }}"/,0')
+ buildid=$(echo "$blob" | \
+ fgrep buildid | \
+ head -n1 | \
+ cut -d'"' -f4)
+ timestamp=$(echo "$blob" | \
+ fgrep timeupdated | \
+ head -n1 | \
+ cut -d'"' -f4)
+ test -z "$buildid" && echo "no buildid result" && exit 1
+ test -z "$timestamp" && echo "no timestamp result" && exit 1
+ test "$buildid" -gt 0 || exit 1
+ test "$timestamp" -gt 0 || exit 1
+ echo "buildid and timestamp of last branch update: $buildid, $timestamp"
+ mkdir -p state
+ touch state/buildid state/timestamp
+ last_buildid=$(cat state/buildid)
+ last_timestamp=$(cat state/timestamp)
+ if [ -z "$last_timestamp" ]; then
+ echo "no stored timestamp"
+ last_buildid=0
+ last_timestamp=0
+ else
+ echo "stored buildid and timestamp of last branch update: $last_buildid, $last_timestamp"
+ fi
+ if [ "$buildid" -ne "$last_buildid" -a "$timestamp" -gt "$last_timestamp" ]; then
+ echo "branch updated"
+ echo "$buildid" >state/buildid
+ echo "$timestamp" >state/timestamp
+ echo BUILDID=$buildid >> $GITHUB_ENV
+ fi
+ - name: Discord Webhook Action
+ uses: tsickert/discord-webhook@v5.3.0
+ if: env.BUILDID
+ with:
+ webhook-url: ${{ secrets.DISCORD_TEAM_PRIVATE_WEBHOOK_URL }}
+ content: "<@&${{ secrets.DISCORD_TEAM_ROLE_ID }}> Steam ${{ matrix.df_steam_branch }} branch updated (build id: ${{ env.BUILDID }})"
+ - name: Launch symbol generation workflow
+ if: env.BUILDID && matrix.dfhack_ref
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ gh workflow run generate-symbols.yml \
+ -R DFHack/dfhack \
+ -r ${{ matrix.dfhack_ref }} \
+ -f structures_ref=${{ matrix.structures_ref }} \
+ -f version=auto \
+ -f platform=${{ matrix.platform }} \
+ -f channel=steam \
+ -f df_steam_branch=${{ matrix.df_steam_branch }} \
+ -f steam_branch=${{ matrix.steam_branch }}
+ - name: Save state
+ uses: actions/cache/save@v4
+ if: env.BUILDID
+ with:
+ path: state
+ key: watch-release-steam-${{ matrix.df_steam_branch }}-${{ env.BUILDID }}
+
+ check-non-steam:
+ if: github.repository == 'DFHack/dfhack'
+ name: Check ${{ matrix.channel }} for new DF releases
+ runs-on: ubuntu-latest
+ concurrency: watch-release-${{ matrix.channel }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - channel: itch
+ url: 'https://kitfoxgames.itch.io/dwarf-fortress'
+ prefix: 'dwarf_fortress'
+ - channel: classic
+ url: 'https://www.bay12games.com/dwarves/'
+ prefix: 'df'
+ steps:
+ - name: Fetch state
+ uses: actions/cache/restore@v4
+ with:
+ path: state
+ key: watch-release-${{ matrix.channel }}
+ - name: Compare versions
+ uses: nick-fields/retry@v3
+ with:
+ timeout_minutes: 5
+ retry_wait_seconds: 60
+ command: |
+ version=$(wget "${{ matrix.url }}" -qO- | tr '"' '\n' | fgrep 'tar.bz2' | head -n1 | sed -r 's/${{ matrix.prefix }}_([0-9]{2})_([0-9]{2})_linux.tar.bz2/\1.\2/')
+ echo "latest ${{ matrix.channel }} version: $version"
+ if ! grep -qE '^[0-9]+\.[0-9]+$' <<<"$version"; then
+ echo "invalid version"
+ exit 1
+ fi
+ mkdir -p state
+ touch state/last_version
+ last_version=$(cat state/last_version)
+ if [ -z "$last_version" ]; then
+ echo "no stored version"
+ last_version=0
+ else
+ echo "stored ${{ matrix.channel }} version: $last_version"
+ fi
+ if [ "$(tr -d '.' <<<"$version")" -gt "$(tr -d '.' <<<"$last_version")" ]; then
+ echo "${{ matrix.channel }} has been updated"
+ echo "$version" >state/last_version
+ echo NEW_VERSION=$version >> $GITHUB_ENV
+ fi
+ - name: Discord Webhook Action
+ uses: tsickert/discord-webhook@v5.3.0
+ if: env.NEW_VERSION
+ with:
+ webhook-url: ${{ secrets.DISCORD_TEAM_PRIVATE_WEBHOOK_URL }}
+ content: "<@&${{ secrets.DISCORD_TEAM_ROLE_ID }}> ${{ matrix.channel }} updated to ${{ env.NEW_VERSION }}"
+ - name: Save state
+ uses: actions/cache/save@v4
+ if: env.NEW_VERSION
+ with:
+ path: state
+ key: watch-release-${{ matrix.channel }}-${{ env.NEW_VERSION }}
diff --git a/.gitignore b/.gitignore
index 5ef3ce7595..eda2b226d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
# linux backup files
*~
-#Kdevelop project files
+# Kdevelop project files
*.kdev4
.kdev4
@@ -9,31 +9,47 @@
build*/
nix
buntu
-build/VC2010
#except for the real one
!build/
# Sphinx generated documentation
-docs/_*
+docs/changelogs/
docs/html/
+docs/pdf/
+docs/pseudoxml/
+docs/tags/
+docs/text/
+docs/tools/
+docs/xml/
# in-place build
build/Makefile
build/CMakeCache.txt
build/cmake_install.cmake
build/CMakeFiles
-build/doc
+build/CTestTestfile.cmake
+build/DartConfiguration.tcl
+build/data
+build/docs
build/lua
build/bin
+build/lib
build/depends
build/library
+build/package
build/plugins
build/scripts
build/install_manifest.txt
build/_CPack_Packages
build/dfhack-*.zip
build/dfhack-*.bz2
+build/*ninja*
+build/compile_commands.json
+build/dfhack_setarch.txt
+build/ImportExecutables.cmake
+build/Testing
+build/_deps
# Python binding binaries
*.pyc
@@ -47,8 +63,27 @@ build/CPack*Config.cmake
*.swp
.vimrc
+# VSCode files
+.vscode
+*.code-workspace
+
# ctags file
tags
# Mac OS X .DS_Store files
.DS_Store
+
+# VS is annoying about this one.
+/build/win64/DF_PATH.txt
+/build/win32/DF_PATH.txt
+/.vs
+
+# CLion
+.idea
+
+# external plugins
+/plugins/CMakeLists.custom.txt
+
+# 3rd party downloads
+depends/steam
+depends/SDL2
diff --git a/.gitmodules b/.gitmodules
index 687dae006a..596bafc98f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,15 +1,33 @@
[submodule "plugins/stonesense"]
path = plugins/stonesense
- url = git://github.com/DFHack/stonesense.git
-[submodule "plugins/isoworld"]
- path = plugins/isoworld
- url = git://github.com/DFHack/isoworld.git
+ url = ../../DFHack/stonesense.git
[submodule "library/xml"]
path = library/xml
- url = git://github.com/DFHack/df-structures.git
+ url = ../../DFHack/df-structures.git
[submodule "depends/clsocket"]
path = depends/clsocket
- url = git://github.com/DFHack/clsocket.git
+ url = ../../DFHack/clsocket.git
[submodule "scripts2"]
path = scripts
- url = git://github.com/dfhack/scripts.git
+ url = ../../DFHack/scripts.git
+[submodule "depends/jsoncpp"]
+ path = depends/jsoncpp-sub
+ url = ../../DFHack/jsoncpp.git
+[submodule "depends/xlsxio"]
+ path = depends/xlsxio
+ url = ../../DFHack/xlsxio.git
+[submodule "depends/libzip"]
+ path = depends/libzip
+ url = ../../DFHack/libzip.git
+[submodule "depends/libexpat"]
+ path = depends/libexpat
+ url = ../../DFHack/libexpat.git
+[submodule "depends/luacov"]
+ path = depends/luacov
+ url = ../../DFHack/luacov.git
+[submodule "depends/googletest"]
+ path = depends/googletest
+ url = ../../google/googletest.git
+[submodule "depends/dfhooks"]
+ path = depends/dfhooks
+ url = ../../DFHack/dfhooks
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000..47251d8ed3
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,44 @@
+ci:
+ autofix_prs: false
+ autoupdate_schedule: monthly
+repos:
+# shared across repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v6.0.0
+ hooks:
+ - id: check-added-large-files
+ - id: check-case-conflict
+ - id: check-executables-have-shebangs
+ - id: check-merge-conflict
+ - id: check-shebang-scripts-are-executable
+ - id: check-symlinks
+ - id: check-xml
+ - id: check-yaml
+ - id: destroyed-symlinks
+ - id: end-of-file-fixer
+ - id: mixed-line-ending
+ args: ['--fix=lf']
+ - id: trailing-whitespace
+- repo: https://github.com/python-jsonschema/check-jsonschema
+ rev: 0.37.4
+ hooks:
+ - id: check-github-workflows
+- repo: https://github.com/Lucas-C/pre-commit-hooks
+ rev: v1.5.6
+ hooks:
+ - id: forbid-tabs
+ exclude_types:
+ - json
+ - id: remove-tabs
+ exclude_types:
+ - json
+# specific to dfhack:
+- repo: local
+ hooks:
+ - id: authors-rst
+ name: Check Authors.rst
+ language: python
+ entry: python3 ci/authors-rst.py
+ files: docs/about/Authors\.rst
+ pass_filenames: false
+exclude: '^(depends/|data/.*\.json$|.*\.diff$|.*\.dfstock$)'
diff --git a/library/doc/img/.dot b/.readthedocs.requirements.txt
similarity index 100%
rename from library/doc/img/.dot
rename to .readthedocs.requirements.txt
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 0000000000..bf71c46b78
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,22 @@
+# .readthedocs.yaml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+version: 2
+
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3"
+
+submodules:
+ include: all
+
+sphinx:
+ configuration: conf.py
+
+formats: all
+
+python:
+ install:
+ - requirements: .readthedocs.requirements.txt
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1455044aa8..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-sudo: false
-language: cpp
-addons:
- apt:
- packages: &default_packages
- - lua5.2
- - libxml-libxml-perl
- - libxml-libxslt-perl
- - zlib1g-dev:i386
-matrix:
- include:
- - env: GCC_VERSION=4.5
- addons:
- apt:
- packages:
- - *default_packages
- - gcc-4.5-multilib
- - g++-4.5-multilib
- - env: GCC_VERSION=4.8
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - *default_packages
- - gcc-4.8-multilib
- - g++-4.8-multilib
-before_install:
- pip install --user sphinx
-script:
-- git tag tmp-travis-build
-- sh travis/git-info.sh
-- sphinx-build -qW -j3 . docs/html
-- python travis/pr-check-base.py
-- python travis/lint.py
-- python travis/authors-rst.py
-- python travis/script-in-readme.py
-- python travis/script-syntax.py --ext=lua --cmd="luac5.2 -p"
-- python travis/script-syntax.py --ext=rb --cmd="ruby -c"
-- mkdir build-travis
-- cd build-travis
-- cmake .. -DCMAKE_C_COMPILER=gcc-$GCC_VERSION -DCMAKE_CXX_COMPILER=g++-$GCC_VERSION -DBUILD_DOCS:BOOL=ON
-- make -j3
-notifications:
- email: false
- irc:
- channels:
- - "chat.freenode.net#dfhack"
- on_success: change
- on_failure: always
diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
index a45f073725..31a336b2b6 100644
--- a/.ycm_extra_conf.py
+++ b/.ycm_extra_conf.py
@@ -4,12 +4,40 @@
# pylint: disable=import-error,invalid-name,missing-docstring,unused-argument
-import os
+import os,platform
import ycm_core
def DirectoryOfThisScript():
return os.path.dirname(os.path.abspath(__file__))
+default_flags = [
+ '-I','library/include',
+ '-I','library/proto',
+ '-I','plugins/proto',
+ '-I','depends/protobuf',
+ '-I','depends/lua/include',
+ '-I','depends/md5',
+ '-I','depends/jsoncpp/include',
+ '-I','depends/tinyxml',
+ '-I','depends/clsocket/src',
+ '-x','c++',
+ '-D','PROTOBUF_USE_DLLS',
+ '-D','LUA_BUILD_AS_DLL',
+ '-Wall','-Wextra',
+]
+
+if os.name == 'posix':
+ default_flags.extend([
+ '-D','LINUX_BUILD',
+ '-D','_GLIBCXX_USE_C99',
+ ])
+ if platform.system() == 'Darwin':
+ default_flags.extend(['-D','_DARWIN'])
+ else:
+ default_flags.extend(['-D','_LINUX'])
+else:
+ default_flags.extend(['-D','WIN32'])
+
# We need to tell YouCompleteMe how to compile this project. We do this using
# clang's "Compilation Database" system, which essentially just dumps a big
# json file into the build folder.
@@ -117,13 +145,19 @@ def FlagsForFile(filename, **kwargs):
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile(filename)
if not compilation_info:
- return None
+ return {
+ 'flags':MakeRelativePathsInFlagsAbsolute(default_flags,DirectoryOfThisScript()),
+ 'do_cache': True,
+ }
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_
)
+ # Make sure ycm reports more suspicuous code lines
+ final_flags.append('-Wextra')
+
return {
'flags': final_flags,
'do_cache': True
diff --git a/CMake/DownloadFile.cmake b/CMake/DownloadFile.cmake
new file mode 100644
index 0000000000..d0165b11a3
--- /dev/null
+++ b/CMake/DownloadFile.cmake
@@ -0,0 +1,71 @@
+# Helper to download files as needed
+
+function(file_md5_if_exists FILE VAR)
+ if(EXISTS "${FILE}")
+ file(MD5 "${FILE}" "${VAR}")
+ set(${VAR} "${${VAR}}" PARENT_SCOPE)
+ else()
+ set(${VAR} "" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(search_downloads FILE_MD5 VAR)
+ set(${VAR} "" PARENT_SCOPE)
+ file(GLOB FILES ${dfhack_SOURCE_DIR}/CMake/downloads/*)
+ foreach(FILE ${FILES})
+ file(MD5 "${FILE}" CUR_MD5)
+ if("${CUR_MD5}" STREQUAL "${FILE_MD5}")
+ set(${VAR} ${FILE} PARENT_SCOPE)
+ return()
+ endif()
+ endforeach()
+endfunction()
+
+function(download_file URL DEST EXPECTED_MD5)
+ get_filename_component(FILENAME "${URL}" NAME)
+ file_md5_if_exists("${DEST}" CUR_MD5)
+
+ if(NOT "${EXPECTED_MD5}" STREQUAL "${CUR_MD5}")
+ search_downloads(${EXPECTED_MD5} DLPATH)
+ if(NOT("${DLPATH}" STREQUAL ""))
+ message("* Copying ${FILENAME} from ${DLPATH}")
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E copy
+ "${DLPATH}"
+ "${DEST}")
+ return()
+ endif()
+
+ message("* Downloading ${FILENAME}")
+ file(DOWNLOAD "${URL}" "${DEST}" EXPECTED_MD5 "${EXPECTED_MD5}" SHOW_PROGRESS)
+ endif()
+endfunction()
+
+# Download a file and uncompress it
+function(download_file_unzip URL ZIP_TYPE ZIP_DEST ZIP_MD5 UNZIP_DEST UNZIP_MD5)
+ get_filename_component(FILENAME "${URL}" NAME)
+ file_md5_if_exists("${UNZIP_DEST}" CUR_UNZIP_MD5)
+
+ # Redownload if the MD5 of the uncompressed file doesn't match
+ if(NOT "${UNZIP_MD5}" STREQUAL "${CUR_UNZIP_MD5}")
+ download_file("${URL}" "${ZIP_DEST}" "${ZIP_MD5}")
+
+ if(EXISTS "${ZIP_DEST}")
+ message("* Decompressing ${FILENAME}")
+ if("${ZIP_TYPE}" STREQUAL "gz")
+ execute_process(COMMAND
+ "${PERL_EXECUTABLE}" "${dfhack_SOURCE_DIR}/depends/gunzip.pl"
+ "${ZIP_DEST}" --force)
+ else()
+ message(SEND_ERROR "Unknown ZIP_TYPE: ${ZIP_TYPE}")
+ endif()
+ if(NOT EXISTS "${UNZIP_DEST}")
+ message(SEND_ERROR "File failed to unzip to ${UNZIP_DEST}")
+ else()
+ file(MD5 "${UNZIP_DEST}" CUR_UNZIP_MD5)
+ if(NOT "${UNZIP_MD5}" STREQUAL "${CUR_UNZIP_MD5}")
+ message(SEND_ERROR "MD5 mismatch: ${UNZIP_DEST}: expected ${UNZIP_MD5}, got ${CUR_UNZIP_MD5}")
+ endif()
+ endif()
+ endif()
+ endif()
+endfunction()
diff --git a/CMake/Modules/CMakeVS10FindMake.cmake b/CMake/Modules/CMakeVS10FindMake.cmake
deleted file mode 100644
index 460de25e5d..0000000000
--- a/CMake/Modules/CMakeVS10FindMake.cmake
+++ /dev/null
@@ -1,28 +0,0 @@
-
-#=============================================================================
-# Copyright 2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distributed this file outside of CMake, substitute the full
-# License text for the above reference.)
-
-# We use MSBuild as the build tool for VS 10
-FIND_PROGRAM(CMAKE_MAKE_PROGRAM
- NAMES MSBuild
- HINTS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0\\Setup\\VS;ProductDir]
- "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/"
- "c:/WINDOWS/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\10.0;CLR Version]/"
- "$ENV{SYSTEMROOT}/Microsoft.NET/Framework/[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\10.0;CLR Version]/"
- )
-
-MARK_AS_ADVANCED(CMAKE_MAKE_PROGRAM)
-SET(MSVC10 1)
-SET(MSVC_VERSION 1600)
-
diff --git a/CMake/Modules/FindCurses.cmake b/CMake/Modules/FindCurses.cmake
deleted file mode 100644
index 98adf9815f..0000000000
--- a/CMake/Modules/FindCurses.cmake
+++ /dev/null
@@ -1,23 +0,0 @@
-IF(Curses_FOUND)
- SET(Curses_FIND_QUIETLY TRUE)
-ENDIF()
-
-FIND_PATH(Curses_INCLUDE_PATH
- NAMES ncurses.h curses.h
- PATH_SUFFIXES ncurses
- PATHS /usr/include/ncursesw /usr/include /usr/local/include /usr/pkg/include
-)
-
-FIND_LIBRARY(Curses_LIBRARY
- NAMES ncursesw
- PATHS /lib /usr/lib /usr/local/lib /usr/pkg/lib
-)
-
-IF (Curses_INCLUDE_PATH AND Curses_LIBRARY)
- SET(Curses_FOUND TRUE)
-ENDIF()
-
-MARK_AS_ADVANCED(
- Curses_INCLUDE_PATH
- Curses_LIBRARY
-)
diff --git a/CMake/Modules/FindDocutils.cmake b/CMake/Modules/FindDocutils.cmake
deleted file mode 100644
index 8103628df0..0000000000
--- a/CMake/Modules/FindDocutils.cmake
+++ /dev/null
@@ -1,3 +0,0 @@
-FIND_PROGRAM(RST2HTML_EXECUTABLE NAMES rst2html rst2html.py)
-INCLUDE(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Docutils DEFAULT_MSG RST2HTML_EXECUTABLE)
\ No newline at end of file
diff --git a/CMake/Modules/FindDoxygen.cmake b/CMake/Modules/FindDoxygen.cmake
deleted file mode 100644
index 94d20a9ffd..0000000000
--- a/CMake/Modules/FindDoxygen.cmake
+++ /dev/null
@@ -1,185 +0,0 @@
-# - This module looks for Doxygen and the path to Graphviz's dot
-# Doxygen is a documentation generation tool. Please see
-# http://www.doxygen.org
-#
-# This module accepts the following optional variables:
-#
-# DOXYGEN_SKIP_DOT = If true this module will skip trying to find Dot
-# (an optional component often used by Doxygen)
-#
-# This modules defines the following variables:
-#
-# DOXYGEN_EXECUTABLE = The path to the doxygen command.
-# DOXYGEN_FOUND = Was Doxygen found or not?
-#
-# DOXYGEN_DOT_EXECUTABLE = The path to the dot program used by doxygen.
-# DOXYGEN_DOT_FOUND = Was Dot found or not?
-# DOXYGEN_DOT_PATH = The path to dot not including the executable
-#
-#
-
-#Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
-#All rights reserved.
-#
-#Redistribution and use in source and binary forms, with or without
-#modification, are permitted provided that the following conditions
-#are met:
-#
-#* Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#
-#* Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-#* Neither the names of Kitware, Inc., the Insight Software Consortium,
-# nor the names of their contributors may be used to endorse or promote
-# products derived from this software without specific prior written
-# permission.
-#
-#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-#-----------------------------------------------------------------------------
-#
-#The above copyright and license notice applies to distributions of
-#CMake in source and binary form. Some source files contain additional
-#notices of original copyright by their contributors; see each source
-#for details. Third-party software packages supplied with CMake under
-#compatible licenses provide their own copyright notices documented in
-#corresponding subdirectories.
-#
-#-----------------------------------------------------------------------------
-#
-#CMake was initially developed by Kitware with the following sponsorship:
-#
-# * National Library of Medicine at the National Institutes of Health
-# as part of the Insight Segmentation and Registration Toolkit (ITK).
-#
-# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel
-# Visualization Initiative.
-#
-# * National Alliance for Medical Image Computing (NAMIC) is funded by the
-# National Institutes of Health through the NIH Roadmap for Medical Research,
-# Grant U54 EB005149.
-#
-# * Kitware, Inc.
-
-
-# For backwards compatibility support
-IF(Doxygen_FIND_QUIETLY)
- SET(DOXYGEN_FIND_QUIETLY TRUE)
-ENDIF(Doxygen_FIND_QUIETLY)
-
-# ===== Rationale for OS X AppBundle mods below =====
-# With the OS X GUI version, Doxygen likes to be installed to /Applications and
-# it contains the doxygen executable in the bundle. In the versions I've
-# seen, it is located in Resources, but in general, more often binaries are
-# located in MacOS.
-#
-# NOTE: The official Doxygen.app that is distributed for OS X uses non-standard
-# conventions. Instead of the command-line "doxygen" tool being placed in
-# Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and
-# "doxygen" is placed in Contents/Resources. This is most likely done
-# so that something happens when people double-click on the Doxygen.app
-# package. Unfortunately, CMake gets confused by this as when it sees the
-# bundle it uses "Doxywizard" as the executable to use instead of
-# "doxygen". Therefore to work-around this issue we temporarily disable
-# the app-bundle feature, just for this CMake module:
-if(APPLE)
- # Save the old setting
- SET(TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE})
- # Disable the App-bundle detection feature
- SET(CMAKE_FIND_APPBUNDLE "NEVER")
-endif()
-# FYI:
-# In the older versions of OS X Doxygen, dot was included with the
-# Doxygen bundle. But the new versions require you to download
-# Graphviz.app which contains "dot" in it's bundle.
-# ============== End OSX stuff ================
-
-#
-# Find Doxygen...
-#
-
-FIND_PROGRAM(DOXYGEN_EXECUTABLE
- NAMES doxygen
- PATHS
- "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin"
- /Applications/Doxygen.app/Contents/Resources
- /Applications/Doxygen.app/Contents/MacOS
- DOC "Doxygen documentation generation tool (http://www.doxygen.org)"
-)
-
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Doxygen DEFAULT_MSG DOXYGEN_EXECUTABLE)
-
-#
-# Find Dot...
-#
-
-IF(NOT DOXYGEN_SKIP_DOT)
- FIND_PROGRAM(DOXYGEN_DOT_EXECUTABLE
- NAMES dot
- PATHS
- "$ENV{ProgramFiles}/Graphviz2.26.3/bin"
- "C:/Program Files/Graphviz2.26.3/bin"
- "$ENV{ProgramFiles}/Graphviz 2.21/bin"
- "C:/Program Files/Graphviz 2.21/bin"
- "$ENV{ProgramFiles}/ATT/Graphviz/bin"
- "C:/Program Files/ATT/Graphviz/bin"
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin
- /Applications/Graphviz.app/Contents/MacOS
- /Applications/Doxygen.app/Contents/Resources
- /Applications/Doxygen.app/Contents/MacOS
- DOC "Graphviz Dot tool for using Doxygen"
- )
-
- if(DOXYGEN_DOT_EXECUTABLE)
- set(DOXYGEN_DOT_FOUND TRUE)
- # The Doxyfile wants the path to Dot, not the entire path and executable
- get_filename_component(DOXYGEN_DOT_PATH "${DOXYGEN_DOT_EXECUTABLE}" PATH CACHE)
- endif()
-
-endif(NOT DOXYGEN_SKIP_DOT)
-
-#
-# Backwards compatibility...
-#
-
-if(APPLE)
- # Restore the old app-bundle setting setting
- SET(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE})
-endif()
-
-# Maintain the _FOUND variables as "YES" or "NO" for backwards compatibility
-# (allows people to stuff them directly into Doxyfile with configure_file())
-if(DOXYGEN_FOUND)
- set(DOXYGEN_FOUND "YES")
-else()
- set(DOXYGEN_FOUND "NO")
-endif()
-if(DOXYGEN_DOT_FOUND)
- set(DOXYGEN_DOT_FOUND "YES")
-else()
- set(DOXYGEN_DOT_FOUND "NO")
-endif()
-
-# For backwards compatibility support
-SET (DOXYGEN ${DOXYGEN_EXECUTABLE} )
-SET (DOT ${DOXYGEN_DOT_EXECUTABLE} )
-
-MARK_AS_ADVANCED(
- DOXYGEN_EXECUTABLE
- DOXYGEN_DOT_EXECUTABLE
- DOXYGEN_DOT_PATH
- )
diff --git a/CMake/Modules/FindSphinx.cmake b/CMake/Modules/FindSphinx.cmake
index 54fc5ea8dc..6b78a555ff 100644
--- a/CMake/Modules/FindSphinx.cmake
+++ b/CMake/Modules/FindSphinx.cmake
@@ -13,4 +13,3 @@ find_package_handle_standard_args(Sphinx DEFAULT_MSG
)
mark_as_advanced(SPHINX_EXECUTABLE)
-
diff --git a/CMake/Modules/FindTinyXML.cmake b/CMake/Modules/FindTinyXML.cmake
index b0466fbd54..4d6d69f7bb 100644
--- a/CMake/Modules/FindTinyXML.cmake
+++ b/CMake/Modules/FindTinyXML.cmake
@@ -32,11 +32,11 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##################################################################################################
-#
+#
# CMake script for finding TinyXML.
-#
+#
# Input variables:
-#
+#
# - TinyXML_ROOT_DIR (optional): When specified, header files and libraries will be searched for in
# ${TinyXML_ROOT_DIR}/include
# ${TinyXML_ROOT_DIR}/libs
@@ -46,23 +46,23 @@
# preference is given to the CMake variable.
# Use this variable for finding packages installed in a nonstandard location, or for enforcing
# that one of multiple package installations is picked up.
-#
-#
+#
+#
# Cache variables (not intended to be used in CMakeLists.txt files)
-#
+#
# - TinyXML_INCLUDE_DIR: Absolute path to package headers.
# - TinyXML_LIBRARY: Absolute path to library.
-#
-#
+#
+#
# Output variables:
-#
+#
# - TinyXML_FOUND: Boolean that indicates if the package was found
# - TinyXML_INCLUDE_DIRS: Paths to the necessary header files
# - TinyXML_LIBRARIES: Package libraries
-#
-#
+#
+#
# Example usage:
-#
+#
# find_package(TinyXML)
# if(NOT TinyXML_FOUND)
# # Error handling
@@ -71,19 +71,19 @@
# include_directories(${TinyXML_INCLUDE_DIRS} ...)
# ...
# target_link_libraries(my_target ${TinyXML_LIBRARIES})
-#
+#
##################################################################################################
# Get package location hint from environment variable (if any)
if(NOT TinyXML_ROOT_DIR AND DEFINED ENV{TinyXML_ROOT_DIR})
- set(TinyXML_ROOT_DIR "$ENV{TinyXML_ROOT_DIR}" CACHE PATH
- "TinyXML base directory location (optional, used for nonstandard installation paths)")
+ set(TinyXML_ROOT_DIR "$ENV{TinyXML_ROOT_DIR}" CACHE PATH
+ "TinyXML base directory location (optional, used for nonstandard installation paths)")
endif()
# Search path for nonstandard package locations
if(TinyXML_ROOT_DIR)
- set(TinyXML_INCLUDE_PATH PATHS "${TinyXML_ROOT_DIR}/include" NO_DEFAULT_PATH)
- set(TinyXML_LIBRARY_PATH PATHS "${TinyXML_ROOT_DIR}/lib" NO_DEFAULT_PATH)
+ set(TinyXML_INCLUDE_PATH PATHS "${TinyXML_ROOT_DIR}/include" NO_DEFAULT_PATH)
+ set(TinyXML_LIBRARY_PATH PATHS "${TinyXML_ROOT_DIR}/lib" NO_DEFAULT_PATH)
endif()
# Find headers and libraries
@@ -102,6 +102,6 @@ set(TinyXML_FOUND ${TINYXML_FOUND}) # Enforce case-correctness: Set appropriatel
unset(TINYXML_FOUND) # ...and unset uppercase variable generated by find_package_handle_standard_args
if(TinyXML_FOUND)
- set(TinyXML_INCLUDE_DIRS ${TinyXML_INCLUDE_DIR})
- set(TinyXML_LIBRARIES ${TinyXML_LIBRARY})
+ set(TinyXML_INCLUDE_DIRS ${TinyXML_INCLUDE_DIR})
+ set(TinyXML_LIBRARIES ${TinyXML_LIBRARY})
endif()
diff --git a/CMake/downloads/.gitignore b/CMake/downloads/.gitignore
new file mode 100644
index 0000000000..ff7b252fea
--- /dev/null
+++ b/CMake/downloads/.gitignore
@@ -0,0 +1,3 @@
+*
+!README.txt
+!.gitignore
diff --git a/CMake/downloads/README.txt b/CMake/downloads/README.txt
new file mode 100644
index 0000000000..40b5047257
--- /dev/null
+++ b/CMake/downloads/README.txt
@@ -0,0 +1,3 @@
+This folder exists as an alternate location for downloaded files. Files will
+ordinarily not be downloaded here, but CMake will look for them here anyway to
+facilitate offline builds.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 10a831c28a..1495bea2b1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,168 +1,295 @@
# main project file. use it from a build sub-folder, see COMPILE for details
-# prevent CMake warnings about INTERFACE_LINK_LIBRARIES vs LINK_INTERFACE_LIBRARIES
-IF(CMAKE_VERSION VERSION_GREATER "2.8.12")
- CMAKE_POLICY(SET CMP0022 OLD)
-ENDIF()
+## some generic CMake magic
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+cmake_policy(SET CMP0048 NEW)
+cmake_policy(SET CMP0074 NEW)
+set(CMAKE_INSTALL_MESSAGE "LAZY")
+
+# set up versioning.
+set(DF_VERSION "53.16")
+set(DFHACK_RELEASE "r1.1")
+set(DFHACK_PRERELEASE FALSE)
+
+set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")
+set(DFHACK_ABI_VERSION 2)
+set(DFHACK_BUILD_ID "" CACHE STRING "Build ID (should be specified on command line)")
+
+# set up ccache
+find_program(CCACHE_EXECUTABLE "ccache" HINTS /usr/local/bin /opt/local/bin)
+if(CCACHE_EXECUTABLE)
+ message(STATUS "using ccache")
+ set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE)
+ set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE)
+endif()
+
+# project must be declared *after* ccache setup
+project(dfhack)
# Set up build types
if(CMAKE_CONFIGURATION_TYPES)
- SET(CMAKE_CONFIGURATION_TYPES Release RelWithDebInfo)
- SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "List of supported configuration types" FORCE)
+ set(CMAKE_CONFIGURATION_TYPES "Release;RelWithDebInfo" CACHE STRING "List of supported configuration types" FORCE)
else(CMAKE_CONFIGURATION_TYPES)
- if (NOT CMAKE_BUILD_TYPE)
- SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Release RelWithDebInfo.")
- endif (NOT CMAKE_BUILD_TYPE)
+ set(DFHACK_TYPE_HELP "Choose the type of build, options are: Release and RelWithDebInfo")
+ # Prevent cmake C module attempts to overwrite our help string
+ if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "${DFHACK_TYPE_HELP}")
+ else(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "${DFHACK_TYPE_HELP}")
+ endif(NOT CMAKE_BUILD_TYPE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Release;RelWithDebInfo")
endif(CMAKE_CONFIGURATION_TYPES)
-OPTION(BUILD_DOCS "Choose whether to build the documentation (requires python and Sphinx)." OFF)
-
-## some generic CMake magic
-cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
-project(dfhack)
+option(BUILD_DOCS "Choose whether to build the documentation (requires python and Sphinx)." OFF)
+option(BUILD_DOCS_NO_HTML "Don't build the HTML docs, only the in-game docs." OFF)
+option(REMOVE_SYMBOLS_FROM_DF_STUBS "Remove debug symbols from DF stubs. (Reduces libdfhack size to about half but removes a few useful symbols)" ON)
-macro(CHECK_GCC COMPILER_PATH)
- execute_process(COMMAND ${COMPILER_PATH} -dumpversion OUTPUT_VARIABLE GCC_VERSION_OUT)
- string(STRIP "${GCC_VERSION_OUT}" GCC_VERSION_OUT)
- if (${GCC_VERSION_OUT} VERSION_LESS "4.5")
- message(SEND_ERROR "${COMPILER_PATH} version ${GCC_VERSION_OUT} cannot be used - use GCC 4.5 or later")
- elseif (${GCC_VERSION_OUT} VERSION_GREATER "4.9.9")
- # GCC 5 changes ABI name mangling to enable C++11 changes.
- # This must be disabled to enable linking against DF.
- # http://developerblog.redhat.com/2015/02/05/gcc5-and-the-c11-abi/
- add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
- endif()
+macro(CHECK_GCC compiler_path)
+ execute_process(COMMAND ${compiler_path} -dumpversion OUTPUT_VARIABLE GCC_VERSION_OUT)
+ string(STRIP "${GCC_VERSION_OUT}" GCC_VERSION_OUT)
+ if(${GCC_VERSION_OUT} VERSION_LESS "11")
+ message(SEND_ERROR "${compiler_path} version ${GCC_VERSION_OUT} cannot be used - use GCC 11 or later")
+ endif()
+ # GCC 16 currently has a defect that prevents it from compiling DFHack
+ # -Warray-bounds is broken in GCC 16 and we'd rather disable the compiler than remove this warning
+ # will reconsider when this defect is fixed in a future GCC release
+ if(${GCC_VERSION_OUT} VERSION_GREATER_EQUAL "16")
+ message(SEND_ERROR "${compiler_path} version ${GCC_VERSION_OUT} cannot be used - use GCC 15 or earlier")
+ endif()
endmacro()
if(UNIX)
- if(CMAKE_COMPILER_IS_GNUCC)
- CHECK_GCC(${CMAKE_C_COMPILER})
- else()
- message(SEND_ERROR "C compiler is not GCC")
- endif()
- if(CMAKE_COMPILER_IS_GNUCXX)
- CHECK_GCC(${CMAKE_CXX_COMPILER})
- else()
- message(SEND_ERROR "C++ compiler is not GCC")
- endif()
+ if(CMAKE_COMPILER_IS_GNUCC)
+ check_gcc(${CMAKE_C_COMPILER})
+ else()
+ message(SEND_ERROR "C compiler is not GCC")
+ endif()
+ if(CMAKE_COMPILER_IS_GNUCXX)
+ check_gcc(${CMAKE_CXX_COMPILER})
+ else()
+ message(SEND_ERROR "C++ compiler is not GCC")
+ endif()
endif()
if(WIN32)
- if((NOT MSVC) OR (NOT MSVC_VERSION STREQUAL 1600))
- message(SEND_ERROR "MSVC 2010 is required")
- endif()
+ set(MSVC_MIN_VER 1930)
+ set(MSVC_MAX_VER 1944)
+ if(NOT MSVC)
+ message(SEND_ERROR "No MSVC found! MSVC 2022 version ${MSVC_MIN_VER} to ${MSVC_MAX_VER} is required.")
+ elseif((MSVC_VERSION LESS MSVC_MIN_VER) OR (MSVC_VERSION GREATER MSVC_MAX_VER))
+ message(SEND_ERROR "MSVC 2022 version ${MSVC_MIN_VER} to ${MSVC_MAX_VER} is required, Version Found: ${MSVC_VERSION}")
+ endif()
endif()
+# Ask for C++-20 standard from compilers
+set(CMAKE_CXX_STANDARD 20)
+# Require the standard support from compilers.
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+# Use only standard c++ to keep code portable
+set(CMAKE_CXX_EXTENSIONS OFF)
+
if(MSVC)
-# disable C4819 code-page warning
-add_definitions( "/wd4819" )
+ # increase warning level and treat warnings as errors
+ add_compile_options("/WX")
+ add_compile_options("/W3")
+
+ # disable C4819 code-page warning
+ add_compile_options("/wd4819")
+
+ # disable use of POSIX name warnings
+ add_definitions("/D_CRT_NONSTDC_NO_WARNINGS /D_CRT_SECURE_NO_WARNINGS")
+
+ # supress C4503 - VC++ dislikes if a name is too long. If you get
+ # weird and mysterious linking errors, you can disable this, but you'll have to
+ # deal with a LOT of compiler noise over it
+ # see https://msdn.microsoft.com/en-us/library/074af4b6.aspx
+ add_compile_options("/wd4503")
+
+ # suppress C4267 - VC++ considers a narrowing conversion from size_t to a smaller
+ # integer type a warning. this is technically correct but there are so many instances
+ # of this that we don't want to fix, so....
+ add_compile_options("/wd4267")
+
+ # suppress C4251 - VC++ will warn when exporting an entire class which contains members
+ # referencing unexported compound types as this is potentially unsafe. because we don't
+ # guarantee a stable ABI for exports, we don't really care about this, and so we choose to
+ # be lazy and continue to export entire classes instead of exporting on a method-by-method basis
+ add_compile_options("/wd4251")
+
+ # suppress C4068 - VC++ will warn for unknown pragmas by default. this is equivalent to gcc
+ # -Wno-unknown-pragmas (which is enabled for gcc below).
+ # we could work around this with sufficiently complex macros
+ add_compile_options("/wd4068")
+
+ # suppress C4244 - VC++ warns by default (with /W3) about narrowing conversions that may lose data
+ # (such as double -> int or int32_t -> int16_t). dfhack has many of these, mostly related to Lua
+ # this is equivalent to gcc -Wno_conversions which is the default as gcc -Wall doesn't enable -Wconversions
+ add_compile_options("/wd4244")
+
+ # Enable C5038 - This is equivalent to gcc's -Werror=reorder, which is enabled by default by gcc -Wall
+ add_compile_options("/w15038")
+
+ # Enable C4062 - Warns about missing enum case in switch statement, equivalent to gcc -Wswitch
+ add_compile_options("/w14062")
+
+ # MSVC panics if an object file contains more than 65,279 sections. this
+ # happens quite frequently with code that uses templates, such as vectors.
+ add_compile_options("/bigobj")
endif()
-IF(CMAKE_CROSSCOMPILING)
- SET(DFHACK_NATIVE_BUILD_DIR "DFHACK_NATIVE_BUILD_DIR-NOTFOUND" CACHE FILEPATH "Path to a native build directory")
- INCLUDE("${DFHACK_NATIVE_BUILD_DIR}/ImportExecutables.cmake")
-ENDIF()
+# Automatically detect architecture based on Visual Studio generator
+if(MSVC AND NOT DEFINED DFHACK_BUILD_ARCH)
+ if ((${CMAKE_GENERATOR} MATCHES "Win32") OR (${CMAKE_GENERATOR} MATCHES "x86"))
+ message(SEND_ERROR "DF v50 does not support 32-bit")
+ else()
+ set(DFHACK_BUILD_ARCH "64")
+ endif()
+else()
+ set(DFHACK_BUILD_ARCH "64" CACHE STRING "Architecture to build ('32' or '64')")
+endif()
-# set up folder structures for IDE solutions
-# MSVC Express won't load solutions that use this. It also doesn't include MFC supported
-# Check for MFC!
-find_package(MFC QUIET)
-if(MFC_FOUND OR (NOT MSVC))
- OPTION(CMAKE_USE_FOLDERS "Enable folder grouping of projects in IDEs." ON)
+if("${DFHACK_BUILD_ARCH}" STREQUAL "32")
+ set(DFHACK_BUILD_32 1)
+ set(DFHACK_BUILD_64 0)
+ set(DFHACK_SETARCH "i386")
+elseif("${DFHACK_BUILD_ARCH}" STREQUAL "64")
+ set(DFHACK_BUILD_32 0)
+ set(DFHACK_BUILD_64 1)
+ set(DFHACK_SETARCH "x86_64")
+ add_definitions(-DDFHACK64)
else()
- OPTION(CMAKE_USE_FOLDERS "Enable folder grouping of projects in IDEs." OFF)
+ message(SEND_ERROR "Invalid build architecture (should be 32 or 64): ${DFHACK_BUILD_ARCH}")
endif()
+if(CMAKE_CROSSCOMPILING)
+ set(DFHACK_NATIVE_BUILD_DIR "DFHACK_NATIVE_BUILD_DIR-NOTFOUND" CACHE FILEPATH "Path to a native build directory")
+ include("${DFHACK_NATIVE_BUILD_DIR}/ImportExecutables.cmake")
+endif()
+
+find_package(Perl REQUIRED)
+
+# set up folder structures for IDE solutions
+# checking for msvc express is meaningless now, all available editions of msvc support folder groupings
+option(CMAKE_USE_FOLDERS "Enable folder grouping of projects in IDEs." ON)
+
if(CMAKE_USE_FOLDERS)
- SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS ON)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
else()
- SET_PROPERTY(GLOBAL PROPERTY USE_FOLDERS OFF)
+ set_property(GLOBAL PROPERTY USE_FOLDERS OFF)
endif()
-# macro for setting up IDE folders without nasty IF()s everywhere
-MACRO(IDE_FOLDER target folder)
+# macro for setting up IDE folders without nasty if()s everywhere
+macro(IDE_FOLDER target folder)
if(CMAKE_USE_FOLDERS)
- SET_PROPERTY(TARGET ${target} PROPERTY FOLDER ${folder})
+ set_property(TARGET ${target} PROPERTY FOLDER ${folder})
endif()
-ENDMACRO()
+endmacro()
-SET(CMAKE_MODULE_PATH
-${dfhack_SOURCE_DIR}/CMake/Modules
-${CMAKE_MODULE_PATH}
+set(CMAKE_MODULE_PATH
+ ${dfhack_SOURCE_DIR}/CMake/Modules
+ ${CMAKE_MODULE_PATH}
)
# generates compile_commands.json, used for autocompletion by some editors
-SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+include(CheckCXXSourceCompiles)
+check_cxx_source_compiles("
+#include
+#include
+int main(void) {
+ char32_t in = 0;
+ char out[MB_CUR_MAX];
+ std::mbstate_t state{};
+ std::c32rtomb(out, in, &state);
+ return 0;
+}" HAVE_CUCHAR2)
+if(HAVE_CUCHAR2)
+ add_definitions("-DHAVE_CUCHAR")
+endif()
# mixing the build system with the source code is ugly and stupid. enforce the opposite :)
-if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
- message(FATAL_ERROR "In-source builds are not allowed.")
+if("${dfhack_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+ message(FATAL_ERROR "In-source builds are not allowed.")
endif()
# make sure all the necessary submodules have been set up
-if (NOT EXISTS ${dfhack_SOURCE_DIR}/library/xml/codegen.pl OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/clsocket/CMakeLists.txt)
- message(SEND_ERROR "One or more required submodules could not be found! Run 'git submodule update --init' from the root DFHack directory. (See the section 'Getting the Code' in docs/Compile.rst)")
+if(NOT EXISTS ${dfhack_SOURCE_DIR}/library/xml/codegen.pl
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/scripts/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/dfhooks/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/clsocket/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/jsoncpp-sub/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/libexpat/expat/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/libzip/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/xlsxio/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/googletest/CMakeLists.txt
+ OR NOT EXISTS ${dfhack_SOURCE_DIR}/depends/luacov/src
+)
+ message(SEND_ERROR "One or more required submodules could not be found! Run 'git submodule update --init' from the root DFHack directory. (See the section 'Getting the Code' in docs/dev/compile/Compile.rst)")
endif()
-# set up versioning.
-set(DF_VERSION "0.43.03")
-SET(DFHACK_RELEASE "r1")
-SET(DFHACK_PRERELEASE FALSE)
-
-set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")
+# dfhack data goes here:
+set(DFHACK_DATA_DESTINATION hack)
## where to install things (after the build is done, classic 'make install' or package structure)
# the dfhack libraries will be installed here:
-IF(UNIX)
- # put the lib into DF/hack
- SET(DFHACK_LIBRARY_DESTINATION hack)
- SET(DFHACK_EGGY_DESTINATION libs)
-ELSE()
- # windows is crap, therefore we can't do nice things with it. leave the libs on a nasty pile...
- SET(DFHACK_LIBRARY_DESTINATION .)
- SET(DFHACK_EGGY_DESTINATION .)
-ENDIF()
+
+# put the lib into DF/hack
+# windows will find it because dfhooks will `AddDllDirectory` the hack folder at runtime
+set(DFHACK_LIBRARY_DESTINATION ${DFHACK_DATA_DESTINATION})
+
# external tools will be installed here:
-SET(DFHACK_BINARY_DESTINATION .)
-# dfhack data goes here:
-SET(DFHACK_DATA_DESTINATION hack)
+set(DFHACK_BINARY_DESTINATION .)
# plugin libs go here:
-SET(DFHACK_PLUGIN_DESTINATION hack/plugins)
-# dfhack header files go here:
-SET(DFHACK_INCLUDES_DESTINATION hack/include)
+set(DFHACK_PLUGIN_DESTINATION ${DFHACK_DATA_DESTINATION}/plugins)
# dfhack lua files go here:
-SET(DFHACK_LUA_DESTINATION hack/lua)
-# the windows .lib file goes here:
-SET(DFHACK_DEVLIB_DESTINATION hack)
+set(DFHACK_LUA_DESTINATION ${DFHACK_DATA_DESTINATION}/lua)
# user documentation goes here:
-SET(DFHACK_USERDOC_DESTINATION hack)
-# developer documentation goes here:
-SET(DFHACK_DEVDOC_DESTINATION hack)
-
-## some options for the user/developer to play with
-OPTION(BUILD_LIBRARY "Build the library that goes into DF." ON)
-OPTION(BUILD_PLUGINS "Build the plugins." ON)
-
-IF(UNIX)
- ## flags for GCC
- # default to hidden symbols
- # build 32bit
- # ensure compatibility with older CPUs
- # enable C++11 features
- add_definitions(-DLINUX_BUILD)
- SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -Wall -Wno-unused-variable")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -m32 -march=i686 -mtune=generic -std=c++0x")
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -m32 -march=i686 -mtune=generic")
-ELSEIF(MSVC)
- # for msvc, tell it to always use 8-byte pointers to member functions to avoid confusion
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /vmg /vmm /MP")
- SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od")
-ENDIF()
+set(DFHACK_USERDOC_DESTINATION ${DFHACK_DATA_DESTINATION})
+
+# some options for the user/developer to play with
+option(BUILD_LIBRARY "Build the DFHack library." ON)
+option(BUILD_PLUGINS "Build the DFHack plugins." ON)
+option(INSTALL_SCRIPTS "Install DFHack scripts." ON)
+option(INSTALL_DATA_FILES "Install DFHack platform independent files." ON)
+
+set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
+if(UNIX)
+ ## flags for GCC
+ # default to hidden symbols
+ # ensure compatibility with older CPUs
+ add_definitions(-DLINUX_BUILD)
+ set(GCC_COMMON_FLAGS "-fvisibility=hidden -mtune=generic -Wall -Werror -Wl,--disable-new-dtags -Wno-unknown-pragmas")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COMMON_FLAGS}")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCC_COMMON_FLAGS}")
+ if(DFHACK_BUILD_64)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -mno-avx")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 -mno-avx")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -march=i686")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -march=i686")
+ endif()
+ string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+ set(CMAKE_INSTALL_RPATH "$ORIGIN")
+elseif(MSVC)
+ # for msvc, tell it to always use 8-byte pointers to member functions to avoid confusion
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /vmg /vmm /MP")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od")
+ string(REPLACE "/O2" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+ string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+
+ option(BUILD_PDBS "Build PDB debug symbol files." OFF)
+ if(BUILD_PDBS)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Z7")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /DEBUG")
+ set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /DEBUG")
+ endif()
+endif()
# use shared libraries for protobuf
-ADD_DEFINITIONS(-DPROTOBUF_USE_DLLS)
-ADD_DEFINITIONS(-DLUA_BUILD_AS_DLL)
+add_definitions(-DPROTOBUF_USE_DLLS)
+add_definitions(-DLUA_BUILD_AS_DLL)
if(APPLE)
add_definitions(-D_DARWIN)
@@ -173,19 +300,125 @@ elseif(WIN32)
add_definitions(-DWIN32)
endif()
-#### expose depends ####
+#### dependencies ####
+
+# fix for pyenv: default to `python3` before `python3.x`
+set(Python_FIND_UNVERSIONED_NAMES FIRST)
-# find and make available libz
-if(NOT UNIX)
- SET(ZLIB_ROOT depends/zlib/)
+include(CMake/DownloadFile.cmake)
+
+if(WIN32)
+ set(ZLIB_FILE zlib.lib)
+ set(ZLIB_PATH ${dfhack_SOURCE_DIR}/depends/zlib/)
+ set(ZLIB_MD5 a3b2fc6b68efafa89b0882e354fc8418)
+ download_file("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/win64-${ZLIB_FILE}"
+ ${ZLIB_PATH}lib/${ZLIB_FILE}
+ ${ZLIB_MD5})
+ set(ZLIB_ROOT ${ZLIB_PATH})
else()
- set(ZLIB_ROOT /usr/lib/i386-linux-gnu)
+ # Rescan for pthread and zlib if the build arch changed
+ if(NOT "${DFHACK_BUILD_ARCH}" STREQUAL "${DFHACK_BUILD_ARCH_PREV}")
+ unset(ZLIB_LIBRARY CACHE)
+ unset(CMAKE_HAVE_PTHREAD_H CACHE)
+ endif()
+
+ if(NOT APPLE AND DFHACK_BUILD_32)
+ set(ZLIB_ROOT /usr/lib/i386-linux-gnu)
+ endif()
endif()
find_package(ZLIB REQUIRED)
-include_directories(depends/protobuf)
-include_directories(depends/lua/include)
-include_directories(depends/md5)
-include_directories(depends/jsoncpp)
+
+set(USE_SYSTEM_SDL2 OFF CACHE BOOL "Set to ON to use the system SDL2 headers.")
+
+if(BUILD_LIBRARY)
+ if(USE_SYSTEM_SDL2)
+ find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2)
+ else()
+ # Download SDL release and extract into depends in the build dir
+ # all we need are the header files (including generated headers), so the same release package
+ # will work for all platforms
+ # (the above statement is untested for OSX)
+ set(SDL_VERSION 2.26.2)
+ set(SDL_ZIP_MD5 574daf26d48de753d0b1e19823c9d8bb)
+ set(SDL_ZIP_FILE SDL2-devel-${SDL_VERSION}-VC.zip)
+ set(SDL_ZIP_PATH ${dfhack_SOURCE_DIR}/depends/SDL2/)
+ download_file("https://github.com/libsdl-org/SDL/releases/download/release-${SDL_VERSION}/${SDL_ZIP_FILE}"
+ ${SDL_ZIP_PATH}${SDL_ZIP_FILE}
+ ${SDL_ZIP_MD5})
+ file(ARCHIVE_EXTRACT INPUT ${SDL_ZIP_PATH}${SDL_ZIP_FILE}
+ DESTINATION ${SDL_ZIP_PATH})
+ set(SDL2_INCLUDE_DIRS ${SDL_ZIP_PATH}/SDL2-${SDL_VERSION}/include)
+ endif()
+endif()
+
+# this can be made conditional once we get to better platform support for std::format
+INCLUDE(FetchContent)
+FetchContent_Declare(
+ fmt
+ GIT_REPOSITORY https://github.com/fmtlib/fmt.git
+ GIT_TAG 790b9389ae99c4ddebdd2736a8602eca1fec684e # 12.1.0 + bugfix for MSVC warning + build time improvements
+)
+FetchContent_MakeAvailable(fmt)
+set(FMTLIB fmt)
+add_definitions("-DUSE_FMTLIB")
+
+if(APPLE)
+ # libstdc++ (GCC 4.8.5 for OS X 10.6)
+ # fixes crash-on-unwind bug in DF's libstdc++
+ set(LIBSTDCXX_DOWNLOAD_DIR ${dfhack_SOURCE_DIR}/package/darwin/osx${DFHACK_BUILD_ARCH})
+
+ if(${GCC_VERSION_OUT} VERSION_LESS "4.9")
+ set(LIBSTDCXX_GCC_VER "48")
+ else()
+ set(LIBSTDCXX_GCC_VER "7")
+ set(LIBSTDCXX_DOWNLOAD_DIR "${LIBSTDCXX_DOWNLOAD_DIR}-gcc7")
+ endif()
+
+ if(${DFHACK_BUILD_ARCH} STREQUAL "64")
+ if(${LIBSTDCXX_GCC_VER} STREQUAL "48")
+ download_file_unzip("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/osx64-gcc48-libstdcxx.6.dylib.gz"
+ "gz"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib.gz
+ "cf26ed588be8e83c8e3a49919793b416"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib
+ "16dc6dbd4ecde7f9b95bb6dc91f07404")
+ else()
+ # GCC 7
+ download_file_unzip("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/osx64-gcc7-libstdcxx.6.dylib.gz"
+ "gz"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib.gz
+ "81314b7846f9e8806409bef2160c76e6"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib
+ "93b6cf4b01e9a9084a508fd6a4a88992")
+ endif()
+
+ else() # 32-bit
+
+ if(${LIBSTDCXX_GCC_VER} STREQUAL "48")
+ download_file_unzip("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/osx32-gcc48-libstdcxx.6.dylib.gz"
+ "gz"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib.gz
+ "40f3d83871b114f0279240626311621b"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib
+ "c3f5678b8204917e03870834902c3e8b")
+ else()
+ # GCC 7
+ download_file_unzip("https://github.com/DFHack/dfhack-bin/releases/download/0.44.09/osx32-gcc7-libstdcxx.6.dylib.gz"
+ "gz"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib.gz
+ "dbd213171f66edb90d204d525f10c969"
+ ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib
+ "b14c857e7e485a097c70a9ccd3132da7")
+ endif()
+ endif()
+
+ if(NOT EXTERNAL_LIBSTDCXX)
+ install(PROGRAMS ${LIBSTDCXX_DOWNLOAD_DIR}/libstdc++.6.dylib
+ DESTINATION ./hack/)
+ endif()
+endif()
+
+#### expose depends ####
# Support linking against external tinyxml
# If we find an external tinyxml, set the DFHACK_TINYXML variable to "tinyxml"
@@ -196,16 +429,25 @@ if(EXTERNAL_TINYXML)
if(NOT TinyXML_FOUND)
message(SEND_ERROR "Could not find an external TinyXML, consider setting EXTERNAL_TINYXML to OFF.")
endif()
- SET(DFHACK_TINYXML "tinyxml")
+ set(DFHACK_TINYXML "tinyxml")
else()
- include_directories(depends/tinyxml)
- SET(DFHACK_TINYXML "dfhack-tinyxml")
+ set(DFHACK_TINYXML "dfhack-tinyxml")
endif()
-include_directories(depends/tthread)
-include_directories(${ZLIB_INCLUDE_DIRS})
-include_directories(depends/clsocket/src)
-add_subdirectory(depends)
+if(BUILD_LIBRARY)
+ add_subdirectory(depends)
+endif()
+
+# Testing with CTest
+macro(dfhack_test name files)
+if(BUILD_LIBRARY AND UNIX AND NOT APPLE) # remove this once our MSVC build env has been updated
+ add_executable(${name} ${files})
+ target_include_directories(${name} PUBLIC depends/googletest/googletest/include)
+ target_link_libraries(${name} dfhack ${FMTLIB} gtest)
+ add_test(NAME ${name} COMMAND ${name})
+endif()
+endmacro()
+include(CTest)
find_package(Git REQUIRED)
if(NOT GIT_FOUND)
@@ -213,92 +455,198 @@ if(NOT GIT_FOUND)
endif()
# build the lib itself
-IF(BUILD_LIBRARY)
- add_subdirectory (library)
- install(FILES LICENSE.rst NEWS.rst DESTINATION ${DFHACK_USERDOC_DESTINATION})
+add_subdirectory(library)
+if(BUILD_LIBRARY)
+ file(WRITE ${CMAKE_BINARY_DIR}/dfhack_setarch.txt ${DFHACK_SETARCH})
+ install(FILES ${CMAKE_BINARY_DIR}/dfhack_setarch.txt DESTINATION ${DFHACK_DATA_DESTINATION})
endif()
-install(DIRECTORY dfhack-config/ DESTINATION dfhack-config/default)
+# build the plugins
+add_subdirectory(plugins)
-#build the plugins
-IF(BUILD_PLUGINS)
- add_subdirectory (plugins)
+if(INSTALL_DATA_FILES)
+ add_subdirectory(data)
+ install(FILES LICENSE.rst DESTINATION ${DFHACK_USERDOC_DESTINATION})
+ install(FILES docs/changelog-placeholder.txt DESTINATION ${DFHACK_USERDOC_DESTINATION} RENAME changelog.txt)
+ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/depends/luacov/src/luacov/ DESTINATION ${DFHACK_DATA_DESTINATION}/lua/luacov)
endif()
-add_subdirectory(scripts)
-
-find_package(Sphinx QUIET)
-if (BUILD_DOCS)
- if (NOT SPHINX_FOUND)
- message(SEND_ERROR "Sphinx not found but BUILD_DOCS enabled")
- endif()
-
- file(GLOB SPHINX_DEPS
- "${CMAKE_CURRENT_SOURCE_DIR}/docs/*.rst"
- "${CMAKE_CURRENT_SOURCE_DIR}/docs/images/*.png"
- "${CMAKE_CURRENT_SOURCE_DIR}/docs/styles/*"
- "${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
- "${CMAKE_CURRENT_SOURCE_DIR}/scripts/about.txt"
- "${CMAKE_CURRENT_SOURCE_DIR}/scripts/*/about.txt"
- )
- file(GLOB_RECURSE SPHINX_SCRIPT_DEPS
- "${CMAKE_CURRENT_SOURCE_DIR}/scripts/*.lua"
- "${CMAKE_CURRENT_SOURCE_DIR}/scripts/*.rb"
- )
- set(SPHINX_DEPS ${SPHINX_DEPS} ${SPHINX_SCRIPT_DEPS}
- "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.rst"
- "${CMAKE_CURRENT_SOURCE_DIR}/NEWS.rst"
- "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
- )
-
- set(SPHINX_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/html/.buildinfo")
- set_source_files_properties(${SPHINX_OUTPUT} PROPERTIES GENERATED TRUE)
- add_custom_command(OUTPUT ${SPHINX_OUTPUT}
- COMMAND ${SPHINX_EXECUTABLE}
- -a -E -q -b html
- "${CMAKE_CURRENT_SOURCE_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}/docs/html"
- -w "${CMAKE_CURRENT_SOURCE_DIR}/docs/_sphinx-warnings.txt"
- -j 2
- DEPENDS ${SPHINX_DEPS}
- COMMENT "Building HTML documentation with Sphinx"
- )
-
- add_custom_target(dfhack_docs ALL
- DEPENDS ${SPHINX_OUTPUT}
- )
- # Sphinx doesn't touch this file if it didn't make changes,
- # which makes CMake think it didn't complete
- add_custom_command(TARGET dfhack_docs POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E touch ${SPHINX_OUTPUT})
-
- install(DIRECTORY ${dfhack_SOURCE_DIR}/docs/html/
- DESTINATION ${DFHACK_USERDOC_DESTINATION}/docs
- )
- install(FILES "README.html" DESTINATION "${DFHACK_DATA_DESTINATION}")
+if(INSTALL_SCRIPTS)
+ add_subdirectory(scripts)
+endif()
+
+if(BUILD_DOCS)
+ find_package(Python3)
+ find_package(Sphinx)
+
+ if(NOT SPHINX_FOUND)
+ message(SEND_ERROR "Sphinx not found but BUILD_DOCS enabled")
+ endif()
+
+ file(GLOB SPHINX_GLOB_DEPS
+ LIST_DIRECTORIES false
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/images/*.png"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/styles/*"
+ "${CMAKE_CURRENT_SOURCE_DIR}/data/init/*init"
+ )
+ file(GLOB_RECURSE SPHINX_GLOB_RECURSE_DEPS
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.rst"
+ "${CMAKE_CURRENT_SOURCE_DIR}/changelog.txt"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/*py"
+ )
+ list(FILTER SPHINX_GLOB_RECURSE_DEPS
+ EXCLUDE REGEX "docs/changelogs"
+ )
+ list(FILTER SPHINX_GLOB_RECURSE_DEPS
+ EXCLUDE REGEX "docs/html"
+ )
+ list(FILTER SPHINX_GLOB_RECURSE_DEPS
+ EXCLUDE REGEX "docs/tags"
+ )
+ list(FILTER SPHINX_GLOB_RECURSE_DEPS
+ EXCLUDE REGEX "docs/text"
+ )
+ list(FILTER SPHINX_GLOB_RECURSE_DEPS
+ EXCLUDE REGEX "docs/tools"
+ )
+ set(SPHINX_DEPS ${SPHINX_GLOB_DEPS} ${SPHINX_GLOB_RECURSE_DEPS} ${SPHINX_SCRIPT_DEPS}
+ "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt"
+ "${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
+ )
+
+ if(BUILD_DOCS_NO_HTML)
+ set(SPHINX_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/text/index.txt")
+ set(SPHINX_BUILD_TARGETS text)
+ else()
+ set(SPHINX_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/html/.buildinfo")
+ set(SPHINX_BUILD_TARGETS html text)
+ endif()
+
+ set_property(
+ DIRECTORY PROPERTY ADDITIONAL_CLEAN_FILES TRUE
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/changelogs"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/html"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/pdf"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/pseudoxml"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/tags"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/text"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/tools"
+ "${CMAKE_CURRENT_SOURCE_DIR}/docs/xml"
+ "${CMAKE_BINARY_DIR}/docs/html"
+ "${CMAKE_BINARY_DIR}/docs/pdf"
+ "${CMAKE_BINARY_DIR}/docs/pseudoxml"
+ "${CMAKE_BINARY_DIR}/docs/text"
+ "${CMAKE_BINARY_DIR}/docs/xml"
+ )
+
+ add_custom_command(OUTPUT ${SPHINX_OUTPUT}
+ COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/docs/build.py"
+ ${SPHINX_BUILD_TARGETS} --sphinx="${SPHINX_EXECUTABLE}" --quiet -- -W
+ DEPENDS ${SPHINX_DEPS}
+ COMMENT "Building documentation with Sphinx"
+ )
+
+ add_custom_target(dfhack_docs ALL
+ DEPENDS ${SPHINX_OUTPUT}
+ )
+ # Sphinx doesn't touch this file if it didn't make changes,
+ # which makes CMake think it didn't complete
+ add_custom_command(TARGET dfhack_docs POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E touch ${SPHINX_OUTPUT})
+
+ if(NOT BUILD_DOCS_NO_HTML)
+ install(DIRECTORY ${dfhack_SOURCE_DIR}/docs/html/
+ DESTINATION ${DFHACK_USERDOC_DESTINATION}/docs
+ FILES_MATCHING PATTERN "*"
+ PATTERN html/_sources EXCLUDE)
+ endif()
+ install(DIRECTORY ${dfhack_SOURCE_DIR}/docs/text/
+ DESTINATION ${DFHACK_USERDOC_DESTINATION}/docs)
+ install(FILES docs/changelogs/news.rst docs/changelogs/news-dev.rst DESTINATION ${DFHACK_USERDOC_DESTINATION})
+ install(FILES "README.html" DESTINATION "${DFHACK_DATA_DESTINATION}")
+endif()
+
+option(BUILD_TESTS "Include tests (currently just installs Lua tests into the scripts folder)" OFF)
+if(BUILD_TESTS)
+ if(EXISTS "${dfhack_SOURCE_DIR}/test/scripts")
+ message(SEND_ERROR "test/scripts must not exist in the dfhack repo since it would conflict with the tests installed from the scripts repo.")
+ endif()
+ install(DIRECTORY ${dfhack_SOURCE_DIR}/test
+ DESTINATION ${DFHACK_DATA_DESTINATION}/scripts)
+ install(FILES ci/test.lua DESTINATION ${DFHACK_DATA_DESTINATION}/scripts)
endif()
# Packaging with CPack!
-SET(DFHACK_PACKAGE_SUFFIX "")
-IF(UNIX)
+set(DFHACK_PACKAGE_SUFFIX "")
+if(UNIX)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
string(STRIP ${GCC_VERSION} GCC_VERSION)
- SET(DFHACK_PACKAGE_SUFFIX "-gcc-${GCC_VERSION}")
- if(APPLE)
- SET(CPACK_GENERATOR "ZIP;TBZ2")
- else()
- SET(CPACK_GENERATOR "TBZ2")
- endif()
-ELSEIF(WIN32)
- SET(CPACK_GENERATOR "ZIP")
-ENDIF()
+ set(DFHACK_PACKAGE_SUFFIX "-gcc-${GCC_VERSION}")
+ set(CPACK_GENERATOR "TBZ2")
+elseif(WIN32)
+ set(CPACK_GENERATOR "ZIP")
+endif()
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
-IF(APPLE)
+if(APPLE)
set(DFHACK_PACKAGE_PLATFORM_NAME OSX)
-ELSE()
+else()
set(DFHACK_PACKAGE_PLATFORM_NAME ${CMAKE_SYSTEM_NAME})
-ENDIF()
-set(CPACK_PACKAGE_FILE_NAME "dfhack-${DFHACK_VERSION}-${DFHACK_PACKAGE_PLATFORM_NAME}${DFHACK_PACKAGE_SUFFIX}")
-INCLUDE(CPack)
+endif()
+# set on command line
+if(DFHACK_BUILD_ID STREQUAL "")
+ set(DFHACK_BUILD_ID_PACKAGE "")
+else()
+ set(DFHACK_BUILD_ID_PACKAGE "${DFHACK_BUILD_ID}-")
+endif()
+set(CPACK_PACKAGE_FILE_NAME "dfhack-${DFHACK_VERSION}-${DFHACK_BUILD_ID_PACKAGE}${DFHACK_PACKAGE_PLATFORM_NAME}-${DFHACK_BUILD_ARCH}bit${DFHACK_PACKAGE_SUFFIX}")
+include(CPack)
+
+option(DFHACK_INCLUDE_CORE "Download and include Dwarf Fortress core files in DFHack. Useful for local testing, but should not be used in releases." OFF)
+if(DFHACK_INCLUDE_CORE)
+ string(REPLACE "." "_" DF_CORE_FILENAME "${DF_VERSION}")
+ string(REGEX REPLACE "^0_" "df_" DF_CORE_FILENAME "${DF_CORE_FILENAME}")
+ if(UNIX)
+ if(APPLE)
+ string(APPEND DF_CORE_FILENAME "_osx")
+ else()
+ string(APPEND DF_CORE_FILENAME "_linux")
+ endif()
+ if(DFHACK_BUILD_32)
+ string(APPEND DF_CORE_FILENAME "32")
+ endif()
+ string(APPEND DF_CORE_FILENAME ".tar.bz2")
+ else()
+ string(APPEND DF_CORE_FILENAME "_win")
+ if(DFHACK_BUILD_32)
+ string(APPEND DF_CORE_FILENAME "32")
+ endif()
+ string(APPEND DF_CORE_FILENAME ".zip")
+ endif()
+ set(DF_CORE_URL "http://bay12games.com/dwarves/${DF_CORE_FILENAME}")
+ if(NOT EXISTS "${CMAKE_BINARY_DIR}/${DF_CORE_FILENAME}")
+ file(DOWNLOAD "${DF_CORE_URL}" "${CMAKE_BINARY_DIR}/${DF_CORE_FILENAME}" SHOW_PROGRESS)
+ endif()
+ file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/df-core")
+ file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/df-core")
+ if(UNIX)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xjf "../${DF_CORE_FILENAME}" --strip-components=1
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/df-core")
+ else()
+ execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "../${DF_CORE_FILENAME}" --format=zip
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/df-core")
+ file(REMOVE "${CMAKE_BINARY_DIR}/df-core/SDL.dll")
+ endif()
+ install(DIRECTORY "${CMAKE_BINARY_DIR}/df-core/"
+ DESTINATION .)
+endif()
+
+# Store old build arch
+set(DFHACK_BUILD_ARCH_PREV "${DFHACK_BUILD_ARCH}" CACHE STRING "Previous build architecture" FORCE)
+
+option(BUILD_SIZECHECK "Build the sizecheck library, for research" OFF)
+if(BUILD_LIBRARY AND BUILD_SIZECHECK)
+ add_subdirectory(depends/sizecheck)
+ add_dependencies(dfhack sizecheck)
+endif()
-#INCLUDE(FindSphinx.cmake)
+add_subdirectory(package)
diff --git a/CMakeSettings.json b/CMakeSettings.json
new file mode 100644
index 0000000000..d1511716f7
--- /dev/null
+++ b/CMakeSettings.json
@@ -0,0 +1,284 @@
+{
+ "configurations": [
+ {
+ "name": "MSVC 64 Debug",
+ "generator": "Ninja",
+ "configurationType": "RelWithDebInfo",
+ "inheritEnvironments": [ "msvc_x64_x64" ],
+ "variables": [
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "64"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ },
+ {
+ "name": "REMOVE_SYMBOLS_FROM_DF_STUBS",
+ "value": "0"
+ },
+ {
+ "name": "DFHACK_INCLUDE_CORE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "MSVC 64 Release",
+ "generator": "Ninja",
+ "configurationType": "Release",
+ "inheritEnvironments": [ "msvc_x64_x64" ],
+ "variables": [
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "64"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 32 Debug",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/debug-32",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "RelWithDebInfo",
+ "intelliSenseMode": "linux-gcc-x86",
+ "variables": [
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "32"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ },
+ {
+ "name": "REMOVE_SYMBOLS_FROM_DF_STUBS",
+ "value": "0"
+ },
+ {
+ "name": "DFHACK_INCLUDE_CORE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 32 Release",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/release-32",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "Release",
+ "intelliSenseMode": "linux-gcc-x86",
+ "variables": [
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "32"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 64 Debug",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/debug-64",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "RelWithDebInfo",
+ "intelliSenseMode": "linux-gcc-x64",
+ "variables": [
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "64"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ },
+ {
+ "name": "REMOVE_SYMBOLS_FROM_DF_STUBS",
+ "value": "0"
+ },
+ {
+ "name": "DFHACK_INCLUDE_CORE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 64 Release",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/release-64",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "Release",
+ "intelliSenseMode": "linux-gcc-x64",
+ "variables": [
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "64"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 4.8 32 Debug",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/debug-32-48",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "RelWithDebInfo",
+ "intelliSenseMode": "linux-gcc-x86",
+ "variables": [
+ {
+ "name": "CMAKE_C_COMPILER",
+ "value": "gcc-4.8"
+ },
+ {
+ "name": "CMAKE_CXX_COMPILER",
+ "value": "g++-4.8"
+ },
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "32"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ },
+ {
+ "name": "REMOVE_SYMBOLS_FROM_DF_STUBS",
+ "value": "0"
+ },
+ {
+ "name": "DFHACK_INCLUDE_CORE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 4.8 32 Release",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/release-32-48",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "Release",
+ "intelliSenseMode": "linux-gcc-x86",
+ "variables": [
+ {
+ "name": "CMAKE_C_COMPILER",
+ "value": "gcc-4.8"
+ },
+ {
+ "name": "CMAKE_CXX_COMPILER",
+ "value": "g++-4.8"
+ },
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "32"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 4.8 64 Debug",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/debug-64-48",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "RelWithDebInfo",
+ "intelliSenseMode": "linux-gcc-x64",
+ "variables": [
+ {
+ "name": "CMAKE_C_COMPILER",
+ "value": "gcc-4.8"
+ },
+ {
+ "name": "CMAKE_CXX_COMPILER",
+ "value": "g++-4.8"
+ },
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "64"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ },
+ {
+ "name": "REMOVE_SYMBOLS_FROM_DF_STUBS",
+ "value": "0"
+ },
+ {
+ "name": "DFHACK_INCLUDE_CORE",
+ "value": "1"
+ }
+ ]
+ },
+ {
+ "name": "GCC 4.8 64 Release",
+ "remoteMachineName": "${defaultRemoteMachineName}",
+ "remoteCMakeListsRoot": "/tmp/dfhack-${workspaceHash}/src",
+ "remoteBuildRoot": "/tmp/dfhack-${workspaceHash}/release-64-48",
+ "rsyncCommandArgs": "--exclude=build --include=.git",
+ "remoteCopySources": true,
+ "cmakeExecutable": "$(which cmake)/..",
+ "generator": "Ninja",
+ "configurationType": "Release",
+ "intelliSenseMode": "linux-gcc-x64",
+ "variables": [
+ {
+ "name": "CMAKE_C_COMPILER",
+ "value": "gcc-4.8"
+ },
+ {
+ "name": "CMAKE_CXX_COMPILER",
+ "value": "g++-4.8"
+ },
+ {
+ "name": "DFHACK_BUILD_ARCH",
+ "value": "64"
+ },
+ {
+ "name": "BUILD_STONESENSE",
+ "value": "1"
+ }
+ ]
+ }
+ ]
+}
diff --git a/Contributing.rst b/Contributing.rst
deleted file mode 100644
index 2c1e7bb451..0000000000
--- a/Contributing.rst
+++ /dev/null
@@ -1,228 +0,0 @@
-###########################
-How to contribute to DFHack
-###########################
-
-.. contents::
-
-
-.. _contributing-code:
-
-Contributing Code
-=================
-Several things should be kept in mind when contributing code to DFHack.
-
-Code Format
------------
-* Four space indents for C++. Never use tabs for indentation in any language.
-* LF (Unix style) line terminators
-* Avoid trailing whitespace
-* UTF-8 encoding
-* For C++:
-
- * Opening and closing braces on their own lines or opening brace at the end of the previous line
- * Braces placed at original indent level if on their own lines
- * #includes should be sorted. C++ libraries first, then dfhack modules, then df structures,
- then local includes. Within each category they should be sorted alphabetically.
-
-How to get new code into DFHack
--------------------------------
-* Submit pull requests to the ``develop`` branch, not the ``master`` branch.
- (The ``master`` branch always points at the most recent release)
-* Use a new branch for each feature or bugfix so that your changes can be merged independently
- (i.e. not the master or develop branch of your fork).
-* If possible, compile on multiple platforms when changing anything that compiles
-* It must pass CI - run ``python travis/all.py`` to check this.
-* Update ``NEWS.rst`` and ``docs/Authors.rst`` when applicable.
-* Create a GitHub pull request once finished
-* Submit ideas and bug reports as :issue:`issues on GitHub <>`.
- Posts in the forum thread can easily get missed or forgotten.
-* Work on :issue:`reported problems `
- will take priority over ideas or suggestions.
-
-.. _contributing-memory-research:
-
-Memory research
----------------
-If you want to do memory research, you'll need some tools and some knowledge.
-In general, you'll need a good memory viewer and optionally something
-to look at machine code without getting crazy :)
-Using publicly known information and analyzing the game's data is preferred.
-
-Good windows tools include:
-
-* Cheat Engine
-* IDA Pro 5.0 (freely available for non-commercial use)
-
-Good linux tools:
-
-* angavrilov's df-structures gui (visit us on IRC for details).
-* edb (Evan's Debugger)
-* IDA Pro 5.0 running under Wine
-* Some of the tools residing in the ``legacy`` dfhack branch.
-
-Using the library as a developer
-================================
-Currently, the most direct way to use the library is to write a script or plugin that can be loaded by it.
-All the plugins can be found in the 'plugins' folder. There's no in-depth documentation
-on how to write one yet, but it should be easy enough to copy one and just follow the pattern.
-``plugins/skeleton/skeleton.cpp`` is provided for this purpose.
-
-Other than through plugins, it is possible to use DFHack via remote access interface,
-or by writing scripts in Lua or Ruby. There are plenty of examples in the scripts folder.
-The `lua-api` is quite well documented.
-
-The most important parts of DFHack are the Core, Console, Modules and Plugins.
-
-* Core acts as the centerpiece of DFHack - it acts as a filter between DF and
- SDL and synchronizes the various plugins with DF.
-* Console is a thread-safe console that can be used to invoke commands exported by Plugins.
-* Modules actually describe the way to access information in DF's memory. You
- can get them from the Core. Most modules are split into two parts: high-level
- and low-level. High-level is mostly method calls, low-level publicly visible
- pointers to DF's data structures.
-* Plugins are the tools that use all the other stuff to make things happen.
- A plugin can have a list of commands that it exports and an onupdate function
- that will be called each DF game tick.
-
-Rudimentary API documentation can be built using doxygen (see build options
-in ``CMakeCache.txt`` or with ``ccmake`` or ``cmake-gui``). The full DFHack
-documentation is built with Sphinx_, which runs automatically at compile time.
-
-.. _Sphinx: http://www.sphinx-doc.org
-
-DFHack consists of variously licensed code, but invariably weak copyleft.
-The main license is zlib/libpng, some bits are MIT licensed, and some are
-BSD licensed. See the `license` for more information.
-
-Feel free to add your own extensions and plugins. Contributing back to
-the DFHack repository is welcome and the right thing to do :)
-
-DF data structure definitions
------------------------------
-DFHack uses information about the game data structures, represented via xml files
-in the ``library/xml/`` submodule.
-
-See https://github.com/DFHack/df-structures, and the documentation linked in the index.
-
-Data structure layouts are described in files following the ``df.*.xml`` name pattern.
-This information is transformed by a perl script into C++ headers describing the
-structures, and associated metadata for the Lua wrapper. These headers and data
-are then compiled into the DFHack libraries, thus necessitating a compatibility
-break every time layouts change; in return it significantly boosts the efficiency
-and capabilities of DFHack code.
-
-Global object addresses are stored in :file:`symbols.xml`, which is copied to the dfhack
-release package and loaded as data at runtime.
-
-Remote access interface
------------------------
-DFHack supports remote access by exchanging Google protobuf messages via a TCP
-socket. Both the core and plugins can define remotely accessible methods. The
-``dfhack-run`` command uses this interface to invoke ordinary console commands.
-
-Currently the supported set of requests is limited, because the developers don't
-know what exactly is most useful. `remotefortressreader` provides a fairly
-comprehensive interface for visualisers such as :forums:`Armok Vision <146473>`.
-
-
-Documentation Standards
-=======================
-DFHack documentation is built with Sphinx_, and configured automatically
-through CMake. If you want to build the docs *only*, use this command::
-
- sphinx-build . docs/html
-
-Whether you're adding new code or just fixing old documentation (and there's plenty),
-there are a few important standards for completeness and consistent style. Treat
-this section as a guide rather than iron law, match the surrounding text, and you'll
-be fine.
-
-Each command should have a short (~54 character) help string, which is shown
-by the `ls` command. For scripts, this is a comment on the first line
-(the comment marker and whitespace is stripped). For plugins it's the second
-argument to ``PluginCommand``. Please make this brief but descriptive!
-
-Everything should be documented! If it's not clear *where* a particular
-thing should be documented, ask on IRC or in the DFHack thread on Bay12 -
-as well as getting help, you'll be providing valuable feedback that
-makes it easier for future readers!
-
-Scripts can use a custom autodoc function, based on the Sphinx ``include``
-directive - anything between the tokens is copied into the appropriate scripts
-documentation page. For Ruby, we follow the built-in docstring convention
-(``=begin`` and ``=end``). For Lua, the tokens are ``[====[`` and ``]====]``
-- ordinary multi-line strings. It is highly encouraged to reuse this string
-as the in-console documentation by (eg.) printing it when a ``-help`` argument
-is given.
-
-The docs **must** have a heading which exactly matches the command, underlined
-with ``=====`` to the same length. For example, a lua file would have::
-
- local helpstr = [====[
-
- add-thought
- ===========
- Adds a thought or emotion to the selected unit. Can be used by other scripts,
- or the gui invoked by running ``add-thought gui`` with a unit selected.
-
- ]====]
-
-
-Where the heading for a section is also the name of a command, the spelling
-and case should exactly match the command to enter in the DFHack command line.
-
-Try to keep lines within 80-100 characters, so it's readable in plain text
-in the terminal - Sphinx (our documentation system) will make sure
-paragraphs flow.
-
-If there aren't many options or examples to show, they can go in a paragraph of
-text. Use double-backticks to put commands in monospaced font, like this::
-
- You can use ``cleanowned scattered x`` to dump tattered or abandoned items.
-
-If the command takes more than three arguments, format the list as a table
-called Usage. The table *only* lists arguments, not full commands.
-Input values are specified in angle brackets. Example::
-
- Usage:
-
- :arg1: A simple argument.
- :arg2 : Does something based on the input value.
- :Very long argument:
- Is very specific.
-
-To demonstrate usage - useful mainly when the syntax is complicated, list the
-full command with arguments in monospaced font, then indent the next line and
-describe the effect::
-
- ``resume all``
- Resumes all suspended constructions.
-
-If it would be helpful to mention another DFHack command, don't just type the
-name - add a hyperlink! Specify the link target in backticks, and it will be
-replaced with the corresponding title and linked: eg ```autolabor```
-=> `autolabor`. Link targets should be equivalent to the command
-described (without file extension), and placed above the heading of that
-section like this::
-
- .. _autolabor:
-
- autolabor
- =========
-
-Add link targets if you need them, but otherwise plain headings are preferred.
-Scripts have link targets created automatically.
-
-Other ways to help
-==================
-DFHack is a software project, but there's a lot more to it than programming.
-If you're not comfortable programming, you can help by:
-
-* reporting bugs and incomplete documentation
-* improving the documentation
-* finding third-party scripts to add
-* writing tutorials for newbies
-
-All those things are crucial, and often under-represented. So if that's
-your thing, go get started!
-
diff --git a/LICENSE.rst b/LICENSE.rst
index e6a643e3d9..1ab6a682ee 100644
--- a/LICENSE.rst
+++ b/LICENSE.rst
@@ -4,16 +4,19 @@
Licenses
########
-DFHack is distributed under the Zlib license, with some MIT-
-and BSD-licensed components. These licenses protect your right
-to use DFhack for any purpose, distribute copies, and so on.
+DFHack is distributed under the Zlib license, with some MIT- and BSD-licensed
+components. These licenses protect your right to use DFHack for any purpose,
+distribute copies, and so on.
-The core, plugins, scripts, and other DFHack code all use the
-ZLib license unless noted otherwise. By contributing to DFHack,
-authors release the contributed work under this license.
+The core, plugins, scripts, and other DFHack code all use the ZLib license
+unless noted otherwise. By contributing to DFHack, authors release the
+contributed work under this license.
-DFHack also draws on several external packages.
-Their licenses are summarised here and reproduced below.
+Some graphic assets are derived from vanilla DF assets and used with permission
+from Bay12.
+
+DFHack also draws on several external packages. Their licenses are summarised
+here and reproduced below.
=============== ============= =================================================
Component License Copyright
@@ -23,13 +26,19 @@ clsocket_ BSD 3-clause \(c\) 2007-2009, CarrierLabs, LLC.
dirent_ MIT \(c\) 2006, Toni Ronkko
JSON.lua_ CC-BY-SA_ \(c\) 2010-2014, Jeffrey Friedl
jsoncpp_ MIT \(c\) 2007-2010, Baptiste Lepilleur
+libexpat_ MIT \(c\) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper \(c\) 2001-2019 Expat maintainers
+libzip_ BSD 3-clause \(c\) 1999-2020 Dieter Baron and Thomas Klausner
linenoise_ BSD 2-clause \(c\) 2010, Salvatore Sanfilippo & Pieter Noordhuis
lua_ MIT \(c\) 1994-2008, Lua.org, PUC-Rio.
+luacov_ MIT \(c\) 2007 - 2018 Hisham Muhammad
luafilesystem_ MIT \(c\) 2003-2014, Kepler Project
+lua-profiler_ MIT \(c\) 2002,2003,2004 Pepperfish
protobuf_ BSD 3-clause \(c\) 2008, Google Inc.
-tinythread_ Zlib \(c\) 2010, Marcus Geelnard
tinyxml_ Zlib \(c\) 2000-2006, Lee Thomason
UTF-8-decoder_ MIT \(c\) 2008-2010, Bjoern Hoehrmann
+xlsxio_ MIT \(c\) 2016-2020, Brecht Sanders
+alt-getopt_ MIT \(c\) 2009 Aleksey Cheusov
+googletest_ BSD 3-Clause \(c\) 2008, Google Inc.
=============== ============= =================================================
.. _DFHack: https://github.com/DFHack/dfhack
@@ -37,13 +46,19 @@ UTF-8-decoder_ MIT \(c\) 2008-2010, Bjoern Hoehrmann
.. _dirent: https://github.com/tronkko/dirent
.. _JSON.lua: http://regex.info/blog/lua/json
.. _jsoncpp: https://github.com/open-source-parsers/jsoncpp
+.. _libexpat: https://github.com/libexpat/libexpat
+.. _libzip: https://github.com/nih-at/libzip
.. _linenoise: http://github.com/antirez/linenoise
.. _lua: http://www.lua.org
+.. _luacov: https://github.com/keplerproject/luacov
.. _luafilesystem: https://github.com/keplerproject/luafilesystem
+.. _lua-profiler: http://lua-users.org/wiki/PepperfishProfiler
.. _protobuf: https://github.com/google/protobuf
-.. _tinythread: http://tinythreadpp.bitsnbites.eu/
.. _tinyxml: http://www.sourceforge.net/projects/tinyxml
.. _UTF-8-decoder: http://bjoern.hoehrmann.de/utf-8/decoder/dfa
+.. _xlsxio: https://github.com/brechtsanders/xlsxio
+.. _alt-getopt: https://github.com/LuaDist/alt-getopt
+.. _googletest: https://github.com/google/googletest
.. _CC-BY-SA: http://creativecommons.org/licenses/by/3.0/deed.en_US
diff --git a/NEWS.rst b/NEWS.rst
deleted file mode 100644
index dcc87b04af..0000000000
--- a/NEWS.rst
+++ /dev/null
@@ -1,537 +0,0 @@
-.. comment
- This is the changelog file for DFHack. If you add or change anything, note
- it here under the heading "DFHack Future", in the appropriate section.
- Items within each section are listed in alphabetical order to minimise merge
- conflicts. Try to match the style and level of detail of the other entries.
-
- Sections for each release are added as required, and consist solely of the
- following in order as subheadings::
-
- Internals
- Lua
- New [Internal Commands | Plugins | Scripts | Features]
- Fixes
- Misc Improvements
- Removed
-
- When referring to a script, plugin, or command, use backticks (```) to
- create a link to the relevant documentation - and check that the docs are
- still up to date!
-
- When adding a new release, change "DFHack future" to the appropriate title
- before releasing, and then add a new "DFHack future" section after releasing.
-
-.. _changelog:
-
-#########
-Changelog
-#########
-
-.. contents::
- :depth: 2
-
-DFHack 0.43.03-r1
-=================
-
-Lua
----
-- Label widgets can now easily register handlers for mouse clicks
-
-New Features
-------------
-- `add-thought`: allow syndrome name as ``-thought`` argument
-- `gui/gm-editor`
-
- - Added ability to insert default types into containers. For primitive types leave the type entry empty, and for references use ``*``.
- - Added ``shift-esc`` binding to fully exit from editor
- - Added ``gui/gm-editor toggle`` command to toggle editor visibility (saving position)
-
-- `modtools/create-unit`:
-
- - Added an option to attach units to an existing wild animal population
- - Added an option to attach units to a map feature
-
-Fixes
------
-- `autofarm`: Can now handle crops that grow for more than a season
-- `combine-plants`: Fixed recursion into sub-containers
-- `createitem`: Now moves multiple created items to cursor correctly
-- `exportlegends`: Improved handling of unknown enum items (fixes many errors)
-- `gui/create-item`: Fixed quality when creating multiple items
-- `gui/mod-manager`: Fixed error when mods folder doesn't exist
-- `modtools/item-trigger`: Fixed handling of items with subtypes
-- `stockflow`:
-
- - Can order metal mechanisms
- - Fixed material category of thread-spinning jobs
-
-Misc Improvements
------------------
-- The built-in ``ls`` command now wraps the descriptions of commands
-- `catsplosion`: now a lua script instead of a plugin
-- `fix/diplomats`: replaces ``fixdiplomats``
-- `fix/merchants`: replaces ``fixmerchants``
-- Unified script documentation and in-terminal help options
-
-Removed
--------
-- `tweak` manager-quantity: no longer needed
-
-DFHack 0.42.06-r1
-=================
-
-Internals
----------
-- Commands to run on startup can be specified on the command line with ``+``
-
- Example::
-
- ./dfhack +devel/print-args example
- "Dwarf Fortress.exe" +devel/print-args example
-
-- Prevented plugins with active viewscreens from being unloaded and causing a crash
-- Additional script search paths can be specified in dfhack-config/script-paths.txt
-
-Lua
----
-- `building-hacks` now supports ``auto_gears`` flags. It automatically finds and animates gears in building definition
-- Changed how `eventful` triggers reaction complete. Now it has ``onReactionComplete`` and ``onReactionCompleting``. Second one can be canceled
-
-New Plugins
------------
-- `autogems`: Creates a new Workshop Order setting, automatically cutting rough gems
-
-New Scripts
------------
-- `devel/save-version`: Displays DF version information about the current save
-- `modtools/extra-gamelog`: replaces ``log-region``, ``soundsense-season``, and ``soundsense``
-
-New Features
-------------
-- `buildingplan`: Support for floodgates, grates, and bars
-- `colonies`: new ``place`` subcommand and supports any vermin (default honey bees)
-- `confirm`: Added a confirmation for retiring locations
-- `exportlegends`: Exports more information (poetic/musical/dance forms, written/artifact content, landmasses, extra histfig information, and more)
-- `search-plugin`: Support for new screens:
-
- - location occupation assignment
- - civilization animal training knowledge
- - animal trainer assignment
-
-- `tweak`:
-
- - ``tweak block-labors``: Prevents labors that can't be used from being toggled
- - ``tweak hide-priority``: Adds an option to hide designation priority indicators
- - ``tweak title-start-rename``: Adds a safe rename option to the title screen "Start Playing" menu
-
-- `zone`:
-
- - Added ``unassign`` subcommand
- - Added ``only`` option to ``assign`` subcommand
-
-Fixes
------
-- Fixed a crash bug caused by the historical figures DFHack uses to store persistent data.
-- More plugins should recognize non-dwarf citizens
-- Fixed a possible crash from cloning jobs
-- moveToBuilding() now sets flags for items that aren't a structural part of the building properly
-- `autotrade`, `stocks`: Made trading work when multiple caravans are present but only some can trade
-- `confirm` note-delete: No longer interferes with name entry
-- `exportlegends`: Handles entities without specific races, and a few other fixes for things new to v0.42
-- `fastdwarf`: Fixed a bug involving teleporting mothers but not the babies they're holding.
-- `gaydar`: Fixed text display on OS X/Linux and failure with soul-less creatures
-- `manipulator`:
-
- - allowed editing of non-dwarf citizens
- - stopped ghosts and visitors from being editable
- - fixed applying last custom profession
-
-- `modtools/create-unit`: Stopped making units without civs historical figures
-- `modtools/force`:
-
- - Removed siege option
- - Prevented a crash resulting from a bad civilization option
-
-- `showmood`: Fixed name display on OS X/Linux
-- `view-item-info`: Fixed density units
-
-Misc Improvements
------------------
-- `autochop`: Can now edit log minimum/maximum directly and remove limit entirely
-- `autolabor`, `autohauler`, `manipulator`: Added support for new jobs/labors/skills
-- `colonies`: now implemented by a script
-- `createitem`: Can now create items anywhere without specifying a unit, as long as a unit exists on the map
-- `devel/export-dt-ini`: Updated for 0.42.06
-- `devel/find-offsets`: Automated several more scans
-- `gui/gm-editor`: Now supports finding some items with a numeric ID (with ``i``)
-- `lua`: Now supports some built-in variables like `gui/gm-editor`, e.g. ``unit``, ``screen``
-- `remotefortressreader`: Can now trigger keyboard events
-- `stockflow`: Now offers better control over individual craft jobs
-- `weather`: now implemented by a script
-- `zone`: colored output
-
-Removed
--------
-- DFusion: legacy script system, obsolete or replaced by better alternatives
-
-
-DFHack 0.40.24-r5
-=================
-
-New Features
-------------
-- `confirm`:
-
- - Added a ``uniform-delete`` option for military uniform deletion
- - Added a basic in-game configuration UI
-
-Fixes
------
-- Fixed a rare crash that could result from running `keybinding` in onLoadWorld.init
-- Script help that doesn't start with a space is now recognized correctly
-- `confirm`: Fixed issues with haul-delete, route-delete, and squad-disband confirmations intercepting keys too aggressively
-- `emigration` should work now
-- `fix-unit-occupancy`: Significantly optimized - up to 2,000 times faster in large fortresses
-- `gui/create-item`: Allow exiting quantity prompt
-- `gui/family-affairs`: Fixed an issue where lack of relationships wasn't recognized and other issues
-- `modtools/create-unit`: Fixed a possible issue in reclaim fortress mode
-- `search-plugin`: Fixed a crash on the military screen
-- `tweak` max-wheelbarrow: Fixed a minor display issue with large numbers
-- `workflow`: Fixed a crash related to job postings (and added a fix for existing, broken jobs)
-
-Misc Improvements
------------------
-- Unrecognized command feedback now includes more information about plugins
-- `fix/dry-buckets`: replaces the ``drybuckets`` plugin
-- `feature`: now implemented by a script
-
-DFHack 0.40.24-r4
-=================
-
-Internals
----------
-- A method for caching screen output is now available to Lua (and C++)
-- Developer plugins can be ignored on startup by setting the ``DFHACK_NO_DEV_PLUGINS`` environment variable
-- The console on Linux and OS X now recognizes keyboard input between prompts
-- JSON libraries available (C++ and Lua)
-- More DFHack build information used in plugin version checks and available to plugins and lua scripts
-- Fixed a rare overflow issue that could cause crashes on Linux and OS X
-- Stopped DF window from receiving input when unfocused on OS X
-- Fixed issues with keybindings involving :kbd:`Ctrl`:kbd:`A` and :kbd:`Ctrl`:kbd:`Z`,
- as well as :kbd:`Alt`:kbd:`E`/:kbd:`U`/:kbd:`N` on OS X
-- Multiple contexts can now be specified when adding keybindings
-- Keybindings can now use :kbd:`F10`-:kbd:`F12` and :kbd:`0`-:kbd:`9`
-- Plugin system is no longer restricted to plugins that exist on startup
-- :file:`dfhack.init` file locations significantly generalized
-
-Lua
----
-- Scripts can be enabled with the built-in `enable`/`disable ` commands
-- A new function, ``reqscript()``, is available as a safer alternative to ``script_environment()``
-- Lua viewscreens can choose not to intercept the OPTIONS keybinding
-
-New internal commands
----------------------
-- `kill-lua`: Interrupt running Lua scripts
-- `type`: Show where a command is implemented
-
-New plugins
------------
-- `confirm`: Adds confirmation dialogs for several potentially dangerous actions
-- `fix-unit-occupancy`: Fixes issues with unit occupancy, such as faulty "unit blocking tile" messages (:bug:`3499`)
-- `title-version` (formerly ``vshook``): Display DFHack version on title screen
-
-New scripts
------------
-- `armoks-blessing`: Adjust all attributes, personality, age and skills of all dwarves in play
-- `brainwash`: brainwash a dwarf (modifying their personality)
-- `burial`: sets all unowned coffins to allow burial ("-pets" to allow pets too)
-- `deteriorateclothes`: make worn clothes on the ground wear far faster to boost FPS
-- `deterioratecorpses`: make body parts wear away far faster to boost FPS
-- `deterioratefood`: make food vanish after a few months if not used
-- `elevate-mental`: elevate all the mental attributes of a unit
-- `elevate-physical`: elevate all the physical attributes of a unit
-- `emigration`: stressed dwarves may leave your fortress if they see a chance
-- `fix-ster`: changes fertility/sterility of animals or dwarves
-- `gui/family-affairs`: investigate and alter romantic relationships
-- `make-legendary`: modify skill(s) of a single unit
-- `modtools/create-unit`: create new units from nothing
-- `modtools/equip-item`: a script to equip items on units
-- `points`: set number of points available at embark screen
-- `pref-adjust`: Adjust all preferences of all dwarves in play
-- `rejuvenate`: make any "old" dwarf 20 years old
-- `starvingdead`: make undead weaken after one month on the map, and crumble after six
-- `view-item-info`: adds information and customisable descriptions to item viewscreens
-- `warn-starving`: check for starving, thirsty, or very drowsy units and pause with warning if any are found
-
-New tweaks
-----------
-- embark-profile-name: Allows the use of lowercase letters when saving embark profiles
-- kitchen-keys: Fixes DF kitchen meal keybindings
-- kitchen-prefs-color: Changes color of enabled items to green in kitchen preferences
-- kitchen-prefs-empty: Fixes a layout issue with empty kitchen tabs
-
-Fixes
------
-- Plugins with vmethod hooks can now be reloaded on OS X
-- Lua's ``os.system()`` now works on OS X
-- Fixed default arguments in Lua gametype detection functions
-- Circular lua dependencies (reqscript/script_environment) fixed
-- Prevented crash in ``Items::createItem()``
-- `buildingplan`: Now supports hatch covers
-- `gui/create-item`: fixed assigning quality to items, made :kbd:`Esc` work properly
-- `gui/gm-editor`: handles lua tables properly
-- `help`: now recognizes built-in commands, like ``help``
-- `manipulator`: fixed crash when selecting custom professions when none are found
-- `remotefortressreader`: fixed crash when attempting to send map info when no map was loaded
-- `search-plugin`: fixed crash in unit list after cancelling a job; fixed crash when disabling stockpile category after searching in a subcategory
-- `stockpiles`: now checks/sanitizes filenames when saving
-- `stocks`: fixed a crash when right-clicking
-- `steam-engine`: fixed a crash on arena load; number keys (e.g. 2/8) take priority over cursor keys when applicable
-- tweak fps-min fixed
-- tweak farm-plot-select: Stopped controls from appearing when plots weren't fully built
-- `workflow`: Fixed some issues with stuck jobs. Existing stuck jobs must be cancelled and re-added
-- `zone`: Fixed a crash when using ``zone set`` (and a few other potential crashes)
-
-Misc Improvements
------------------
-- DFHack documentation:
-
- - massively reorganised, into files of more readable size
- - added many missing entries
- - indexes, internal links, offline search all documents
- - includes documentation of linked projects (df-structures, third-party scripts)
- - better HTML generation with Sphinx
- - documentation for scripts now located in source files
-
-- `autolabor`:
-
- - Stopped modification of labors that shouldn't be modified for brokers/diplomats
- - Prioritize skilled dwarves more efficiently
- - Prevent dwarves from running away with tools from previous jobs
-
-- `automaterial`: Fixed several issues with constructions being allowed/disallowed incorrectly when using box-select
-- `dwarfmonitor`:
-
- - widgets' positions, formats, etc. are now customizable
- - weather display now separated from the date display
- - New mouse cursor widget
-
-- `gui/dfstatus`: Can enable/disable individual categories and customize metal bar list
-- `full-heal`: ``-r`` option removes corpses
-- `gui/gm-editor`
-
- - Pointers can now be displaced
- - Added some useful aliases: "item" for the selected item, "screen" for the current screen, etc.
- - Now avoids errors with unrecognized types
-
-- `gui/hack-wish`: renamed to `gui/create-item`
-- `keybinding list ` accepts a context
-- `lever`:
-
- - Lists lever names
- - ``lever pull`` can be used to pull the currently-selected lever
-
-- ``memview``: Fixed display issue
-- `modtools/create-item`: arguments are named more clearly, and you can specify the creator to be the unit with id ``df.global.unit_next_id-1`` (useful in conjunction with `modtools/create-unit`)
-- ``nyan``: Can now be stopped with dfhack-run
-- `plug`: lists all plugins; shows state and number of commands in plugins
-- `prospect`: works from within command-prompt
-- `quicksave`: Restricted to fortress mode
-- `remotefortressreader`: Exposes more information
-- `search-plugin`:
-
- - Supports noble suggestion screen (e.g. suggesting a baron)
- - Supports fortress mode loo[k] menu
- - Recognizes ? and ; keys
-
-- `stocks`: can now match beginning and end of item names
-- `teleport`: Fixed cursor recognition
-- `tidlers`, `twaterlvl`: now implemented by scripts instead of a plugin
-- `tweak`:
-
- - debug output now logged to stderr.log instead of console - makes DFHack start faster
- - farm-plot-select: Fixed issues with selecting undiscovered crops
-
-- `workflow`: Improved handling of plant reactions
-
-Removed
--------
-- `embark-tools` nano: 1x1 embarks are now possible in vanilla 0.40.24
-
-DFHack 0.40.24-r3
-=================
-
-Internals
----------
-- Ruby library now included on OS X - Ruby scripts should work on OS X 10.10
-- libstdc++ should work with older versions of OS X
-- Added support for `onMapLoad.init / onMapUnload.init ` scripts
-- game type detection functions are now available in the World module
-- The ``DFHACK_LOG_MEM_RANGES`` environment variable can be used to log information to ``stderr.log`` on OS X
-- Fixed adventure mode menu names
-- Fixed command usage information for some commands
-
-Lua
----
-- Lua scripts will only be reloaded if necessary
-- Added a ``df2console()`` wrapper, useful for printing DF (CP437-encoded) text to the console in a portable way
-- Added a ``strerror()`` wrapper
-
-New Internal Commands
----------------------
-- `hide`, `show`: hide and show the console on Windows
-- `sc-script`: Allows additional scripts to be run when certain events occur (similar to `onLoad.init` scripts)
-
-New Plugins
------------
-- `autohauler`: A hauling-only version of autolabor
-
-New Scripts
------------
-- `modtools/reaction-product-trigger`: triggers callbacks when products are produced (contrast with when reactions complete)
-
-New Tweaks
-----------
-- `fps-min `: Fixes the in-game minimum FPS setting
-- `shift-8-scroll `: Gives Shift+8 (or ``*``) priority when scrolling menus, instead of scrolling the map
-- `tradereq-pet-gender `: Displays pet genders on the trade request screen
-
-Fixes
------
-- Fixed game type detection in `3dveins`, `gui/create-item`, `reveal`, `seedwatch`
-- ``PRELOAD_LIB``: More extensible on Linux
-- `add-spatter`, `eventful`: Fixed crash on world load
-- `add-thought`: Now has a proper subthought arg.
-- `building-hacks`: Made buildings produce/consume correct amount of power
-- `fix-armory`: compiles and is available again (albeit with issues)
-- `gui/gm-editor`: Added search option (accessible with "s")
-- `hack-wish `: Made items stack properly.
-- `modtools/skill-change`: Made level granularity work properly.
-- `show-unit-syndromes`: should work
-- `stockflow`:
-
- - Fixed error message in Arena mode
- - no longer checks the DF version
- - fixed ballistic arrow head orders
- - convinces the bookkeeper to update records more often
-
-- `zone`: Stopped crash when scrolling cage owner list
-
-Misc Improvements
------------------
-- `autolabor`: A negative pool size can be specified to use the most unskilled dwarves
-- `building-hacks`:
-
- - Added a way to allow building to work even if it consumes more power than is available.
- - Added setPower/getPower functions.
-
-- `catsplosion`: Can now trigger pregnancies in (most) other creatures
-- `exportlegends`: ``info`` and ``all`` options export ``legends_plus.xml`` with more data for legends utilities
-- `manipulator`:
-
- - Added ability to edit nicknames/profession names
- - added "Job" as a View Type, in addition to "Profession" and "Squad"
- - added custom profession templates with masking
-
-- `remotefortressreader`: Exposes more information
-
-
-DFHack 0.40.24-r2
-=================
-
-Internals
----------
-- Lua scripts can set environment variables of each other with ``dfhack.run_script_with_env``
-- Lua scripts can now call each others internal nonlocal functions with ``dfhack.script_environment(scriptName).functionName(arg1,arg2)``
-- `eventful`: Lua reactions no longer require LUA_HOOK as a prefix; you can register a callback for the completion of any reaction with a name
-- Filesystem module now provides file access/modification times and can list directories (normally and recursively)
-- Units Module: New functions::
-
- isWar
- isHunter
- isAvailableForAdoption
- isOwnCiv
- isOwnRace
- getRaceName
- getRaceNamePlural
- getRaceBabyName
- getRaceChildName
- isBaby
- isChild
- isAdult
- isEggLayer
- isGrazer
- isMilkable
- isTrainableWar
- isTrainableHunting
- isTamable
- isMale
- isFemale
- isMerchant
- isForest
- isMarkedForSlaughter
-
-- Buildings Module: New Functions::
-
- isActivityZone
- isPenPasture
- isPitPond
- isActive
- findPenPitAt
-
-Fixes
------
-- ``dfhack.run_script`` should correctly find save-specific scripts now.
-- `add-thought`: updated to properly affect stress.
-- `hfs-pit`: should work now
-- `autobutcher`: takes gelding into account
-- :file:`init.lua` existence checks should be more reliable (notably when using non-English locales)
-
-Misc Improvements
------------------
-Multiline commands are now possible inside dfhack.init scripts. See :file:`dfhack.init-example` for example usage.
-
-
-DFHack 0.40.24-r1
-=================
-
-Internals
----------
-CMake shouldn't cache DFHACK_RELEASE anymore. People may need to manually update/delete their CMake cache files to get rid of it.
-
-
-DFHack 0.40.24-r0
-=================
-
-Internals
----------
-- `EventManager`: fixed crash error with EQUIPMENT_CHANGE event.
-- key modifier state exposed to Lua (ie :kbd:`Ctrl`, :kbd:`Alt`, :kbd:`Shift`)
-
-Fixes
------
-``dfhack.sh`` can now be run from other directories on OS X
-
-New Plugins
------------
-- `blueprint`: export part of your fortress to quickfort .csv files
-
-New Scripts
------------
-- `hotkey-notes`: print key, name, and jump position of hotkeys
-
-Removed
--------
-- needs_porting/*
-
-Misc Improvements
------------------
-Added support for searching more lists
-
-
-Older Changelogs
-================
-Are kept in a seperate file: `HISTORY`
-
-.. that's ``docs/history.rst``, if you're reading the raw text.
diff --git a/README.html b/README.html
index b8e15a0d11..4d1b0fd13c 100644
--- a/README.html
+++ b/README.html
@@ -13,4 +13,4 @@
Follow this link to the documentation.
-