Skip to content

Commit ccc94c9

Browse files
authored
Mingw tests (32-bit and 64-bit) (simdjson#1004)
1 parent 1fd30db commit ccc94c9

15 files changed

+165
-17
lines changed

.github/workflows/mingw-ci.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: MinGW32-CI
2+
3+
on: push
4+
5+
6+
# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both.
7+
8+
# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So
9+
# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL.
10+
11+
jobs:
12+
ci:
13+
name: windows-gcc
14+
runs-on: windows-2016
15+
16+
env:
17+
CMAKE_GENERATOR: Ninja # This is critical, try ' cmake -GNinja-DSIMDJSON_BUILD_STATIC=ON .. ' if using the command line
18+
CC: gcc
19+
CXX: g++
20+
21+
steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea
22+
- uses: actions/checkout@v2
23+
24+
- uses: actions/cache@v2 # we cache the scoop setup with 32-bit GCC
25+
id: cache
26+
with:
27+
path: |
28+
C:\ProgramData\scoop
29+
key: scoop32 # static key: should be good forever
30+
- name: Setup Windows # This should almost never run if the cache works.
31+
if: steps.cache.outputs.cache-hit != 'true'
32+
shell: powershell
33+
run: |
34+
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
35+
scoop install sudo --global
36+
sudo scoop install git --global
37+
sudo scoop install ninja --global
38+
sudo scoop install cmake --global
39+
sudo scoop install gcc --arch 32bit --global
40+
$env:path
41+
Write-Host 'Everything has been installed, you are good!'
42+
- name: Build and Test 32-bit x86
43+
shell: powershell
44+
run: |
45+
$ENV:PATH="$ENV:PATH;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\shims;C:\Users\runneradmin\scoop\shims"
46+
mkdir build32
47+
cd build32
48+
cmake -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_COMPETITION=OFF -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_ENABLE_THREADS=OFF ..
49+
cmake --build . --target basictests numberparsingcheck stringparsingcheck errortests integer_tests pointercheck --verbose
50+
ctest . -R stringparsingcheck --output-on-failure
51+
ctest . -R numberparsingcheck --output-on-failure
52+
ctest . -R errortests --output-on-failure
53+
ctest . -R integer_tests --output-on-failure
54+
ctest . -R pointercheck --output-on-failure

.github/workflows/mingw64-ci.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: MinGW64-CI
2+
3+
on: push
4+
5+
6+
# Important: scoop will either install 32-bit GCC or 64-bit GCC, not both.
7+
8+
# It is important to build static libraries because cmake is not smart enough under Windows/mingw to take care of the path. So
9+
# with a dynamic library, you could get failures due to the fact that the EXE can't find its DLL.
10+
11+
jobs:
12+
ci:
13+
name: windows-gcc
14+
runs-on: windows-2016
15+
16+
env:
17+
CMAKE_GENERATOR: Ninja # This is critical, try ' cmake -GNinja-DSIMDJSON_BUILD_STATIC=ON .. ' if using the command line
18+
CC: gcc
19+
CXX: g++
20+
21+
steps: # To reproduce what is below, start a powershell with administrative rights, using scoop *is* a good idea
22+
- uses: actions/checkout@v2
23+
24+
25+
- uses: actions/cache@v2 # we cache the scoop setup with 64-bit GCC
26+
id: cache
27+
with:
28+
path: |
29+
C:\ProgramData\scoop
30+
key: scoop64 # static key: should be good forever
31+
- name: Setup Windows # This should almost never run if the cache works.
32+
if: steps.cache.outputs.cache-hit != 'true'
33+
shell: powershell
34+
run: |
35+
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
36+
scoop install sudo --global
37+
sudo scoop install git --global
38+
sudo scoop install ninja --global
39+
sudo scoop install cmake --global
40+
sudo scoop install gcc --arch 64bit --global
41+
$env:path
42+
Write-Host 'Everything has been installed, you are good!'
43+
- name: Build and Test 64-bit x64
44+
shell: powershell
45+
run: |
46+
$ENV:PATH="$ENV:PATH;C:\ProgramData\scoop\apps\gcc\current\bin;C:\ProgramData\scoop\shims;C:\Users\runneradmin\scoop\shims"
47+
mkdir build64
48+
cd build64
49+
cmake -DSIMDJSON_BUILD_STATIC=ON -DSIMDJSON_COMPETITION=OFF -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_ENABLE_THREADS=OFF ..
50+
cmake --build . --target basictests numberparsingcheck stringparsingcheck errortests integer_tests pointercheck --verbose
51+
ctest . -R stringparsingcheck --output-on-failure
52+
ctest . -R numberparsingcheck --output-on-failure
53+
ctest . -R errortests --output-on-failure
54+
ctest . -R integer_tests --output-on-failure
55+
ctest . -R pointercheck --output-on-failure
56+

cmake/simdjson-flags.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ endif()
5353
option(SIMDJSON_COMPETITION "Compile competitive benchmarks" ON)
5454

5555
option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" ON)
56+
if(SIMDJSON_COMPETITION)
57+
message(STATUS "Using SIMDJSON_GOOGLE_BENCHMARKS")
58+
endif()
5659

5760
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake")
5861

dependencies/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ if ((Git_FOUND) AND (SIMDJSON_IS_UNDER_GIT))
1818
endfunction(initialize_submodule)
1919

2020
if (SIMDJSON_GOOGLE_BENCHMARKS)
21+
message (STATUS "'SIMDJSON_GOOGLE_BENCHMARKS' is requested, configuring..." )
2122
option(BENCHMARK_ENABLE_TESTING OFF)
2223
set(BENCHMARK_ENABLE_TESTING OFF)
2324
option(BENCHMARK_ENABLE_INSTALL OFF)

singleheader/CMakeLists.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ set_source_files_properties(${SINGLEHEADER_FILES} PROPERTIES GENERATED TRUE)
2020

2121
find_program(BASH bash)
2222

23-
if (BASH)
23+
# Under Windows, exectuting a bash script works, except that you cannot generally
24+
# do bash C:/path to my script. You need a "mounted" path: /mnt/c/path
25+
26+
if (BASH AND (NOT WIN32))
2427
add_custom_command(
2528
OUTPUT ${SINGLEHEADER_FILES}
2629
COMMAND ${CMAKE_COMMAND} -E env
@@ -69,7 +72,7 @@ if (BASH)
6972
# add_custom_target(amalgamate DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.h ${CMAKE_CURRENT_SOURCE_DIR}/amalgamate_demo.cpp ${CMAKE_CURRENT_SOURCE_DIR}/README.md)
7073
##
7174

72-
else(BASH)
75+
else()
7376

7477
# We do not have bash, so we use existing amalgamated files instead of generating them ...
7578
# (Do not do this if the source and destination are the same!)
@@ -83,7 +86,7 @@ else(BASH)
8386
)
8487
endif()
8588

86-
endif(BASH)
89+
endif()
8790

8891
#
8992
# Do not depend on singleheader files directly: depend on this target instead.

tests/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ add_cpp_test(unicode_tests LABELS acceptance per_implementation)
6262

6363
find_program(BASH bash)
6464

65+
# Below we skip anything on Windows, not just visual studio, because running bash under Windows requires you to
66+
# map app paths to their "mounted" equivalent (e.g., /mnt/c/...). So even if you have bash under Windows, extra work would be
67+
# required to make things work robustly. Simply put: bash is not quite portable.
6568

6669
# Script tests
67-
if (BASH AND (NOT MSVC) AND (TARGET json2json)) # The scripts are not robust enough to run under Windows even if bash is available
70+
if (BASH AND (NOT WIN32) AND (TARGET json2json)) # The scripts are not robust enough to run under Windows even if bash is available
6871
#
6972
# json2json test
7073
#

tests/basictests.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "test_macros.h"
1919

2020
const size_t AMAZON_CELLPHONES_NDJSON_DOC_COUNT = 793;
21+
#define SIMDJSON_SHOW_DEFINE(x) printf("%s=%s\n", #x, STRINGIFY(x))
2122

2223
namespace number_tests {
2324

@@ -68,7 +69,9 @@ namespace number_tests {
6869
uint64_t ulp = f64_ulp_dist(actual,expected);
6970
if(ulp > maxulp) maxulp = ulp;
7071
if(ulp > 0) {
71-
std::cerr << "JSON '" << buf << " parsed to " << actual << " instead of " << expected << std::endl;
72+
std::cerr << "JSON '" << buf << " parsed to ";
73+
fprintf( stderr," %18.18g instead of %18.18g\n", actual, expected); // formatting numbers is easier with printf
74+
SIMDJSON_SHOW_DEFINE(FLT_EVAL_METHOD);
7275
return false;
7376
}
7477
}
@@ -152,18 +155,25 @@ namespace number_tests {
152155
std::cout << __func__ << std::endl;
153156
char buf[1024];
154157
simdjson::dom::parser parser;
155-
for (int i = -1000000; i <= 308; ++i) {// large negative values should be zero.
158+
159+
bool is_pow_correct{1e-308 == std::pow(10,-308)};
160+
int start_point = is_pow_correct ? -10000 : -307;
161+
if(!is_pow_correct) {
162+
std::cout << "On your system, the pow function is busted. Sorry about that. " << std::endl;
163+
}
164+
for (int i = start_point; i <= 308; ++i) {// large negative values should be zero.
156165
size_t n = snprintf(buf, sizeof(buf), "1e%d", i);
157166
if (n >= sizeof(buf)) { abort(); }
158167
fflush(NULL);
159-
160168
double actual;
161169
auto error = parser.parse(buf, n).get(actual);
162170
if (error) { std::cerr << error << std::endl; return false; }
163171
double expected = ((i >= -307) ? testing_power_of_ten[i + 307]: std::pow(10, i));
164172
int ulp = (int) f64_ulp_dist(actual, expected);
165173
if(ulp > 0) {
166-
std::cerr << "JSON '" << buf << " parsed to " << actual << " instead of " << expected << std::endl;
174+
std::cerr << "JSON '" << buf << " parsed to ";
175+
fprintf( stderr," %18.18g instead of %18.18g\n", actual, expected); // formatting numbers is easier with printf
176+
SIMDJSON_SHOW_DEFINE(FLT_EVAL_METHOD);
167177
return false;
168178
}
169179
}
@@ -1924,6 +1934,7 @@ namespace format_tests {
19241934
}
19251935
}
19261936

1937+
19271938
int main(int argc, char *argv[]) {
19281939
std::cout << std::unitbuf;
19291940
int c;
@@ -1949,6 +1960,11 @@ int main(int argc, char *argv[]) {
19491960
if (simdjson::active_implementation->name() == "unsupported") {
19501961
printf("unsupported CPU\n");
19511962
}
1963+
// We want to know what we are testing.
1964+
std::cout << "Running tests against this implementation: " << simdjson::active_implementation->name();
1965+
std::cout << "(" << simdjson::active_implementation->description() << ")" << std::endl;
1966+
std::cout << "------------------------------------------------------------" << std::endl;
1967+
19521968
std::cout << "Running basic tests." << std::endl;
19531969
if (validate_tests::run() &&
19541970
minify_tests::run() &&

tests/jsoncheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <cstring>
2-
#ifndef _MSC_VER
2+
#if (!(_MSC_VER) && !(__MINGW32__) && !(__MINGW64__))
33
#include <dirent.h>
44
#else
55
// Microsoft can't be bothered to provide standard utils.

tests/numberparsingcheck.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#define JSON_TEST_NUMBERS
1010
#endif
1111

12-
#ifndef _MSC_VER
12+
#if (!(_MSC_VER) && !(__MINGW32__) && !(__MINGW64__))
1313
#include <dirent.h>
1414
#else
1515
#include <dirent_portable.h>
@@ -87,7 +87,11 @@ void found_integer(int64_t result, const uint8_t *buf) {
8787
char *endptr;
8888
long long expected = strtoll((const char *)buf, &endptr, 10);
8989
if ((endptr == (const char *)buf) || (expected != result)) {
90+
#if (!(__MINGW32__) && !(__MINGW64__))
9091
fprintf(stderr, "Error: parsed %" PRId64 " out of %.32s, ", result, buf);
92+
#else // mingw is busted since we include #include <inttypes.h>
93+
fprintf(stderr, "Error: parsed %lld out of %.32s, ", (long long)result, buf);
94+
#endif
9195
fprintf(stderr, " while parsing %s \n", fullpath);
9296
parse_error |= PARSE_ERROR;
9397
}
@@ -98,7 +102,11 @@ void found_unsigned_integer(uint64_t result, const uint8_t *buf) {
98102
char *endptr;
99103
unsigned long long expected = strtoull((const char *)buf, &endptr, 10);
100104
if ((endptr == (const char *)buf) || (expected != result)) {
105+
#if (!(__MINGW32__) && !(__MINGW64__))
101106
fprintf(stderr, "Error: parsed %" PRIu64 " out of %.32s, ", result, buf);
107+
#else // mingw is busted since we include #include <inttypes.h>
108+
fprintf(stderr, "Error: parsed %llu out of %.32s, ", (unsigned long long)result, buf);
109+
#endif
102110
fprintf(stderr, " while parsing %s \n", fullpath);
103111
parse_error |= PARSE_ERROR;
104112
}

tests/parse_many_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <cstring>
2-
#ifndef _MSC_VER
2+
#if (!(_MSC_VER) && !(__MINGW32__) && !(__MINGW64__))
33
#include <dirent.h>
44
#else
55
// Microsoft can't be bothered to provide standard utils.

tests/stringparsingcheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#define JSON_TEST_STRINGS
1313
#endif
1414

15-
#ifndef _MSC_VER
15+
#if (!(_MSC_VER) && !(__MINGW32__) && !(__MINGW64__))
1616
#include <dirent.h>
1717
#else
1818
#include <dirent_portable.h>

tools/minify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <iostream>
2-
#ifndef _MSC_VER
2+
#if (!(_MSC_VER) && !(__MINGW32__) && !(__MINGW64__))
33
#include <dirent.h>
44
#endif
55
#include <unistd.h>

windows/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
add_library(simdjson-windows-headers INTERFACE)
2-
if(MSVC)
2+
if(MSVC OR MINGW)
33
target_include_directories(simdjson-windows-headers INTERFACE .)
44
# getopt.h triggers bogus CRT_SECURE warnings. If you include them, you need this.
55
target_compile_definitions(simdjson-windows-headers INTERFACE _CRT_SECURE_NO_WARNINGS)

windows/dirent_portable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef SIMDBJSON_DIRENT_PORTABLE_INC_
22
#define SIMDBJSON_DIRENT_PORTABLE_INC_
33

4-
#if (!defined(_WIN32) && !defined(_WIN64))
4+
#if (!defined(_WIN32) && !defined(_WIN64) && !(__MINGW32__) && !(__MINGW64__))
55
#include <dirent.h>
66
#else
77
#include "toni_ronnko_dirent.h"

windows/getopt.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#ifndef __GETOPT_H__
2+
/** This file has been modified by D. Lemire for use in simdjson. **/
23
/* From https://github.com/skandhurkat/Getopt-for-Visual-Studio/blob/master/getopt.h */
34
/**
45
* DISCLAIMER
@@ -56,8 +57,9 @@
5657
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
5758
* POSSIBILITY OF SUCH DAMAGE.
5859
*/
59-
60+
#ifdef _MSC_VER
6061
#pragma warning(disable:4996)
62+
#endif
6163

6264
#define __GETOPT_H__
6365

@@ -110,7 +112,9 @@ char *optarg; /* argument associated with option */
110112
extern char __declspec(dllimport) *__progname;
111113
#endif
112114

113-
#if defined(__CYGWIN__) || defined(__clang__) // D. Lemire (April 2020): adding __clang__
115+
// D. Lemire (April 2020): adding __clang__
116+
// D. Lemire (June 2020): adding __MINGW32__ and __MINGW64__
117+
#if defined(__CYGWIN__) || defined(__clang__) || defined(__MINGW32__) || defined(__MINGW64__)
114118
static char EMSG[] = "";
115119
#else
116120
#define EMSG ""

0 commit comments

Comments
 (0)