Merge pull request #684 from simdjson/jkeiser/cmake

Simplify cmake, add more of our tests into it
This commit is contained in:
John Keiser 2020-04-08 16:02:47 -07:00 committed by GitHub
commit 3b1b1bfd48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 198 additions and 260 deletions

View File

@ -2,28 +2,33 @@ version: '{build}'
branches:
only:
- master
image:
- Visual Studio 2017
clone_folder: c:\projects\simdjson
platform:
- x64
platform: x64
image:
- Visual Studio 2019
- Visual Studio 2017
configuration: Release
environment:
matrix:
- SIMDJSON_BUILD_STATIC: "OFF"
THREADS: "ON"
- SIMDJSON_BUILD_STATIC: "OFF"
THREADS: "OFF"
- SIMDJSON_BUILD_STATIC: "ON"
THREADS: "ON"
# - SIMDJSON_BUILD_STATIC: "ON"
# THREADS: "OFF"
- SIMDJSON_BUILD_STATIC: ON
SIMDJSON_ENABLE_THREADS: OFF
- SIMDJSON_BUILD_STATIC: OFF
SIMDJSON_ENABLE_THREADS: ON
build_script:
- set
- mkdir build
- cd build
- ps: cmake -DSIMDJSON_BUILD_STATIC="$env:SIMDJSON_BUILD_STATIC" -DSIMDJSON_ENABLE_THREADS="$env:THREADS" -DCMAKE_BUILD_TYPE=Release -DCMAKE_GENERATOR_PLATFORM=x64 -DSIMDJSON_GOOGLE_BENCHMARKS=OFF ..
- cmake --build .
- ctest --verbose --output-on-failure
- cmake -DSIMDJSON_BUILD_STATIC=%SIMDJSON_BUILD_STATIC% -DSIMDJSON_ENABLE_THREADS=%SIMDJSON_ENABLE_THREADS% -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_GENERATOR_PLATFORM=x64 -DSIMDJSON_GOOGLE_BENCHMARKS=OFF ..
- cmake --build . --config %Configuration%
test_script:
- ctest --verbose --output-on-failure -C %Configuration%
matrix:
fast_finish: true
exclude:
# Don't build all variants on 2019, just running it to make sure readme_tests succeed
- image: Visual Studio 2019
SIMDJSON_BUILD_STATIC: ON
SIMDJSON_ENABLE_THREADS: OFF

View File

@ -59,7 +59,7 @@ commands:
- run: make all
- run: make test
cmake_test: # this version builds, install, test and then verifyi from the installation
cmake_test: # this version builds, install, test and then verify from the installation
steps:
- run: apt-get update -qq
- run: apt-get install -y cmake

6
.gitignore vendored
View File

@ -121,15 +121,17 @@ objs
/singleheader/demo
/tests/basictests
/tests/errortests
/tests/jsoncheck
/tests/pointercheck
/tests/integer_tests
/tests/jsoncheck
/tests/numberparsingcheck
/tests/pointercheck
/tests/parse_many_test
/tests/readme_examples
/tests/readme_examples11
/tests/readme_examples_noexceptions
/tests/readme_examples_noexceptions11
/tests/staticchecks
/tests/stringparsingcheck
/tools/json2json
/tools/jsonstats
/tools/minify

View File

@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 3.9) # CMP0069 NEW
message(STATUS "cmake version ${CMAKE_VERSION}")
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
@ -24,7 +25,6 @@ set(CMAKE_MACOSX_RPATH OFF)
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(SIMDJSON_LIB_NAME simdjson)
set(PROJECT_VERSION_MAJOR 0)
set(PROJECT_VERSION_MINOR 3)
set(PROJECT_VERSION_PATCH 1)
@ -43,25 +43,28 @@ endif()
option(SIMDJSON_SANITIZE "Sanitize addresses" OFF)
option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" OFF)
option(SIMDJSON_ENABLE_THREADS "enable threaded operation" ON)
option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON)
option(SIMDJSON_NO_EXCEPTIONS "Disable simdjson's exception-throwing interface" OFF)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake")
find_package(CTargets)
find_package(Options)
# We used to have install(DIRECTORY include/${SIMDJSON_LIB_NAME} DESTINATION include)
# alone.
# However, this fails because we also need the root level simdjson.h file.
install(DIRECTORY include/${SIMDJSON_LIB_NAME} DESTINATION include)
install(FILES include/${SIMDJSON_LIB_NAME}.h DESTINATION include)
set (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jsonchecker/")
set (BENCHMARK_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/")
add_definitions(-DSIMDJSON_TEST_DATA_DIR="${TEST_DATA_DIR}")
add_definitions(-DSIMDJSON_BENCHMARK_DATA_DIR="${TEST_DATA_DIR}")
enable_testing()
include(include/CMakeLists.txt)
#
# Create the top level simdjson library (must be done at this level to use both src/ and include/
# directories)
#
add_subdirectory(windows)
add_subdirectory(include)
add_subdirectory(src)
#
# Compile tools / tests / benchmarks
#
add_definitions(-DSIMDJSON_TEST_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonchecker/")
add_definitions(-DSIMDJSON_BENCHMARK_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/")
enable_testing()
add_subdirectory(tools)
add_subdirectory(tests)
add_subdirectory(benchmark)

View File

@ -1,21 +1,14 @@
target_include_directories(${SIMDJSON_LIB_NAME}
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/benchmark>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/benchmark/linux>
)
add_cpp_benchmark(parse)
add_cpp_benchmark(statisticalmodel)
add_cpp_benchmark(parse_stream)
add_cpp_benchmark(get_corpus_benchmark)
include_directories( . linux )
link_libraries(simdjson)
add_executable(parse parse.cpp)
add_executable(statisticalmodel statisticalmodel.cpp)
add_executable(parse_stream parse_stream.cpp)
add_executable(get_corpus_benchmark get_corpus_benchmark.cpp)
add_executable(perfdiff perfdiff.cpp)
# Google Benchmarks
if (SIMDJSON_GOOGLE_BENCHMARKS)
add_cpp_benchmark(bench_parse_call)
target_link_libraries(bench_parse_call benchmark::benchmark)
add_cpp_benchmark(bench_dom_api)
target_link_libraries(bench_dom_api benchmark::benchmark)
target_compile_definitions(bench_dom_api PRIVATE JSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json")
link_libraries(benchmark::benchmark)
add_executable(bench_parse_call bench_parse_call.cpp)
add_executable(bench_dom_api bench_dom_api.cpp)
endif()

View File

@ -6,18 +6,16 @@ using namespace simdjson;
using namespace benchmark;
using namespace std;
#ifndef JSON_TEST_PATH
#define JSON_TEST_PATH "jsonexamples/twitter.json"
#endif
const padded_string EMPTY_ARRAY("[]", 2);
const char *TWITTER_JSON = SIMDJSON_BENCHMARK_DATA_DIR "";
#if SIMDJSON_EXCEPTIONS
static void twitter_count(State& state) {
// Prints the number of results in twitter.json
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(TWITTER_JSON);
for (auto _ : state) {
uint64_t result_count = doc["search_metadata"]["count"];
if (result_count != 100) { return; }
@ -29,7 +27,7 @@ SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING
static void iterator_twitter_count(State& state) {
// Prints the number of results in twitter.json
padded_string json = padded_string::load(JSON_TEST_PATH);
padded_string json = padded_string::load(TWITTER_JSON);
ParsedJson pj = build_parsed_json(json);
for (auto _ : state) {
ParsedJson::Iterator iter(pj);
@ -48,7 +46,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
static void twitter_default_profile(State& state) {
// Count unique users with a default profile.
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(TWITTER_JSON);
for (auto _ : state) {
set<string_view> default_users;
for (dom::object tweet : doc["statuses"].get<dom::array>()) {
@ -65,7 +63,7 @@ BENCHMARK(twitter_default_profile);
static void twitter_image_sizes(State& state) {
// Count unique image sizes
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(TWITTER_JSON);
for (auto _ : state) {
set<tuple<uint64_t, uint64_t>> image_sizes;
for (dom::object tweet : doc["statuses"].get<dom::array>()) {
@ -88,7 +86,7 @@ BENCHMARK(twitter_image_sizes);
static void error_code_twitter_count(State& state) noexcept {
// Prints the number of results in twitter.json
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(TWITTER_JSON);
for (auto _ : state) {
auto [value, error] = doc["search_metadata"]["count"].get<uint64_t>();
if (error) { return; }
@ -100,7 +98,7 @@ BENCHMARK(error_code_twitter_count);
static void error_code_twitter_default_profile(State& state) noexcept {
// Count unique users with a default profile.
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(TWITTER_JSON);
for (auto _ : state) {
set<string_view> default_users;
@ -127,7 +125,7 @@ SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING
static void iterator_twitter_default_profile(State& state) {
// Count unique users with a default profile.
padded_string json = padded_string::load(JSON_TEST_PATH);
padded_string json = padded_string::load(TWITTER_JSON);
ParsedJson pj = build_parsed_json(json);
for (auto _ : state) {
set<string_view> default_users;
@ -167,7 +165,7 @@ BENCHMARK(iterator_twitter_default_profile);
static void error_code_twitter_image_sizes(State& state) noexcept {
// Count unique image sizes
dom::parser parser;
dom::element doc = parser.load(JSON_TEST_PATH);
dom::element doc = parser.load(TWITTER_JSON);
for (auto _ : state) {
set<tuple<uint64_t, uint64_t>> image_sizes;
auto [statuses, error] = doc["statuses"].get<dom::array>();
@ -196,7 +194,7 @@ SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING
static void iterator_twitter_image_sizes(State& state) {
// Count unique image sizes
padded_string json = padded_string::load(JSON_TEST_PATH);
padded_string json = padded_string::load(TWITTER_JSON);
ParsedJson pj = build_parsed_json(json);
for (auto _ : state) {
set<tuple<uint64_t, uint64_t>> image_sizes;
@ -254,7 +252,7 @@ BENCHMARK(iterator_twitter_image_sizes);
static void print_json(State& state) noexcept {
// Prints the number of results in twitter.json
padded_string json = get_corpus(JSON_TEST_PATH);
padded_string json = get_corpus(TWITTER_JSON);
dom::parser parser;
if (int error = json_parse(json, parser); error != SUCCESS) { cerr << error_message(error) << endl; return; }
for (auto _ : state) {

View File

@ -44,7 +44,7 @@ macro(implement_fuzzer sourcefile)
if (SIMDJSON_FUZZ_LINKMAIN)
target_sources(${name} PRIVATE main.cpp)
endif ()
target_link_libraries(${name} PRIVATE ${SIMDJSON_LIB_NAME})
target_link_libraries(${name} PRIVATE simdjson)
if (SIMDJSON_FUZZ_LDFLAGS)
target_link_libraries(${name} PRIVATE ${SIMDJSON_FUZZ_LDFLAGS})
endif ()

View File

@ -1,25 +1,2 @@
set(SIMDJSON_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
set(SIMDJSON_INCLUDE
${SIMDJSON_INCLUDE_DIR}/simdjson.h
${SIMDJSON_INCLUDE_DIR}/simdjson/common_defs.h
${SIMDJSON_INCLUDE_DIR}/simdjson/compiler_check.h
${SIMDJSON_INCLUDE_DIR}/simdjson/document_stream.h
${SIMDJSON_INCLUDE_DIR}/simdjson/document.h
${SIMDJSON_INCLUDE_DIR}/simdjson/error.h
${SIMDJSON_INCLUDE_DIR}/simdjson/implementation.h
${SIMDJSON_INCLUDE_DIR}/simdjson/inline/document_stream.h
${SIMDJSON_INCLUDE_DIR}/simdjson/inline/document.h
${SIMDJSON_INCLUDE_DIR}/simdjson/inline/error.h
${SIMDJSON_INCLUDE_DIR}/simdjson/inline/padded_string.h
${SIMDJSON_INCLUDE_DIR}/simdjson/inline/parsedjson_iterator.h
${SIMDJSON_INCLUDE_DIR}/simdjson/internal/jsonformatutils.h
${SIMDJSON_INCLUDE_DIR}/simdjson/jsonioutil.h
${SIMDJSON_INCLUDE_DIR}/simdjson/jsonparser.h
${SIMDJSON_INCLUDE_DIR}/simdjson/nonstd/string_view.hpp
${SIMDJSON_INCLUDE_DIR}/simdjson/padded_string.h
${SIMDJSON_INCLUDE_DIR}/simdjson/parsedjson.h
${SIMDJSON_INCLUDE_DIR}/simdjson/parsedjson_iterator.h
${SIMDJSON_INCLUDE_DIR}/simdjson/portability.h
${SIMDJSON_INCLUDE_DIR}/simdjson/simdjson_version.h
${SIMDJSON_INCLUDE_DIR}/simdjson/simdjson.h
)
install(DIRECTORY simdjson DESTINATION include FILES_MATCHING PATTERN *.h)
install(FILES simdjson.h DESTINATION include)

View File

@ -1,132 +1,70 @@
if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
# prevent shared libraries from depending on Intel provided libraries
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel")
endif()
include(GNUInstallDirs)
# we default on a shared library.
if(SIMDJSON_BUILD_STATIC)
set(SIMDJSON_LIB_TYPE STATIC)
MESSAGE( STATUS "Building a static library." )
add_library(simdjson STATIC "")
else()
MESSAGE( STATUS "Building a dynamic library (default)." )
set(SIMDJSON_LIB_TYPE SHARED)
MESSAGE( STATUS "Building a dynamic library." )
add_library(simdjson SHARED "")
endif()
MESSAGE( STATUS "SIMDJSON_LIB_TYPE: " ${SIMDJSON_LIB_TYPE})
target_sources(simdjson PRIVATE simdjson.cpp)
target_include_directories(simdjson PRIVATE .)
target_include_directories(simdjson PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
# Bring in include files
include(../include/CMakeLists.txt)
if(SIMDJSON_NO_EXCEPTIONS)
message(STATUS "simdjson exception interface turned off. Code that does not check error codes will not compile.")
target_compile_definitions(simdjson PUBLIC SIMDJSON_EXCEPTIONS=0)
endif()
set(SIMDJSON_SRC_DIR $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
# prevent shared libraries from depending on Intel provided libraries
target_link_options(simdjson PUBLIC "-static-intel")
endif()
set(SIMDJSON_SRC
simdjson.cpp
)
if(SIMDJSON_ENABLE_THREADS)
find_package(Threads REQUIRED)
target_link_libraries(simdjson PRIVATE Threads::Threads)
endif()
# Load headers and sources
set(SIMDJSON_SRC_HEADERS
error.cpp
implementation.cpp
isadetection.h
simdprune_tables.h
stage1_find_marks.cpp
stage2_build_tape.cpp
arm64/bitmanipulation.h
arm64/bitmask.h
arm64/implementation.h
arm64/intrinsics.h
arm64/numberparsing.h
arm64/simd.h
arm64/stage1_find_marks.h
arm64/stage2_build_tape.h
arm64/stringparsing.h
fallback/implementation.h
fallback/stage1_find_marks.h
fallback/stage2_build_tape.h
generic/atomparsing.h
generic/json_scanner.h
generic/json_string_scanner.h
generic/json_structural_indexer.h
generic/numberparsing.h
generic/stage2_build_tape.h
generic/stage2_streaming_build_tape.h
generic/stringparsing.h
generic/utf8_fastvalidate_algorithm.h
generic/utf8_lookup_algorithm.h
generic/utf8_lookup2_algorithm.h
generic/utf8_range_algorithm.h
generic/utf8_zwegner_algorithm.h
haswell/bitmanipulation.h
haswell/bitmask.h
haswell/implementation.h
haswell/intrinsics.h
haswell/numberparsing.h
haswell/simd.h
haswell/stage1_find_marks.h
haswell/stage2_build_tape.h
haswell/stringparsing.h
document_parser_callbacks.h
westmere/bitmanipulation.h
westmere/bitmask.h
westmere/implementation.h
westmere/intrinsics.h
westmere/numberparsing.h
westmere/simd.h
westmere/stage1_find_marks.h
westmere/stage2_build_tape.h
westmere/stringparsing.h
)
set_source_files_properties(${SIMDJSON_SRC_HEADERS} PROPERTIES HEADER_FILE_ONLY TRUE)
# For targets that want to include the source directly
add_library(simdjson-source INTERFACE)
target_include_directories(simdjson-source INTERFACE .)
target_include_directories(simdjson-source INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
add_library(${SIMDJSON_LIB_NAME} ${SIMDJSON_LIB_TYPE} ${SIMDJSON_SRC} ${SIMDJSON_INCLUDE} ${SIMDJSON_SRC_HEADERS})
# Installation
target_include_directories(${SIMDJSON_LIB_NAME}
PUBLIC
$<BUILD_INTERFACE:${SIMDJSON_SRC_DIR}>
$<BUILD_INTERFACE:${SIMDJSON_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
install(TARGETS ${SIMDJSON_LIB_NAME}
EXPORT ${SIMDJSON_LIB_NAME}-config
install(TARGETS simdjson
EXPORT simdjson-config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(EXPORT ${SIMDJSON_LIB_NAME}-config
FILE ${SIMDJSON_LIB_NAME}-config.cmake
NAMESPACE ${SIMDJSON_LIB_NAME}::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${SIMDJSON_LIB_NAME}
install(EXPORT simdjson-config
FILE simdjson-config.cmake
NAMESPACE simdjson::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/simdjson
)
if(NOT MSVC)
## We output the library at the root of the current directory where cmake is invoked
## This is handy but Visual Studio will happily ignore us
set_target_properties(${SIMDJSON_LIB_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
VERSION ${SIMDJSON_LIB_VERSION}
SOVERSION ${SIMDJSON_LIB_SOVERSION})
set_target_properties(simdjson PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
MESSAGE( STATUS "Library output directory (does not apply to Visual Studio): " ${CMAKE_BINARY_DIR})
endif()
if((SIMDJSON_LIB_TYPE STREQUAL "SHARED"))
target_compile_definitions(${SIMDJSON_LIB_NAME} INTERFACE SIMDJSON_USING_LIBRARY=1)
if(NOT SIMDJSON_BUILD_STATIC)
target_compile_definitions(simdjson INTERFACE SIMDJSON_USING_LIBRARY=1)
endif()
if(MSVC AND (SIMDJSON_LIB_TYPE STREQUAL "SHARED"))
if(MSVC AND (NOT SIMDJSON_BUILD_STATIC))
if (CMAKE_VERSION VERSION_LESS 3.4)
MESSAGE( STATUS "To build a Windows DLL using Visual Studio, you may need cmake 3.4 or better." )
MESSAGE( STATUS "To build a Windows DLL using Visual Studio, you may need cmake 3.4 or better." )
endif()
MESSAGE( STATUS "Building a Windows DLL using Visual Studio, exporting all symbols automatically." )
set_target_properties(${SIMDJSON_LIB_NAME}
set_target_properties(simdjson
PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1)
endif()
if(SIMDJSON_ENABLE_THREADS)
find_package(Threads REQUIRED)
target_link_libraries( ${SIMDJSON_LIB_NAME} Threads::Threads)
endif()

View File

@ -1,31 +1,57 @@
if(MSVC)
target_include_directories(${SIMDJSON_LIB_NAME}
INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/windows>
)
# Helper so we don't have to repeat ourselves so much
function(add_cpp_test TEST_NAME TEST_FILE)
add_executable(${TEST_NAME} ${TEST_FILE})
add_test(${TEST_NAME} ${TEST_NAME})
endfunction(add_cpp_test)
# Sets a target to only build when you run the test, and expect failure
function(add_compile_test TEST_NAME TEST_FILE EXPECT_SUCCESS)
add_executable(${TEST_NAME} ${TEST_FILE})
set_target_properties(${TEST_NAME} PROPERTIES
EXCLUDE_FROM_ALL TRUE
EXCLUDE_FROM_DEFAULT_BUILD TRUE)
add_test(NAME ${TEST_NAME}
COMMAND ${CMAKE_COMMAND} --build . --target ${TEST_NAME} --config $<CONFIGURATION>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
if(NOT ${EXPECT_SUCCESS})
set_tests_properties(${TEST_NAME} PROPERTIES WILL_FAIL TRUE)
endif()
endfunction(add_compile_test)
#
# These test explicitly do #include "simdjson.cpp"
#
if (NOT MSVC) # Can't get simdjson-source to compile on Windows for some reason.
add_cpp_test(numberparsingcheck numberparsingcheck.cpp)
target_link_libraries(numberparsingcheck simdjson-source simdjson-windows-headers)
add_cpp_test(stringparsingcheck stringparsingcheck.cpp)
target_link_libraries(stringparsingcheck simdjson-source simdjson-windows-headers)
endif()
add_cpp_test(basictests)
add_cpp_test(errortests)
#
# All remaining tests link with simdjson proper
#
link_libraries(simdjson)
## Next bit should not be needed!
#if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
# next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang
#set_tests_properties(basictests PROPERTIES
# ENVIRONMENT ASAN_OPTIONS="detect_odr_violation=0")
#endif()
# add_executable(allparserscheckfile allparserscheckfile.cpp)
add_cpp_test(basictests basictests.cpp)
add_cpp_test(errortests errortests.cpp)
add_cpp_test(integer_tests integer_tests.cpp)
add_cpp_test(jsoncheck jsoncheck.cpp)
target_link_libraries(jsoncheck simdjson-windows-headers)
add_cpp_test(parse_many_test parse_many_test.cpp)
target_link_libraries(parse_many_test simdjson-windows-headers)
add_cpp_test(pointercheck pointercheck.cpp)
add_cpp_test(jsoncheck)
add_cpp_test(parse_many_test)
add_cpp_test(pointercheck)
add_cpp_test(integer_tests)
target_compile_definitions(basictests PRIVATE JSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json" NDJSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/amazon_cellphones.ndjson")
target_compile_definitions(errortests PRIVATE JSON_TEST_PATH="${PROJECT_SOURCE_DIR}/jsonexamples/twitter.json")
## This causes problems
# add_executable(singleheader ./singleheadertest.cpp ${PROJECT_SOURCE_DIR}/singleheader/simdjson.cpp)
# target_link_libraries(singleheader ${SIMDJSON_LIB_NAME})
# add_test(singleheader singleheader)
# Compile-only tests
# Don't add the tests if we're on VS2017 or older; they don't succeed.
if(NOT (MSVC AND MSVC_VERSION LESS 1920))
add_compile_test(readme_examples readme_examples.cpp TRUE)
# Test that readme_examples does NOT compile when SIMDJSON_EXCEPTIONS=0 (i.e. test that the define
# works even if exceptions are on)
add_compile_test(readme_examples_will_fail_with_exceptions_off readme_examples.cpp FALSE)
target_compile_definitions(readme_examples_will_fail_with_exceptions_off PRIVATE SIMDJSON_EXCEPTIONS=0)
endif()
if(MSVC)
add_custom_command(TARGET basictests POST_BUILD # Adds a post-build event
@ -36,3 +62,14 @@ if(MSVC)
"$<TARGET_FILE_DIR:basictests>") # <--this is out-file path
endif()
## Next bit should not be needed!
#if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
# next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang
#set_tests_properties(basictests PROPERTIES
# ENVIRONMENT ASAN_OPTIONS="detect_odr_violation=0")
#endif()
## This causes problems
# add_executable(singleheader ./singleheadertest.cpp ${PROJECT_SOURCE_DIR}/singleheader/simdjson.cpp)
# target_link_libraries(singleheader simdjson)
# add_test(singleheader singleheader)

View File

@ -17,12 +17,11 @@
#include "simdjson.h"
#ifndef JSON_TEST_PATH
#define JSON_TEST_PATH "jsonexamples/twitter.json"
#endif
#ifndef NDJSON_TEST_PATH
#define NDJSON_TEST_PATH "jsonexamples/amazon_cellphones.ndjson"
#ifndef SIMDJSON_BENCHMARK_DATA_DIR
#define SIMDJSON_BENCHMARK_DATA_DIR "jsonexamples/"
#endif
const char *TWITTER_JSON = SIMDJSON_BENCHMARK_DATA_DIR "twitter.json";
const char *AMAZON_CELLPHONES_NDJSON = SIMDJSON_BENCHMARK_DATA_DIR "amazon_cellphones.ndjson";
#define ASSERT_EQUAL(ACTUAL, EXPECTED) if ((ACTUAL) != (EXPECTED)) { std::cerr << "Expected " << #ACTUAL << " to be " << (EXPECTED) << ", got " << (ACTUAL) << " instead!" << std::endl; return false; }
#define ASSERT_TRUE(ACTUAL) ASSERT_EQUAL(ACTUAL, true)
@ -493,18 +492,18 @@ namespace parse_api_tests {
// }
bool parser_load() {
std::cout << "Running " << __func__ << std::endl;
std::cout << "Running " << __func__ << " on " << TWITTER_JSON << std::endl;
dom::parser parser;
auto [doc, error] = parser.load(JSON_TEST_PATH);
auto [doc, error] = parser.load(TWITTER_JSON);
if (error) { cerr << error << endl; return false; }
if (!doc.is<dom::object>()) { cerr << "Document did not parse as an object" << endl; return false; }
return true;
}
bool parser_load_many() {
std::cout << "Running " << __func__ << std::endl;
std::cout << "Running " << __func__ << " on " << AMAZON_CELLPHONES_NDJSON << std::endl;
dom::parser parser;
int count = 0;
for (auto [doc, error] : parser.load_many(NDJSON_TEST_PATH)) {
for (auto [doc, error] : parser.load_many(AMAZON_CELLPHONES_NDJSON)) {
if (error) { cerr << error << endl; return false; }
if (!doc.is<dom::array>()) { cerr << "Document did not parse as an array" << endl; return false; }
count++;
@ -537,7 +536,7 @@ namespace parse_api_tests {
bool parser_load_exception() {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
const element doc = parser.load(JSON_TEST_PATH);
const element doc = parser.load(TWITTER_JSON);
if (!doc.is<dom::object>()) { cerr << "Document did not parse as an object" << endl; return false; }
return true;
}
@ -545,7 +544,7 @@ namespace parse_api_tests {
std::cout << "Running " << __func__ << std::endl;
dom::parser parser;
int count = 0;
for (const element doc : parser.load_many(NDJSON_TEST_PATH)) {
for (const element doc : parser.load_many(AMAZON_CELLPHONES_NDJSON)) {
if (!doc.is<dom::array>()) { cerr << "Document did not parse as an array" << endl; return false; }
count++;
}
@ -869,7 +868,7 @@ namespace dom_api_tests {
std::cout << "Running " << __func__ << std::endl;
// Prints the number of results in twitter.json
dom::parser parser;
auto [result_count, error] = parser.load(JSON_TEST_PATH)["search_metadata"]["count"].get<uint64_t>();
auto [result_count, error] = parser.load(TWITTER_JSON)["search_metadata"]["count"].get<uint64_t>();
if (error) { cerr << "Error: " << error << endl; return false; }
if (result_count != 100) { cerr << "Expected twitter.json[metadata_count][count] = 100, got " << result_count << endl; return false; }
return true;
@ -880,7 +879,7 @@ namespace dom_api_tests {
// Print users with a default profile.
set<string_view> default_users;
dom::parser parser;
auto [tweets, error] = parser.load(JSON_TEST_PATH)["statuses"].get<dom::array>();
auto [tweets, error] = parser.load(TWITTER_JSON)["statuses"].get<dom::array>();
if (error) { cerr << "Error: " << error << endl; return false; }
for (auto tweet : tweets) {
object user;
@ -905,7 +904,7 @@ namespace dom_api_tests {
// Print image names and sizes
set<pair<uint64_t, uint64_t>> image_sizes;
dom::parser parser;
auto [tweets, error] = parser.load(JSON_TEST_PATH)["statuses"].get<dom::array>();
auto [tweets, error] = parser.load(TWITTER_JSON)["statuses"].get<dom::array>();
if (error) { cerr << "Error: " << error << endl; return false; }
for (auto tweet : tweets) {
auto [media, not_found] = tweet["entities"]["media"].get<dom::array>();
@ -1043,7 +1042,7 @@ namespace dom_api_tests {
std::cout << "Running " << __func__ << std::endl;
// Prints the number of results in twitter.json
dom::parser parser;
element doc = parser.load(JSON_TEST_PATH);
element doc = parser.load(TWITTER_JSON);
uint64_t result_count = doc["search_metadata"]["count"];
if (result_count != 100) { cerr << "Expected twitter.json[metadata_count][count] = 100, got " << result_count << endl; return false; }
return true;
@ -1054,7 +1053,7 @@ namespace dom_api_tests {
// Print users with a default profile.
set<string_view> default_users;
dom::parser parser;
element doc = parser.load(JSON_TEST_PATH);
element doc = parser.load(TWITTER_JSON);
for (object tweet : doc["statuses"].get<dom::array>()) {
object user = tweet["user"];
if (user["default_profile"]) {
@ -1070,7 +1069,7 @@ namespace dom_api_tests {
// Print image names and sizes
set<pair<uint64_t, uint64_t>> image_sizes;
dom::parser parser;
element doc = parser.load(JSON_TEST_PATH);
element doc = parser.load(TWITTER_JSON);
for (object tweet : doc["statuses"].get<dom::array>()) {
auto [media, not_found] = tweet["entities"]["media"];
if (!not_found) {

View File

@ -14,9 +14,10 @@
using namespace simdjson;
using namespace std;
#ifndef JSON_TEST_PATH
#define JSON_TEST_PATH "jsonexamples/twitter.json"
#ifndef SIMDJSON_BENCHMARK_DATA_DIR
#define SIMDJSON_BENCHMARK_DATA_DIR "jsonexamples/"
#endif
const char *TWITTER_JSON = SIMDJSON_BENCHMARK_DATA_DIR "twitter.json";
#define TEST_START() { cout << "Running " << __func__ << " ..." << endl; }
#define ASSERT_ERROR(ACTUAL, EXPECTED) if ((ACTUAL) != (EXPECTED)) { cerr << "FAIL: Unexpected error \"" << (ACTUAL) << "\" (expected \"" << (EXPECTED) << "\")" << endl; return false; }
@ -27,14 +28,14 @@ namespace parser_load {
bool parser_load_capacity() {
TEST_START();
dom::parser parser(1); // 1 byte max capacity
auto [doc, error] = parser.load(JSON_TEST_PATH);
auto [doc, error] = parser.load(TWITTER_JSON);
ASSERT_ERROR(error, CAPACITY);
TEST_SUCCEED();
}
bool parser_load_many_capacity() {
TEST_START();
dom::parser parser(1); // 1 byte max capacity
for (auto [doc, error] : parser.load_many(JSON_TEST_PATH)) {
for (auto [doc, error] : parser.load_many(TWITTER_JSON)) {
ASSERT_ERROR(error, CAPACITY);
TEST_SUCCEED();
}

View File

@ -5,7 +5,7 @@
using namespace simdjson;
int main() {
const char *filename = JSON_TEST_PATH;
const char *filename = SIMDJSON_BENCHMARK_DATA_DIR "/twitter.json";
padded_string p = get_corpus(filename);
dom::parser parser;
auto [doc, error] = parser.parse(p);

View File

@ -1,3 +1,6 @@
add_cpp_tool(json2json)
add_cpp_tool(jsonstats)
add_cpp_tool(minify)
link_libraries(simdjson)
link_libraries(simdjson-windows-headers)
add_executable(json2json json2json.cpp)
add_executable(jsonstats jsonstats.cpp)
add_executable(minify minify.cpp)

View File

@ -1,15 +0,0 @@
function(add_cpp_test TEST_NAME)
add_executable(${TEST_NAME} ${TEST_NAME}.cpp)
target_link_libraries(${TEST_NAME} ${SIMDJSON_LIB_NAME})
add_test(${TEST_NAME} ${TEST_NAME})
endfunction(add_cpp_test)
function(add_cpp_benchmark BENCH_NAME)
add_executable(${BENCH_NAME} ${BENCH_NAME}.cpp)
target_link_libraries(${BENCH_NAME} ${SIMDJSON_LIB_NAME})
endfunction(add_cpp_benchmark)
function(add_cpp_tool TOOL_NAME)
add_executable(${TOOL_NAME} ${TOOL_NAME}.cpp)
target_link_libraries(${TOOL_NAME} ${SIMDJSON_LIB_NAME})
endfunction(add_cpp_tool)

View File

@ -18,13 +18,6 @@ else ()
set (X64 FALSE)
endif ()
if(SIMDJSON_EXCEPTIONS)
set(OPT_FLAGS "${OPT_FLAGS} -DSIMDJSON_EXCEPTIONS=1")
else()
message(STATUS "simdjson exception interface turned off. Code that does not check error codes will not compile.")
set(OPT_FLAGS "${OPT_FLAGS} -DSIMDJSON_EXCEPTIONS=0")
endif()
if(MSVC)
set(CXXSTD_FLAGS "/std:c++17")
else()

4
windows/CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
add_library(simdjson-windows-headers INTERFACE)
if(MSVC)
target_include_directories(simdjson-windows-headers INTERFACE .)
endif()