From 021c45c4f641676e06401001c9c9cb9b6c6a74cc Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Tue, 2 May 2023 20:45:04 +0200 Subject: [PATCH] Add: [CMake] JSON library (nlohmann) --- .github/workflows/ci-build.yml | 15 ++-- .github/workflows/release-linux.yml | 3 +- .github/workflows/release-macos.yml | 4 +- .github/workflows/release-windows.yml | 3 +- CMakeLists.txt | 2 + COMPILING.md | 6 +- os/emscripten/Dockerfile | 3 + os/emscripten/README.md | 11 +-- os/emscripten/cmake/FindLibLZMA.cmake | 4 +- os/emscripten/cmake/Findnlohmann_json.cmake | 20 +++++ os/emscripten/emsdk-nlohmann-json.patch | 93 +++++++++++++++++++++ 11 files changed, 146 insertions(+), 18 deletions(-) create mode 100644 os/emscripten/cmake/Findnlohmann_json.cmake create mode 100644 os/emscripten/emsdk-nlohmann-json.patch diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 4b3fafd8f0..6ddb2e5901 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -76,20 +76,20 @@ jobs: - name: Clang compiler: clang cxxcompiler: clang++ - libraries: libsdl2-dev + libraries: libsdl2-dev nlohmann-json3-dev - name: GCC - SDL2 compiler: gcc cxxcompiler: g++ - libraries: libsdl2-dev + libraries: libsdl2-dev nlohmann-json3-dev - name: GCC - SDL1.2 compiler: gcc cxxcompiler: g++ - libraries: libsdl1.2-dev + libraries: libsdl1.2-dev nlohmann-json3-dev - name: GCC - Dedicated compiler: gcc cxxcompiler: g++ extra-cmake-parameters: -DOPTION_DEDICATED=ON -DCMAKE_CXX_FLAGS_INIT="-DRANDOM_DEBUG" -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON - # Compile without SDL / SDL2, as that should compile fine too. + # Compile without SDL / SDL2 / nlohmann-json, as that should compile fine too. name: Linux (${{ matrix.name }}) @@ -197,7 +197,7 @@ jobs: uses: actions/cache@v3 with: path: /usr/local/share/vcpkg/installed - key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-0 # Increase the number whenever dependencies are modified + key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-1 # Increase the number whenever dependencies are modified restore-keys: | ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }} @@ -208,6 +208,7 @@ jobs: liblzma \ libpng \ lzo \ + nlohmann-json \ zlib \ # EOF @@ -280,7 +281,7 @@ jobs: uses: actions/cache@v3 with: path: vcpkg/installed - key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-0 # Increase the number whenever dependencies are modified + key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-1 # Increase the number whenever dependencies are modified restore-keys: | ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }} @@ -291,6 +292,7 @@ jobs: liblzma \ libpng \ lzo \ + nlohmann-json \ zlib \ # EOF @@ -377,6 +379,7 @@ jobs: mingw-w64-${{ matrix.arch }}-libpng mingw-w64-${{ matrix.arch }}-lld mingw-w64-${{ matrix.arch }}-ninja + mingw-w64-${{ matrix.arch }}-nlohmann-json - name: Install OpenGFX shell: bash diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index 0f8ba153c6..78080af80b 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -27,7 +27,7 @@ jobs: uses: actions/cache@v3 with: path: /vcpkg/installed - key: ubuntu-20.04-vcpkg-release-0 # Increase the number whenever dependencies are modified + key: ubuntu-20.04-vcpkg-release-1 # Increase the number whenever dependencies are modified restore-keys: | ubuntu-20.04-vcpkg-release @@ -79,6 +79,7 @@ jobs: liblzma \ libpng \ lzo \ + nlohmann-json \ sdl2 \ zlib \ # EOF diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index 1240fae0ab..0654e99424 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -40,7 +40,7 @@ jobs: uses: actions/cache@v3 with: path: /usr/local/share/vcpkg/installed - key: ${{ steps.key.outputs.image }}-vcpkg-release-0 # Increase the number whenever dependencies are modified + key: ${{ steps.key.outputs.image }}-vcpkg-release-1 # Increase the number whenever dependencies are modified restore-keys: | ${{ steps.key.outputs.image }}-vcpkg-release ${{ steps.key.outputs.image }}-vcpkg-x64 @@ -56,6 +56,8 @@ jobs: libpng:arm64-osx \ lzo:x64-osx \ lzo:arm64-osx \ + nlohmann-json:x64-osx \ + nlohmann-json:arm64-osx \ zlib:x64-osx \ zlib:arm64-osx \ # EOF diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 347cb03386..2f934139e1 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -53,7 +53,7 @@ jobs: uses: actions/cache@v3 with: path: vcpkg/installed - key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-0 # Increase the number whenever dependencies are modified + key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-1 # Increase the number whenever dependencies are modified restore-keys: | ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }} @@ -64,6 +64,7 @@ jobs: liblzma \ libpng \ lzo \ + nlohmann-json \ zlib \ # EOF diff --git a/CMakeLists.txt b/CMakeLists.txt index 27b7b0e7d2..ca0b261d85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ find_package(ZLIB) find_package(LibLZMA) find_package(LZO) find_package(PNG) +find_package(nlohmann_json) if(WIN32 OR EMSCRIPTEN) # Windows uses WinHttp for HTTP requests. @@ -293,6 +294,7 @@ link_package(PNG TARGET PNG::PNG ENCOURAGED) link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED) link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED) link_package(LZO) +link_package(nlohmann_json ENCOURAGED) if(NOT WIN32 AND NOT EMSCRIPTEN) link_package(CURL ENCOURAGED) diff --git a/COMPILING.md b/COMPILING.md index 551afe39cb..be1bad79ab 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -4,6 +4,7 @@ OpenTTD makes use of the following external libraries: +- (encouraged) nlohmann-json: JSON handling - (encouraged) zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads, heightmaps - (encouraged) liblzma: (de)compressing of savegames (1.1.0 and later) @@ -52,13 +53,14 @@ the `static` versions, and OpenTTD currently needs the following dependencies: - liblzma - libpng - lzo +- nlohmann-json - zlib To install both the x64 (64bit) and x86 (32bit) variants (though only one is necessary), you can use: ```ps -.\vcpkg install liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static -.\vcpkg install liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static +.\vcpkg install liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static nlohmann-json:x64-windows-static zlib:x64-windows-static +.\vcpkg install liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static nlohmann-json:x86-windows-static zlib:x86-windows-static ``` You can open the folder (as a CMake project). CMake will be detected, and you can compile from there. diff --git a/os/emscripten/Dockerfile b/os/emscripten/Dockerfile index e92858df87..4ded7fe57c 100644 --- a/os/emscripten/Dockerfile +++ b/os/emscripten/Dockerfile @@ -2,3 +2,6 @@ FROM emscripten/emsdk:3.1.37 COPY emsdk-liblzma.patch / RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch + +COPY emsdk-nlohmann-json.patch / +RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-nlohmann-json.patch diff --git a/os/emscripten/README.md b/os/emscripten/README.md index cf8e3ed692..c16eea2416 100644 --- a/os/emscripten/README.md +++ b/os/emscripten/README.md @@ -4,10 +4,11 @@ Please use docker with the supplied `Dockerfile` to build for emscripten. It takes care of a few things: - Use a version of emscripten we know works - Patch in LibLZMA support (as this is not supported by upstream) +- Patch in nlohmann-json support (as this is not supported by upstream) First, build the docker image by navigating in the folder this `README.md` is in, and executing: ``` - docker build -t emsdk-lzma . + docker build -t emsdk-openttd . ``` Next, navigate back to the root folder of this project. @@ -15,15 +16,15 @@ Next, navigate back to the root folder of this project. Now we build the host tools first: ``` mkdir build-host - docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma cmake .. -DOPTION_TOOLS_ONLY=ON - docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma make -j$(nproc) tools + docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-openttd cmake .. -DOPTION_TOOLS_ONLY=ON + docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-openttd make -j$(nproc) tools ``` Finally, we build the actual game: ``` mkdir build - docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emcmake cmake .. -DHOST_BINARY_DIR=../build-host -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_ASSERTS=OFF - docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emmake make -j$(nproc) + docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-openttd emcmake cmake .. -DHOST_BINARY_DIR=../build-host -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_ASSERTS=OFF + docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-openttd emmake make -j$(nproc) ``` In the `build` folder you will now see `openttd.html`. diff --git a/os/emscripten/cmake/FindLibLZMA.cmake b/os/emscripten/cmake/FindLibLZMA.cmake index e8a024c4ee..cd6b44ad3d 100644 --- a/os/emscripten/cmake/FindLibLZMA.cmake +++ b/os/emscripten/cmake/FindLibLZMA.cmake @@ -1,5 +1,5 @@ -# LibLZMA is a recent addition to the emscripten SDK, so it is possible -# someone hasn't updated their SDK yet. Test out if the SDK supports LibLZMA. +# LibLZMA is a custom addition to the emscripten SDK, so it is possible +# someone patched their SDK. Test out if the SDK supports LibLZMA. include(CheckCXXSourceCompiles) set(CMAKE_REQUIRED_FLAGS "-sUSE_LIBLZMA=1") diff --git a/os/emscripten/cmake/Findnlohmann_json.cmake b/os/emscripten/cmake/Findnlohmann_json.cmake new file mode 100644 index 0000000000..6ff84544da --- /dev/null +++ b/os/emscripten/cmake/Findnlohmann_json.cmake @@ -0,0 +1,20 @@ +# nlohmann-json is a custom addition to the emscripten SDK, so it is possible +# someone patched their SDK. Test out if the SDK supports nlohmann-json. +include(CheckCXXSourceCompiles) +set(CMAKE_REQUIRED_FLAGS "-sUSE_NLOHMANN_JSON=1") + +check_cxx_source_compiles(" + #include + int main() { return 0; }" + NLOHMANN_JSON_FOUND +) + +if (NLOHMANN_JSON_FOUND) + add_library(nlohmann_json INTERFACE IMPORTED) + set_target_properties(nlohmann_json PROPERTIES + INTERFACE_COMPILE_OPTIONS "-sUSE_NLOHMANN_JSON=1" + INTERFACE_LINK_LIBRARIES "-sUSE_NLOHMANN_JSON=1" + ) +else() + message(WARNING "You are using an emscripten SDK without nlohmann-json support. Please apply 'emsdk-nlohmann_json.patch' to your local emsdk installation.") +endif() diff --git a/os/emscripten/emsdk-nlohmann-json.patch b/os/emscripten/emsdk-nlohmann-json.patch new file mode 100644 index 0000000000..37d052a2a7 --- /dev/null +++ b/os/emscripten/emsdk-nlohmann-json.patch @@ -0,0 +1,93 @@ +From 0edcedbea375e59f41df10acaee0c483d245751f Mon Sep 17 00:00:00 2001 +From: Patric Stout +Date: Tue, 2 May 2023 21:48:08 +0200 +Subject: [PATCH] Add nlohmmann-json port + +--- + src/settings.js | 4 ++++ + tools/ports/nlohmann_json.py | 46 ++++++++++++++++++++++++++++++++++++ + tools/settings.py | 1 + + 3 files changed, 51 insertions(+) + create mode 100644 tools/ports/nlohmann_json.py + +diff --git a/src/settings.js b/src/settings.js +index f93140d..39f4366 100644 +--- a/src/settings.js ++++ b/src/settings.js +@@ -1483,6 +1483,10 @@ var USE_MPG123 = false; + // [compile+link] + var USE_FREETYPE = false; + ++// 1 = use nlohmann-json from emscripten-ports ++// [compile+link] ++var USE_NLOHMANN_JSON = false; ++ + // Specify the SDL_mixer version that is being linked against. + // Doesn't *have* to match USE_SDL, but a good idea. + // [compile+link] +diff --git a/tools/ports/nlohmann_json.py b/tools/ports/nlohmann_json.py +new file mode 100644 +index 0000000..9e44297 +--- /dev/null ++++ b/tools/ports/nlohmann_json.py +@@ -0,0 +1,46 @@ ++# Copyright 2023 The Emscripten Authors. All rights reserved. ++# Emscripten is available under two separate licenses, the MIT license and the ++# University of Illinois/NCSA Open Source License. Both these licenses can be ++# found in the LICENSE file. ++ ++import os ++ ++TAG = '3.11.2' ++HASH = '99d9e6d588cabe8913a37437f86acb5d4b8b98bce12423e633c11c13b61e6c7f92ef8f9a4e991baa590329ee2b5c09ca9db9894bee1e54bdd68e8d09d83cc245' ++ ++ ++def needed(settings): ++ return settings.USE_NLOHMANN_JSON ++ ++ ++def get(ports, settings, shared): ++ ports.fetch_project('nlohmann_json', ++ f'https://github.com/nlohmann/json/releases/download/v{TAG}/include.zip', ++ sha512hash=HASH) ++ ++ def create(final): ++ source_path = os.path.join(ports.get_dir(), 'nlohmann_json') ++ source_path_include = os.path.join(source_path, 'include', 'nlohmann') ++ ports.install_header_dir(source_path_include, 'nlohmann') ++ ++ # write out a dummy cpp file, to create an empty library ++ # this is needed as emscripten ports expect this, even if it is not used ++ dummy_file = os.path.join(source_path, 'dummy.cpp') ++ shared.safe_ensure_dirs(os.path.dirname(dummy_file)) ++ ports.write_file(dummy_file, 'static void dummy() {}') ++ ++ ports.build_port(source_path, final, 'nlohmann_json', srcs=['dummy.cpp']) ++ ++ return [shared.cache.get_lib('libnlohmann_json.a', create, what='port')] ++ ++ ++def clear(ports, settings, shared): ++ shared.cache.erase_lib('libnlohmann_json.a') ++ ++ ++def process_args(ports): ++ return [] ++ ++ ++def show(): ++ return 'nlohmann-json' +diff --git a/tools/settings.py b/tools/settings.py +index 10d6ca0..8536092 100644 +--- a/tools/settings.py ++++ b/tools/settings.py +@@ -47,6 +47,7 @@ PORTS_SETTINGS = { + 'USE_MPG123', + 'USE_GIFLIB', + 'USE_FREETYPE', ++ 'USE_NLOHMANN_JSON', + 'SDL2_MIXER_FORMATS', + 'SDL2_IMAGE_FORMATS', + 'USE_SQLITE3', +-- +2.34.1