diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 99ff040..68476c6 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,7 +15,7 @@ What does this PR do? Provide a brief summary of the changes. ### Required for All PRs - [ ] Reproducible glTF test file(s) are included (e.g., `models/regression/`, `tests/issue-***.gltf`, etc.) -- [ ] Unit tests are written and pass locally (`cd tests && ./tester`) +- [ ] Unit tests are written and pass locally (`cd tests && make run`) ### Required for Feature PRs diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 0a7feb5..add479b 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -4,39 +4,11 @@ on: [push, pull_request] jobs: - # gcc4.8 is too old and ubuntu-18.04 image is not supported in GitHub Actions anymore, - # so disable this build. - ## compile with older gcc4.8 - #build-gcc48: - - # runs-on: ubuntu-18.04 - # name: Build with gcc 4.8 - - # steps: - # - name: Checkout - # uses: actions/checkout@v5 - - # - name: Build - # run: | - # sudo apt-get update - # sudo apt-get install -y build-essential - # sudo apt-get install -y gcc-4.8 g++-4.8 - # g++-4.8 -std=c++11 -o loader_example loader_example.cc - - # - name: NoexceptBuild - # run: | - # g++-4.8 -DTINYGLTF_NOEXCEPTION -std=c++11 -o loader_example loader_example.cc - - # - name: RapidjsonBuild - # run: | - # git clone https://github.com/Tencent/rapidjson - # g++-4.8 -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc - # compile with mingw gcc cross build-mingw-cross: runs-on: ubuntu-latest - name: Build with MinGW gcc cross + name: Build v3 C tests with MinGW gcc cross steps: - name: Checkout @@ -47,14 +19,14 @@ jobs: sudo apt-get update sudo apt-get install -y build-essential sudo apt-get install -y mingw-w64 - x86_64-w64-mingw32-g++ -std=c++11 -o loader_example loader_example.cc + cd tests + x86_64-w64-mingw32-gcc -I../ -std=c11 -DTINYGLTF3_ENABLE_FS -o tester_v3_c.exe tester_v3_c.c ../tiny_gltf_v3.c # Windows(x64) + Visual Studio 2022 build - # Assume windows-latest have VS2022 installed build-windows-msvc: runs-on: windows-latest - name: Build for Windows(x64, MSVC) + name: Build v3 C tests on Windows(x64, MSVC) # Use system installed cmake # https://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners @@ -65,8 +37,7 @@ jobs: run: | mkdir build cd build - cmake --help - cmake -G "Visual Studio 17 2022" -A x64 -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=On -DTINYGLTF_BUILD_TESTS=ON .. + cmake -G "Visual Studio 17 2022" -A x64 -DTINYGLTF3_BUILD_TESTS=ON .. cd .. - name: Build run: cmake --build build --config Release @@ -77,111 +48,24 @@ jobs: build-linux: runs-on: ubuntu-latest - name: Buld with gcc + name: Build v3 C tests with gcc steps: - uses: actions/checkout@v5 - name: build run: | - g++ -std=c++11 -o loader_example loader_example.cc + cd tests + cc -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS -o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c - name: test run: | - ./loader_example models/Cube/Cube.gltf + ./tests/tester_v3_c models/Cube/Cube.gltf - name: tests run: | cd tests - g++ -I../ -std=c++11 -g -O0 -o tester tester.cc - ./tester - cd .. - - - name: noexcept_tests - run: | - cd tests - g++ -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc - ./tester_noexcept - cd .. - - - name: v3_c_tests - run: | - cd tests - cc -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS \ - -o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c + make all ./tester_v3_c - cc -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS \ - -o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c ./tester_v3_c_v1port - cc -I../ -std=c11 -g -O0 \ - -o tester_v3_json_c tester_v3_json_c.c ./tester_v3_json_c - cc -I../ -std=c11 -ffreestanding -g -O0 \ - -o tester_v3_freestanding tester_v3_freestanding.c ./tester_v3_freestanding cd .. - - - build-rapidjson-linux: - - runs-on: ubuntu-latest - name: Buld with gcc + rapidjson - - steps: - - uses: actions/checkout@v5 - - name: build - run: | - git clone https://github.com/Tencent/rapidjson - g++ -v - g++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -o loader_example loader_example.cc - - - name: loader_example_test - run: | - ./loader_example models/Cube/Cube.gltf - - - name: tests - run: | - cd tests - g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -I../ -std=c++11 -g -O0 -o tester tester.cc - ./tester - cd .. - - - name: noexcept_tests - run: | - cd tests - g++ -DTINYGLTF_USE_RAPIDJSON -I../rapidjson/include/rapidjson -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc - ./tester_noexcept - cd .. - - # Cross-compile for aarch64 linux target - build-cross-aarch64: - - runs-on: ubuntu-latest - name: Build on cross aarch64 - - steps: - - name: Checkout - uses: actions/checkout@v5 - - name: Build - run: | - sudo apt-get update - sudo apt-get install -y build-essential - sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - - git clone https://github.com/Tencent/rapidjson - aarch64-linux-gnu-g++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc - - # macOS clang - build-macos: - - runs-on: macos-latest - name: Build on macOS - - steps: - - name: Checkout - uses: actions/checkout@v5 - - name: Build - run: | - clang++ -std=c++11 -g -O0 -o loader_example loader_example.cc - ./loader_example models/Cube/Cube.gltf - - git clone https://github.com/Tencent/rapidjson - clang++ -DTINYGLTF_USE_RAPIDJSON -I./rapidjson/include/rapidjson -std=c++11 -g -O0 -o loader_example loader_example.cc diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3fdcac2..5efcd1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,13 +26,13 @@ jobs: uses: actions/checkout@v5 - name: Configure - run: cmake -B build -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON -DTINYGLTF_BUILD_TESTS=ON + run: cmake -B build -DTINYGLTF3_BUILD_TESTS=ON - name: Build run: cmake --build build - - name: Run loader_example - run: ./build/loader_example models/Cube/Cube.gltf + - name: Run tester_v3_c on a sample model + run: ./build/tester_v3_c models/Cube/Cube.gltf - name: Run tests run: ctest --test-dir build --output-on-failure @@ -53,14 +53,13 @@ jobs: - name: Configure run: | - cmake -B build -DCMAKE_C_COMPILER=clang-21 -DCMAKE_CXX_COMPILER=clang++-21 -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON -DTINYGLTF_BUILD_TESTS=ON + cmake -B build -DCMAKE_C_COMPILER=clang-21 -DTINYGLTF3_BUILD_TESTS=ON - name: Build run: cmake --build build - - name: Run loader_example - run: | - ./build/loader_example models/Cube/Cube.gltf + - name: Run tester_v3_c on a sample model + run: ./build/tester_v3_c models/Cube/Cube.gltf - name: Run tests run: ctest --test-dir build --output-on-failure @@ -74,13 +73,13 @@ jobs: uses: actions/checkout@v5 - name: Configure - run: cmake -B build -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON -DTINYGLTF_BUILD_TESTS=ON + run: cmake -B build -DTINYGLTF3_BUILD_TESTS=ON - name: Build run: cmake --build build - - name: Run loader_example - run: ./build/loader_example models/Cube/Cube.gltf + - name: Run tester_v3_c on a sample model + run: ./build/tester_v3_c models/Cube/Cube.gltf - name: Run tests run: ctest --test-dir build --output-on-failure @@ -94,13 +93,13 @@ jobs: uses: actions/checkout@v5 - name: Configure - run: cmake -B build -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON -DTINYGLTF_BUILD_TESTS=ON + run: cmake -B build -DTINYGLTF3_BUILD_TESTS=ON - name: Build run: cmake --build build - - name: Run loader_example - run: ./build/loader_example models/Cube/Cube.gltf + - name: Run tester_v3_c on a sample model + run: ./build/tester_v3_c models/Cube/Cube.gltf - name: Run tests run: ctest --test-dir build --output-on-failure @@ -117,55 +116,18 @@ jobs: run: | mkdir build cd build - cmake -G "Visual Studio 17 2022" -A x64 -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=Off -DTINYGLTF_BUILD_TESTS=ON .. + cmake -G "Visual Studio 17 2022" -A x64 -DTINYGLTF3_BUILD_TESTS=ON .. - name: Build run: cmake --build build --config Release - - name: Run loader_example + - name: Run tester_v3_c on a sample model run: | - .\build\Release\loader_example.exe models\Cube\Cube.gltf + .\build\Release\tester_v3_c.exe models\Cube\Cube.gltf - name: Run tests run: ctest --test-dir build -C Release --output-on-failure - # Windows x86 - MSVC - windows-msvc-x86: - runs-on: windows-latest - name: Windows x86 (MSVC) - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Configure - run: | - mkdir build - cd build - cmake -G "Visual Studio 17 2022" -A Win32 -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=Off -DTINYGLTF_BUILD_TESTS=ON .. - - - name: Build - run: cmake --build build --config Release - - - name: Run tests - run: ctest --test-dir build -C Release --output-on-failure - - # Windows ARM64 - MSVC (cross-compile) - windows-msvc-arm64: - runs-on: windows-latest - name: Windows ARM64 (MSVC) - Cross-compile - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Configure - run: | - mkdir build - cd build - cmake -G "Visual Studio 17 2022" -A ARM64 -DTINYGLTF_BUILD_LOADER_EXAMPLE=On -DTINYGLTF_BUILD_GL_EXAMPLES=Off -DTINYGLTF_BUILD_VALIDATOR_EXAMPLE=Off .. - - - name: Build - run: cmake --build build --config Release - # Windows MinGW - MSYS2 windows-mingw-msys2: runs-on: windows-latest @@ -189,12 +151,12 @@ jobs: - name: Build with CMake run: | - cmake -G"Ninja" -S . -B build -DTINYGLTF_BUILD_TESTS=ON + cmake -G"Ninja" -S . -B build -DTINYGLTF3_BUILD_TESTS=ON cmake --build build - - name: Run loader_example + - name: Run tester_v3_c on a sample model run: | - ./build/loader_example models/Cube/Cube.gltf + ./build/tester_v3_c models/Cube/Cube.gltf - name: Run tests run: ctest --test-dir build --output-on-failure @@ -213,51 +175,9 @@ jobs: sudo apt-get install -y build-essential mingw-w64 - name: Build - run: | - x86_64-w64-mingw32-g++ -std=c++11 -o loader_example.exe loader_example.cc - - # Special Configuration: No Exceptions - linux-noexception: - runs-on: ubuntu-latest - name: Linux x64 (GCC) - No Exceptions - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Build loader_example - run: | - g++ -DTINYGLTF_NOEXCEPTION -std=c++11 -o loader_example loader_example.cc - - - name: Run loader_example - run: | - ./loader_example models/Cube/Cube.gltf - - - name: Build and run unit tests run: | cd tests - g++ -DTINYGLTF_NOEXCEPTION -I../ -std=c++11 -g -O0 -o tester_noexcept tester.cc - ./tester_noexcept - - # Special Configuration: Header-Only Mode - linux-header-only: - runs-on: ubuntu-latest - name: Linux x64 (GCC) - Header-Only Mode - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Build with CMake Header-Only - run: | - mkdir build - cmake -B build -DTINYGLTF_HEADER_ONLY=ON -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON -DTINYGLTF_BUILD_TESTS=ON - cmake --build build - - - name: Run loader_example - run: | - ./build/loader_example models/Cube/Cube.gltf - - - name: Run tests - run: ctest --test-dir build --output-on-failure + x86_64-w64-mingw32-gcc -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS -o tester_v3_c.exe tester_v3_c.c ../tiny_gltf_v3.c # v3 C tests through Meson on the primary desktop platforms. v3-c-meson: @@ -283,76 +203,6 @@ jobs: - name: Run v3 C tests run: meson test -C build-meson --print-errorlogs - # Special Configuration: RapidJSON Backend - linux-rapidjson: - runs-on: ubuntu-latest - name: Linux x64 (GCC) - RapidJSON Backend - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Clone RapidJSON - run: | - git clone https://github.com/Tencent/rapidjson - - - name: Configure - run: | - cmake -B build -DTINYGLTF_USE_RAPIDJSON=ON -DTINYGLTF_BUILD_LOADER_EXAMPLE=ON -DTINYGLTF_BUILD_TESTS=ON -DCMAKE_PREFIX_PATH=$PWD/rapidjson - - - name: Build - run: cmake --build build - - - name: Run loader_example - run: | - ./build/loader_example models/Cube/Cube.gltf - - - name: Run tests - run: ctest --test-dir build --output-on-failure - - # Special Configuration: AddressSanitizer - linux-asan: - runs-on: ubuntu-latest - name: Linux x64 (Clang) - AddressSanitizer - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Build loader_example with ASan - run: | - clang++ -fsanitize=address -std=c++11 -g -O1 -o loader_example loader_example.cc - - - name: Run loader_example - run: | - ./loader_example models/Cube/Cube.gltf - - - name: Build and run unit tests with ASan - run: | - cd tests - clang++ -fsanitize=address -I../ -std=c++11 -g -O1 -o tester tester.cc - ./tester - - # Special Configuration: UndefinedBehaviorSanitizer - linux-ubsan: - runs-on: ubuntu-latest - name: Linux x64 (Clang) - UndefinedBehaviorSanitizer - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Build loader_example with UBSan - run: | - clang++ -fsanitize=undefined -std=c++11 -g -O1 -o loader_example loader_example.cc - - - name: Run loader_example - run: | - ./loader_example models/Cube/Cube.gltf - - - name: Build and run unit tests with UBSan - run: | - cd tests - clang++ -fsanitize=undefined -I../ -std=c++11 -g -O1 -o tester tester.cc - ./tester - # v3 C runtime: internal security regression tests + ported v1 unit tests. v3-c-tests: runs-on: ubuntu-latest @@ -378,7 +228,7 @@ jobs: cd tests ./tester_v3_c - - name: Run tester_v3_c_v1port (18 ported unit tests) + - name: Run tester_v3_c_v1port (ported unit tests) run: | cd tests ./tester_v3_c_v1port diff --git a/.github/workflows/mingw-w64-msys2.yml b/.github/workflows/mingw-w64-msys2.yml index a1bc9b4..7842670 100644 --- a/.github/workflows/mingw-w64-msys2.yml +++ b/.github/workflows/mingw-w64-msys2.yml @@ -42,7 +42,7 @@ jobs: -G"Ninja" \ -S . \ -B build \ - -DTINYGLTF_BUILD_TESTS=ON + -DTINYGLTF3_BUILD_TESTS=ON - name: Build run: | diff --git a/.gitignore b/.gitignore index 20ef663..e140f7c 100644 --- a/.gitignore +++ b/.gitignore @@ -71,10 +71,6 @@ imgui.ini loader_example # Compiled test binaries (built by tests/Makefile, CMakeLists.txt, meson.build) -tests/tester -tests/tester_noexcept -tests/tester_customjson -tests/tester_intensive_customjson tests/tester_v3 tests/tester_v3_c tests/tester_v3_c_cpp @@ -82,27 +78,9 @@ tests/tester_v3_c_v1port tests/tester_v3_c_v1port_cpp tests/tester_v3_freestanding tests/tester_v3_json_c -tests/fuzzer/fuzz_gltf -tests/fuzzer/fuzz_gltf_customjson -tests/issue-97.gltf -tests/issue-261.gltf -tests/issue-495-external.gltf -# Test-generated output files (written by tester.cc during test run) -tests/Cube.gltf -tests/Cube.bin -tests/Cube.glb -tests/Cube_BaseColor.png -tests/Cube_MetallicRoughness.png -tests/Cube_with_embedded_images.gltf -tests/Cube_with_image_files.gltf -tests/tmp.glb -tests/ issue-236.gltf -tests/ issue-236.bin -tests/ 2x2 image has multiple spaces.png +tests/v3/fuzzer/fuzz_gltf_v3 +tests/v3/fuzzer/fuzz_gltf_v3_c # unignore !Makefile -!examples/build-gltf/Makefile -!examples/raytrace/cornellbox_suzanne.obj !tests/Makefile -!tools/windows/premake5.exe diff --git a/CMakeLists.txt b/CMakeLists.txt index 68b7e90..2f7c268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,45 +1,20 @@ -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.10) -project(tinygltf) +project(tinygltf_v3 C) include(GNUInstallDirs) -include(CMakePackageConfigHelpers) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED On) -set(CMAKE_CXX_EXTENSIONS Off) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED On) +set(CMAKE_C_EXTENSIONS Off) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -option(TINYGLTF_BUILD_LOADER_EXAMPLE "Build loader_example(load glTF and dump infos)" ON) -option(TINYGLTF_BUILD_GL_EXAMPLES "Build GL exampels(requires glfw, OpenGL, etc)" OFF) -option(TINYGLTF_BUILD_VALIDATOR_EXAMPLE "Build validator exampe" OFF) -option(TINYGLTF_BUILD_BUILDER_EXAMPLE "Build glTF builder example" OFF) -option(TINYGLTF_BUILD_TESTS "Build unit tests" OFF) -option(TINYGLTF_HEADER_ONLY "On: header-only mode. Off: create tinygltf library(No TINYGLTF_IMPLEMENTATION required in your project)" OFF) -option(TINYGLTF_INSTALL "Install tinygltf files during install step. Usually set to OFF if you include tinygltf through add_subdirectory()" ON) -option(TINYGLTF_INSTALL_VENDOR "Install vendored nlohmann/json and nothings/stb headers" ON) -option(TINYGLTF_USE_CUSTOM_JSON "Use the built-in fast JSON parser (tinygltf_json.h) instead of nlohmann/json" OFF) +option(TINYGLTF3_BUILD_TESTS "Build and run tinygltf v3 C unit tests" ON) +option(TINYGLTF3_INSTALL "Install tinygltf v3 files during install step" ON) -if (TINYGLTF_BUILD_LOADER_EXAMPLE) - add_executable(loader_example - loader_example.cc - ) -endif (TINYGLTF_BUILD_LOADER_EXAMPLE) +set(TINYGLTF3_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) -if (TINYGLTF_BUILD_GL_EXAMPLES) - add_subdirectory( examples/gltfutil ) - add_subdirectory( examples/glview ) -endif (TINYGLTF_BUILD_GL_EXAMPLES) - -if (TINYGLTF_BUILD_VALIDATOR_EXAMPLE) - add_subdirectory( examples/validator ) -endif (TINYGLTF_BUILD_VALIDATOR_EXAMPLE) - -if (TINYGLTF_BUILD_BUILDER_EXAMPLE) - add_subdirectory ( examples/build-gltf ) -endif (TINYGLTF_BUILD_BUILDER_EXAMPLE) - -if (TINYGLTF_BUILD_TESTS) +if (TINYGLTF3_BUILD_TESTS) enable_testing() function(add_tinygltf_v3_c_test target) @@ -56,31 +31,6 @@ if (TINYGLTF_BUILD_TESTS) add_test(NAME ${target} COMMAND ${target} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests) endfunction() - add_executable(tester tests/tester.cc) - target_include_directories(tester PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ) - add_test(NAME tester COMMAND tester WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests) - - # Build and run tests with the custom JSON backend enabled to catch regressions - add_executable(tester_customjson tests/tester.cc) - target_include_directories(tester_customjson PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ) - target_compile_definitions(tester_customjson PRIVATE TINYGLTF_USE_CUSTOM_JSON) - add_test(NAME tester_customjson COMMAND tester_customjson WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests) - - # Intensive parser tests for the custom JSON backend - add_executable(tester_intensive_customjson tests/tester_intensive_customjson.cc) - target_include_directories(tester_intensive_customjson PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/tests - ) - target_compile_definitions(tester_intensive_customjson PRIVATE TINYGLTF_USE_CUSTOM_JSON) - add_test(NAME tester_intensive_customjson COMMAND tester_intensive_customjson WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests) - add_tinygltf_v3_c_test(tester_v3_c tests/tester_v3_c.c tiny_gltf_v3.c) target_compile_definitions(tester_v3_c PRIVATE TINYGLTF3_ENABLE_FS) @@ -93,65 +43,14 @@ if (TINYGLTF_BUILD_TESTS) if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") target_compile_options(tester_v3_freestanding PRIVATE -ffreestanding) endif() -endif (TINYGLTF_BUILD_TESTS) - -# -# for add_subdirectory and standalone build -# -if (TINYGLTF_HEADER_ONLY) - add_library(tinygltf INTERFACE) - - target_include_directories(tinygltf - INTERFACE - $ - $ - ) - -else (TINYGLTF_HEADER_ONLY) - add_library(tinygltf) - target_sources(tinygltf PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/tiny_gltf.cc) - target_include_directories(tinygltf - INTERFACE - $ - $ - ) -endif (TINYGLTF_HEADER_ONLY) - -if (TINYGLTF_USE_CUSTOM_JSON) - if (TINYGLTF_HEADER_ONLY) - target_compile_definitions(tinygltf INTERFACE TINYGLTF_USE_CUSTOM_JSON) - else () - target_compile_definitions(tinygltf PUBLIC TINYGLTF_USE_CUSTOM_JSON) - endif () endif () -if (TINYGLTF_INSTALL) - install(TARGETS tinygltf EXPORT tinygltfTargets) - install(EXPORT tinygltfTargets NAMESPACE tinygltf:: FILE TinyGLTFTargets.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/tinygltf) - configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/TinyGLTFConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/TinyGLTFConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/TinyGLTFConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/tinygltf) - # Do not install .lib even if !TINYGLTF_HEADER_ONLY - - INSTALL ( FILES - tiny_gltf.h +if (TINYGLTF3_INSTALL) + install(FILES tiny_gltf_v3.h tiny_gltf_v3.c - tinygltf_json.h tinygltf_json_c.h - ${TINYGLTF_EXTRA_SOUECES} DESTINATION - include - ) - - if(TINYGLTF_INSTALL_VENDOR) - INSTALL ( FILES - json.hpp - stb_image.h - stb_image_write.h - DESTINATION - include - ) - endif() - -endif(TINYGLTF_INSTALL) + ${TINYGLTF3_INSTALL_DIR} + ) +endif () diff --git a/README.md b/README.md index 8c6cd66..95b2972 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,18 @@ -# Header only C++ tiny glTF library(loader/saver). +# tinygltf v3 — C glTF 2.0 loader/saver -`TinyGLTF` is a header only C++ glTF 2.0 https://github.com/KhronosGroup/glTF library. +`TinyGLTF v3` is a C11-first implementation of a glTF 2.0 +https://github.com/KhronosGroup/glTF loader and writer. -## TinyGLTF v3 (new major release) - -**`tiny_gltf_v3.h`** is the new major version of TinyGLTF. -The new C implementation (`tiny_gltf_v3.c` + `tinygltf_json_c.h`) is currently **experimental**. - -### What's new in v3 - -v3 is a ground-up rewrite with a C-centric, low-overhead design: - -- **Pure C POD structs** — no STL containers in the public API; easy to bind to other languages. +- **Pure C POD API** (`tiny_gltf_v3.h` + `tiny_gltf_v3.c` + `tinygltf_json_c.h`) — no STL, no RTTI, no exceptions required; easy to bind to other languages. - **Arena-based memory management** — all parse-time allocations come from a single arena; a single `tg3_model_free()` frees everything. - **Structured error reporting** — `tg3_error_stack` provides machine-readable errors with severity levels and source locations. -- **Custom JSON backend** — backed by `tinygltf_json_c.h`, a locale-independent pure-C JSON parser/serializer used by the v3 runtime. +- **Custom JSON backend** — `tinygltf_json_c.h` is a locale-independent pure-C JSON parser/serializer used by the v3 runtime. - **Streaming callbacks** — opt-in streaming parse/write via user-supplied callbacks. -- **No RTTI, no exceptions required** — suitable for embedded and game-engine use. - **Opt-in filesystem and image I/O** — `TINYGLTF3_ENABLE_FS` / `TINYGLTF3_ENABLE_STB_IMAGE` are off by default; you control when and how assets are loaded. - **C++20 coroutine facade** (optional, auto-detected). C17/C++17 default. -- **Hardened against untrusted input** — URI sanitization, post-parse index-bounds validation (default-on, opt-out via `tg3_parse_options.validate_indices = 0`), strict numeric range checks; exercised by a libFuzzer harness and by a cross-version verifier that compares parsed output against the v1 C++ reference loader. See the `Security Considerations` block at the top of `tiny_gltf_v3.h`. +- **Hardened against untrusted input** — URI sanitization, post-parse index-bounds validation (default-on, opt-out via `tg3_parse_options.validate_indices = 0`), strict numeric range checks; exercised by a libFuzzer harness. See the `Security Considerations` block at the top of `tiny_gltf_v3.h`. -### Quick start (v3) +## Quick start Copy `tiny_gltf_v3.h`, `tiny_gltf_v3.c`, and `tinygltf_json_c.h` to your project. Compile `tiny_gltf_v3.c` as C11 or newer. Define `TINYGLTF3_ENABLE_FS` when @@ -55,262 +46,51 @@ tg3_model_free(&model); tg3_error_stack_free(&errors); ``` -### Testing & verification +## Testing & verification The v3 C runtime ships with three layers of automated coverage: - **`tests/tester_v3_c.c`** — internal unit checks plus security regression tests (path traversal, negative `byteStride`, OOB indices, error-message lifetime, …). Build via `make` in `tests/`; run `./tester_v3_c` for the internal suite or `./tester_v3_c ` to parse a single asset. -- **`test_runner.py`** — a cross-version verifier that runs the v1 C++ reference loader (`loader_example`) and the v3 C tester against every model in `glTF-Sample-Models/2.0`, then diffs a structured DIGEST block (buffer FNV64 hashes, accessor/bufferView fields, primitive attribute maps, node TRS, material PBR factors, skin/animation/scene topology, …). v1 is the ground truth. +- **`tests/tester_v3_c_v1port.c`** — v3 C port of the legacy unit tests, keeping behavioral parity with the old C++ API. +- **`tests/tester_v3_json_c.c`** and **`tests/tester_v3_freestanding.c`** — JSON backend and freestanding (no libc) checks. +- **`test_runner.py`** — model verifier that runs `tests/tester_v3_c` against every model in `glTF-Sample-Models/2.0` and validates the structured COUNTS/DIGEST output. - **`tests/v3/fuzzer/`** — libFuzzer harness with ASan + UBSan (`make run` builds and runs `fuzz_gltf_v3_c`). Crafted regression inputs live in `tests/v3/security/` and are seeded into `tests/v3/fuzzer/corpus/`. +### Building + +```bash +# Plain make (gcc/clang) +$ make -C tests && make -C tests run + +# CMake +$ cmake -B build && cmake --build build && ctest --test-dir build --output-on-failure + +# Meson +$ meson setup build && meson compile -C build && meson test -C build +``` + +## Legacy v1/v2 (C++) + +The previous C++ implementation (`tiny_gltf.h`, `tiny_gltf.cc`, +`tinygltf_json.h`, `json.hpp`, `loader_example.cc`, the C++ examples and +tests) is deprecated and has been moved to [`attic/`](attic/) for reference. +It is no longer built, tested, or installed. TinyGLTF v3 C is the mainline. + ## Status -> ⚠️ **v2 deprecation notice:** `tiny_gltf.h` (v2) remains fully functional and is still supported, -> but it is now in **maintenance mode only** — no new features will be added. -> v2 will be **sunset after mid-2026**. `tiny_gltf_v3.h` is the intended successor, but the new C v3 runtime is still **experimental**. - -TinyGLTF v3's C runtime (`tiny_gltf_v3.h` + `tiny_gltf_v3.c`) is available for evaluation and early adoption, -but its API/behavior may still change while the implementation matures. - -Currently TinyGLTF v2 is stable and in maintenance mode. No drastic changes and feature additions planned. - - v2.9.0 Various fixes and improvements. Filesystem callback API change. - - v2.8.0 Add URICallbacks for custom URI handling in Buffer and Image. PR#397 - - v2.7.0 Change WriteImageDataFunction user callback function signature. PR#393 - - v2.6.0 Support serializing sparse accessor(Thanks to @fynv). - - v2.5.0 Add SetPreserveImageChannels() option to load image data as is. - - v2.4.0 Experimental RapidJSON support. Experimental C++14 support(C++14 may give better performance) - - v2.3.0 Modified Material representation according to glTF 2.0 schema(and introduced TextureInfo class) - - v2.2.0 release(Support loading 16bit PNG. Sparse accessor support) - - v2.1.0 release(Draco decoding support) - - v2.0.0 release(22 Aug, 2018)! - -### Branches - -* `sajson` : Use sajson to parse JSON. Parsing only but faster compile time(2x reduction compared to json.hpp and RapidJson), but not well maintained. +TinyGLTF v3 (`tiny_gltf_v3.h` + `tiny_gltf_v3.c`) is the mainline release. +API additions and behavior changes go through the usual review process. ## Builds ![C/C++ CI](https://github.com/syoyo/tinygltf/workflows/C/C++%20CI/badge.svg) -## Features - -Probably mostly feature-complete. Last missing feature is Draco encoding: https://github.com/syoyo/tinygltf/issues/207 - -* Written in portable C++. C++-11 with STL dependency only. - * [x] macOS + clang(LLVM) - * [x] iOS + clang - * [x] Linux + gcc/clang - * [x] Windows + MinGW - * [x] Windows + Visual Studio 2015 Update 3 or later. - * Visual Studio 2013 is not supported since they have limited C++11 support and failed to compile `json.hpp`. - * [x] Android NDK - * [x] Android + CrystaX(NDK drop-in replacement) GCC - * [x] Web using Emscripten(LLVM) -* Moderate parsing time and memory consumption. -* glTF specification v2.0.0 - * [x] ASCII glTF - * [x] Load - * [x] Save - * [x] Binary glTF(GLB) - * [x] Load - * [x] Save(.bin embedded .glb) -* Buffers - * [x] Parse BASE64 encoded embedded buffer data(DataURI). - * [x] Load `.bin` file. -* Image(Using stb_image) - * [x] Parse BASE64 encoded embedded image data(DataURI). - * [x] Load external image file. - * [x] Load PNG(8bit and 16bit) - * [x] Load JPEG(8bit only) - * [x] Load BMP - * [x] Load GIF - * [x] Custom Image decoder callback(e.g. for decoding OpenEXR image) -* Morph traget - * [x] Sparse accessor -* Load glTF from memory -* Custom callback handler - * [x] Image load - * [x] Image save -* Extensions - * [x] Draco mesh decoding - * [ ] Draco mesh encoding - -## Note on extension property - -In extension(`ExtensionMap`), JSON number value is parsed as int or float(number) and stored as `tinygltf::Value` object. If you want a floating point value from `tinygltf::Value`, use `GetNumberAsDouble()` method. - -`IsNumber()` returns true if the underlying value is an int value or a floating point value. - -## Examples - -* [glview](examples/glview) : Simple glTF geometry viewer. -* [validator](examples/validator) : Simple glTF validator with JSON schema. -* [basic](examples/basic) : Basic glTF viewer with texturing support. -* [build-gltf](examples/build-gltf) : Build simple glTF scene from a scratch. - -### WASI/WASM build - -Users who want to run TinyGLTF securely and safely(e.g. need to handle malcious glTF file to serve online glTF conver), -I recommend to build TinyGLTF for WASM target. -WASI build example is located in [wasm](wasm) . - - -## TODOs - -* [ ] Robust URI decoding/encoding. https://github.com/syoyo/tinygltf/issues/369 -* [ ] Mesh Compression/decompression(Open3DGC, etc) - * [x] Load Draco compressed mesh - * [ ] Save Draco compressed mesh - * [ ] Open3DGC? -* [x] Support `extensions` and `extras` property -* [ ] HDR image? - * [ ] OpenEXR extension through TinyEXR. -* [ ] 16bit PNG support in Serialization -* [ ] Write example and tests for `animation` and `skin` - -### Optional - -* [ ] Write C++ code generator which emits C++ code from JSON schema for robust parsing? - ## Licenses -TinyGLTF is licensed under MIT license. +TinyGLTF is licensed under MIT license. See [LICENSE](LICENSE). -TinyGLTF uses the following third party libraries. +TinyGLTF v3 uses the following third party code: -* json.hpp : Copyright (c) 2013-2017 Niels Lohmann. MIT license. -* base64 : Copyright (C) 2004-2008 René Nyffenegger -* stb_image.h : v2.08 - public domain image loader - [Github link](https://github.com/nothings/stb/blob/master/stb_image.h) -* stb_image_write.h : v1.09 - public domain image writer - [Github link](https://github.com/nothings/stb/blob/master/stb_image_write.h) - - -## Build and example - -Copy `stb_image.h`, `stb_image_write.h`, `json.hpp` and `tiny_gltf.h` to your project. - -### Loading glTF 2.0 model - -```c++ -// Define these only in *one* .cc file. -#define TINYGLTF_IMPLEMENTATION -#define STB_IMAGE_IMPLEMENTATION -#define STB_IMAGE_WRITE_IMPLEMENTATION -// #define TINYGLTF_NOEXCEPTION // optional. disable exception handling. -#include "tiny_gltf.h" - -using namespace tinygltf; - -Model model; -TinyGLTF loader; -std::string err; -std::string warn; -std::string filename = "input.gltf"; - -bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, filename); -//bool ret = loader.LoadBinaryFromFile(&model, &err, &warn, filename); // for binary glTF(.glb) - -if (!warn.empty()) { - printf("Warn: %s\n", warn.c_str()); -} - -if (!err.empty()) { - printf("Err: %s\n", err.c_str()); -} - -if (!ret) { - printf("Failed to parse glTF: %s\n", filename.c_str()); -} -``` - -#### Loader options - -* `TinyGLTF::SetPreserveimageChannels(bool onoff)`. `true` to preserve image channels as stored in image file for loaded image. `false` by default for backward compatibility(image channels are widen to `RGBA` 4 channels). Effective only when using builtin image loader(STB image loader). - -## Compile options - -* `TINYGLTF_NOEXCEPTION` : Disable C++ exception in JSON parsing. You can use `-fno-exceptions` or by defining the symbol `JSON_NOEXCEPTION` and `TINYGLTF_NOEXCEPTION` to fully remove C++ exception codes when compiling TinyGLTF. -* `TINYGLTF_NO_STB_IMAGE` : Do not load images with stb_image. Instead use `TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data)` to set a callback for loading images. -* `TINYGLTF_NO_STB_IMAGE_WRITE` : Do not write images with stb_image_write. Instead use `TinyGLTF::SetImageWriter(WriteimageDataFunction WriteImageData, void *user_data)` to set a callback for writing images. -* `TINYGLTF_NO_EXTERNAL_IMAGE` : Do not try to load external image file. This option would be helpful if you do not want to load image files during glTF parsing. -* `TINYGLTF_ANDROID_LOAD_FROM_ASSETS`: Load all files from packaged app assets instead of the regular file system. **Note:** You must pass a valid asset manager from your android app to `tinygltf::asset_manager` beforehand. -* `TINYGLTF_ENABLE_DRACO`: Enable Draco compression. User must provide include path and link correspnding libraries in your project file. -* `TINYGLTF_NO_INCLUDE_JSON `: Disable including `json.hpp` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. -* `TINYGLTF_NO_INCLUDE_RAPIDJSON `: Disable including RapidJson's header files from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. -* `TINYGLTF_NO_INCLUDE_STB_IMAGE `: Disable including `stb_image.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. -* `TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE `: Disable including `stb_image_write.h` from within `tiny_gltf.h` because it has been already included before or you want to include it using custom path before including `tiny_gltf.h`. -* `TINYGLTF_USE_RAPIDJSON` : Use RapidJSON as a JSON parser/serializer. RapidJSON files are not included in TinyGLTF repo. Please set an include path to RapidJSON if you enable this feature. - - -## CMake options - -You can add tinygltf using `add_subdirectory` feature. -If you add tinygltf to your project using `add_subdirectory`, it would be better to set `TINYGLTF_HEADER_ONLY` on(just add an include path to tinygltf) and `TINYGLTF_INSTALL` off(Which does not install tinygltf files). - -``` -// Your project's CMakeLists.txt -... - -set(TINYGLTF_HEADER_ONLY ON CACHE INTERNAL "" FORCE) -set(TINYGLTF_INSTALL OFF CACHE INTERNAL "" FORCE) -add_subdirectory(/path/to/tinygltf) -``` - -NOTE: Using tinygltf as a submodule doesn't automatically add the headers to your include path (as standard for many libraries). To get this functionality, add the following to the CMakeLists.txt file from above: - -``` -target_include_directories(${PROJECT_NAME} PRIVATE "/path/to/tinygltf") -``` - -### Saving gltTF 2.0 model - -* Buffers. - * [x] To file - * [x] Embedded - * [ ] Draco compressed? -* [x] Images - * [x] To file - * [x] Embedded -* Binary(.glb) - * [x] .bin embedded single .glb - * [ ] External .bin - -## Running tests. - -### glTF parsing test - -#### Setup - -Python required. -Git clone https://github.com/KhronosGroup/glTF-Sample-Models to your local dir. - -#### Run parsing test - -After building `loader_example`, edit `test_runner.py`, then, - -```bash -$ python test_runner.py -``` - -### Unit tests - -```bash -$ cd tests -$ make -$ ./tester -$ ./tester_noexcept -``` - -### Fuzzing tests - -See `tests/fuzzer` for details. - -After running fuzzer on Ryzen9 3950X a week, at least `LoadASCIIFromString` looks safe except for out-of-memory error in Fuzzer. -We may be better to introduce bounded memory size checking when parsing glTF data. - -## Third party licenses - -* json.hpp : Licensed under the MIT License . Copyright (c) 2013-2017 Niels Lohmann . -* stb_image : Public domain. -* catch : Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. Distributed under the Boost Software License, Version 1.0. -* RapidJSON : Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. http://rapidjson.org/ -* dlib(uridecode, uriencode) : Copyright (C) 2003 Davis E. King Boost Software License 1.0. http://dlib.net/dlib/server/server_http.cpp.html +* fast_float (JSON number parsing, in `tinygltf_json_c.h`): Copyright (c) 2021 The fast_float authors. Apache License 2.0 / MIT / Boost 1.0. +* dragonbox (JSON number serialization, in `tinygltf_json_c.h`): Copyright 2020-2024 Junekey Jeon. Apache 2.0 with LLVM exceptions / Boost 1.0. +* stb_image.h (optional, `TINYGLTF3_ENABLE_STB_IMAGE`) : public domain image loader - [Github link](https://github.com/nothings/stb/blob/master/stb_image.h) diff --git a/meson_options.txt b/meson_options.txt index 7f6e95a..32564ef 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1 @@ -option('tests', type: 'boolean', value: true, description: 'Build and run tinygltf tests') +option('tests', type: 'boolean', value: true, description: 'Build and run tinygltf v3 C tests') diff --git a/test_runner.py b/test_runner.py index 04911d2..44e0156 100644 --- a/test_runner.py +++ b/test_runner.py @@ -6,17 +6,15 @@ import re import subprocess import sys -## Cross-version verifier: parses each sample model with the mature v1 -## (loader_example) and the new v3 C tester, then compares both the COUNTS -## summary line and the structured DIGEST block both binaries emit. -## v1 is the ground truth. +## Model verifier for the tinygltf v3 C runtime: parses every sample model +## with the v3 C tester (tests/tester_v3_c) and validates that it exits +## successfully and emits a well-formed COUNTS summary and DIGEST block. # -- config ----------------------- sample_model_dir = "/mnt/nfs/syoyo/glTF-Sample-Models" base_model_dir = os.path.join(sample_model_dir, "2.0") -v1_bin = "./loader_example" v3_bin = "./tests/tester_v3_c" kinds = ["glTF", "glTF-Binary", "glTF-Embedded", "glTF-MaterialsCommon"] @@ -54,65 +52,31 @@ def run_binary(binary, filename): return p.returncode, out.decode("utf-8", "replace"), err.decode("utf-8", "replace") -def diff_digests(v1, v3, max_lines=20): - """Return a short summary of differences between two digest line lists.""" - diffs = [] - n = max(len(v1), len(v3)) - for i in range(n): - a = v1[i] if i < len(v1) else "" - b = v3[i] if i < len(v3) else "" - if a != b: - diffs.append(" v1[{0}]: {1}".format(i, a)) - diffs.append(" v3[{0}]: {1}".format(i, b)) - if len(diffs) >= max_lines * 2: - diffs.append(" ... (truncated)") - break - return diffs - - -parse_failed = [] # v3 returned non-zero or no COUNTS/DIGEST -v1_skipped = [] # v1 returned non-zero or no COUNTS/DIGEST -counts_diff = [] # counts disagree -digest_diff = [] # digest disagrees +parse_failed = [] # v3 returned non-zero or no COUNTS/DIGEST +digest_malformed = [] # COUNTS/DIGEST present but structurally wrong ok = [] def verify(filename): print("Testing: " + filename) - rc1, out1, err1 = run_binary(v1_bin, filename) - c1 = parse_counts(out1) if rc1 == 0 else None - d1 = parse_digest(out1) if rc1 == 0 else None - if c1 is None or d1 is None: - v1_skipped.append(filename) - print(" v1 ground truth unavailable (rc={0}); skipping".format(rc1)) + rc, out, err = run_binary(v3_bin, filename) + if rc != 0: + parse_failed.append((filename, rc, err.strip())) + print(" v3 FAILED (rc={0}): {1}".format(rc, err.strip()[:200])) return - rc3, out3, err3 = run_binary(v3_bin, filename) - c3 = parse_counts(out3) if rc3 == 0 else None - d3 = parse_digest(out3) if rc3 == 0 else None - if c3 is None or d3 is None: - parse_failed.append((filename, rc3, err3.strip())) - print(" v3 FAILED (rc={0}): {1}".format(rc3, err3.strip()[:200])) + counts = parse_counts(out) + digest = parse_digest(out) + if counts is None or digest is None: + digest_malformed.append((filename, counts is None, digest is None)) + print(" v3 COUNTS/DIGEST MISSING (counts={0}, digest={1})".format( + counts is not None, digest is not None)) return - cdiffs = [] - for k in sorted(set(c1) | set(c3)): - if c1.get(k) != c3.get(k): - cdiffs.append((k, c1.get(k), c3.get(k))) - if cdiffs: - counts_diff.append((filename, cdiffs)) - print(" COUNTS MISMATCH:") - for k, a, b in cdiffs: - print(" {0}: v1={1} v3={2}".format(k, a, b)) - return - - if d1 != d3: - diffs = diff_digests(d1, d3) - digest_diff.append((filename, diffs)) - print(" DIGEST MISMATCH ({0} v1 lines, {1} v3 lines):".format(len(d1), len(d3))) - for line in diffs[:8]: - print(line) + if "asset" not in counts: + digest_malformed.append((filename, "no asset count", None)) + print(" v3 COUNTS missing asset key") return ok.append(filename) @@ -134,8 +98,6 @@ def test(): def main(): - if not os.path.exists(v1_bin): - sys.exit("error: v1 binary not found at {0}".format(v1_bin)) if not os.path.exists(v3_bin): sys.exit("error: v3 binary not found at {0}".format(v3_bin)) @@ -143,24 +105,14 @@ def main(): print("") print("=== Summary ===") - print("OK : {0}".format(len(ok))) - print("Counts diff : {0}".format(len(counts_diff))) - print("Digest diff : {0}".format(len(digest_diff))) - print("v3 failed : {0}".format(len(parse_failed))) - print("v1 skipped : {0}".format(len(v1_skipped))) + print("OK : {0}".format(len(ok))) + print("Malformed output: {0}".format(len(digest_malformed))) + print("v3 failed : {0}".format(len(parse_failed))) - for f, diffs in counts_diff: - print("COUNTS DIFF: " + f) - for k, a, b in diffs: - print(" {0}: v1={1} v3={2}".format(k, a, b)) - for f, diffs in digest_diff: - print("DIGEST DIFF: " + f) - for line in diffs: - print(line) for f, rc, err in parse_failed: print("V3 FAIL: {0} (rc={1}) {2}".format(f, rc, err[:200])) - if counts_diff or digest_diff or parse_failed: + if digest_malformed or parse_failed: sys.exit(1) diff --git a/tests/Makefile b/tests/Makefile index 7f161fb..2fb2086 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,19 +1,32 @@ -# Use this for strict compilation check(will work on clang 3.8+) -#EXTRA_CXXFLAGS := -fsanitize=address -Wall -Werror -Weverything -Wno-c++11-long-long -DTINYGLTF_APPLY_CLANG_WEVERYTHING +# Build and run tinygltf v3 C unit tests. +# +# Targets: +# make all — build all v3 C testers +# make run — run all v3 C testers +# make clean — remove test binaries -all: ../tiny_gltf.h tester_v3_c tester_v3_c_v1port tester_v3_json_c tester_v3_freestanding - clang++ -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester tester.cc - clang++ -DTINYGLTF_NOEXCEPTION -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester_noexcept tester.cc - clang++ -DTINYGLTF_USE_CUSTOM_JSON -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester_intensive_customjson tester_intensive_customjson.cc +CC ?= cc +CFLAGS ?= -I../ -std=c11 -g -O0 -Wall -Wextra + +all: tester_v3_c tester_v3_c_v1port tester_v3_json_c tester_v3_freestanding tester_v3_c: tester_v3_c.c ../tiny_gltf_v3.h ../tiny_gltf_v3.c ../tinygltf_json_c.h - clang -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS -o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c + $(CC) $(CFLAGS) -DTINYGLTF3_ENABLE_FS -o tester_v3_c tester_v3_c.c ../tiny_gltf_v3.c tester_v3_c_v1port: tester_v3_c_v1port.c ../tiny_gltf_v3.h ../tiny_gltf_v3.c ../tinygltf_json_c.h - clang -I../ -std=c11 -g -O0 -DTINYGLTF3_ENABLE_FS -o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c + $(CC) $(CFLAGS) -DTINYGLTF3_ENABLE_FS -o tester_v3_c_v1port tester_v3_c_v1port.c ../tiny_gltf_v3.c tester_v3_json_c: tester_v3_json_c.c ../tinygltf_json_c.h - clang -I../ -std=c11 -g -O0 -o tester_v3_json_c tester_v3_json_c.c + $(CC) $(CFLAGS) -o tester_v3_json_c tester_v3_json_c.c tester_v3_freestanding: tester_v3_freestanding.c ../tiny_gltf_v3.h ../tiny_gltf_v3.c ../tinygltf_json_c.h - clang -I../ -std=c11 -ffreestanding -g -O0 -o tester_v3_freestanding tester_v3_freestanding.c + $(CC) $(CFLAGS) -ffreestanding -o tester_v3_freestanding tester_v3_freestanding.c + +run: all + ./tester_v3_c + ./tester_v3_c_v1port + ./tester_v3_json_c + ./tester_v3_freestanding + +clean: + rm -f tester_v3_c tester_v3_c_v1port tester_v3_json_c tester_v3_freestanding