Skip to content

Commit 58d4192

Browse files
authored
Porting to visual studio
Now builds on Visual Studio
1 parent 2b3d6f6 commit 58d4192

40 files changed

+1584
-306
lines changed

CMakeLists.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 2.8)
2-
3-
2+
set(CMAKE_CXX_STANDARD 17)
3+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
44
set(CMAKE_MACOSX_RPATH OFF)
55
if (NOT CMAKE_BUILD_TYPE)
66
message(STATUS "No build type selected, default to Release")
@@ -10,8 +10,11 @@ endif()
1010
project(simdjson)
1111
set(SIMDJSON_LIB_NAME simdjson)
1212

13-
13+
if(NOT MSVC)
1414
option(SIMDJSON_BUILD_STATIC "Build a static library" OFF) # turning it on disables the production of a dynamic library
15+
else()
16+
option(SIMDJSON_BUILD_STATIC "Build a static library" ON) # turning it on disables the production of a dynamic library
17+
endif()
1518
option(SIMDJSON_BUILD_LTO "Build library with Link Time Optimization" OFF)
1619
option(SIMDJSON_SANITIZE "Sanitize addresses" OFF)
1720

README.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,17 @@ twitter.json:
3939

4040
## Requirements
4141

42-
- Linux or macOS (currently)
42+
- We support platforms like Linux or macOS, as well as Windows through Visual Studio 2017 or better.
4343
- A processor with AVX2 (i.e., Intel processors starting with the Haswell microarchitecture released 2013, and processors from AMD starting with the Rizen)
44-
- A recent C++ compiler (e.g., GNU GCC or LLVM CLANG), we assume C++17
45-
- Bash (for benchmark scripts) and other common utilities (optional)
44+
- A recent C++ compiler (e.g., GNU GCC or LLVM CLANG or Visual Studio 2017), we assume C++17
45+
- Some benchmark scripts assume bash and other common utilities, but they are optional.
4646

4747
## License
4848

4949
This code is made available under the Apache License 2.0.
5050

51+
Under Windows, we build some tools using the windows/dirent_portable.h file (which is outside our library code): it under the liberal (business-friendly) MIT license.
52+
5153
## Code example
5254

5355
```C
@@ -80,14 +82,14 @@ of memory allocation with each new JSON document:
8082
const char * filename = ... //
8183
std::string_view p = get_corpus(filename);
8284
ParsedJson pj = build_parsed_json(p); // do the parsing
83-
// you no longer need p at this point, can do free((void*)p.data())
85+
// you no longer need p at this point, can do aligned_free((void*)p.data())
8486
if( ! pj.isValid() ) {
8587
// something went wrong
8688
}
8789
```
8890

8991

90-
## Usage (old-school Makefile)
92+
## Usage (old-school Makefile on platforms like Linux or macOS)
9193

9294
Requirements: clang or gcc and make. A system like Linux or macOS is expected.
9395

@@ -112,7 +114,7 @@ To run comparative benchmarks (with other parsers):
112114
make benchmark
113115
```
114116

115-
## Usage (CMake)
117+
## Usage (CMake on platforms like Linux or macOS)
116118

117119
While in the project repository, do the following:
118120

@@ -136,6 +138,19 @@ make
136138
make test
137139
```
138140

141+
## Usage (CMake on Windows using Visual Studio)
142+
143+
144+
We are assuming that you have a common Windows PC with at least Visual Studio 2017, and an x64 processor with AVX2 support (2013 Haswell or better).
145+
146+
- Grab the simdjosn code from GitHub, e.g., by cloning it using [GitHub Desktop](https://desktop.github.com/).
147+
- Install [CMake](https://cmake.org/download/). When you install it, make sure to ask that ``cmake`` be made available from the command line.
148+
- Create a subdirectory within simdjson, such as ``VisualStudio``.
149+
- Using a shell, go to this newly created directory.
150+
- Type ``cmake -DCMAKE_GENERATOR_PLATFORM=x64 ..`` in the shell while in the ``VisualStudio`` repository. (Alternatively, if you want to build a DLL, you may use the command line ``cmake -DCMAKE_GENERATOR_PLATFORM=x64 -DSIMDJSON_BUILD_STATIC=OFF ..``.)
151+
- This last command created a Visual Studio solution file in the newly created directory (e.g., ``simdjson.sln``). Open this file in Visual Studio. You should now be able to build the project and run the tests. For example, in the ``Solution Explorer`` window (available from the ``View`` menu), right-click ``ALL_BUILD`` and select ``Build``. To test the code, still in the ``Solution Explorer`` window, select ``RUN_TESTS`` and select ``Build``.
152+
153+
139154
## Tools
140155

141156
- `json2json mydoc.json` parses the document, constructs a model and then dumps back the result to standard output.

benchmark/benchmark.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ double diff(timespec start, timespec end) {
106106
clock_gettime(CLOCK_REALTIME, &time1); \
107107
RDTSC_START(cycles_start); \
108108
if (test != expected) { \
109-
printf("not expected (%d , %d )", (int)test, (int)expected); \
109+
fprintf(stderr, "not expected (%d , %d )", (int)test, (int)expected); \
110110
break; \
111111
} \
112112
RDTSC_STOP(cycles_final); \

benchmark/distinctuseridcompetition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,5 +279,5 @@ int main(int argc, char *argv[]) {
279279
!justdata);
280280
BEST_TIME("sasjon ", sasjon_computestats(p).size(), size, , repeat, volume,
281281
!justdata);
282-
free((void*)p.data());
282+
aligned_free((void*)p.data());
283283
}

benchmark/minifiercompetition.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,20 @@ int main(int argc, char *argv[]) {
137137
ParsedJson pj;
138138
bool isallocok = pj.allocateCapacity(p.size(), 1024);
139139
if(!isallocok) {
140-
printf("failed to allocate memory\n");
140+
fprintf(stderr, "failed to allocate memory\n");
141141
return EXIT_FAILURE;
142142
}
143143
BEST_TIME("simdjson orig", json_parse((const uint8_t*)buffer, p.size(), pj), true, memcpy(buffer, p.data(), p.size()), repeat, volume, !justdata);
144144

145145
ParsedJson pj2;
146146
bool isallocok2 = pj2.allocateCapacity(p.size(), 1024);
147147
if(!isallocok2) {
148-
printf("failed to allocate memory\n");
148+
fprintf(stderr, "failed to allocate memory\n");
149149
return EXIT_FAILURE;
150150
}
151151

152152
BEST_TIME("simdjson despaced", json_parse((const uint8_t*)buffer, minisize, pj2), true, memcpy(buffer, minibuffer, p.size()), repeat, volume, !justdata);
153-
free((void*)p.data());
153+
aligned_free((void*)p.data());
154154
free(buffer);
155155
free(ast_buffer);
156156
free(minibuffer);

benchmark/parse.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
#include <assert.h>
22
#include <ctype.h>
3+
#ifndef _MSC_VER
4+
#include <unistd.h>
5+
#include <x86intrin.h>
36
#include <dirent.h>
7+
#else
8+
#include <intrin.h>
9+
#endif
410
#include <inttypes.h>
511
#include <stdbool.h>
612
#include <stdio.h>
713
#include <stdlib.h>
814
#include <string.h>
9-
#include <unistd.h>
10-
#include <x86intrin.h>
1115

1216
#include <algorithm>
1317
#include <chrono>
@@ -41,7 +45,7 @@ int main(int argc, char *argv[]) {
4145
bool jsonoutput = false;
4246
bool forceoneiteration = false;
4347
bool justdata = false;
44-
48+
#ifndef _MSC_VER
4549
int c;
4650

4751
while ((c = getopt(argc, argv, "1vdt")) != -1)
@@ -64,6 +68,9 @@ int main(int argc, char *argv[]) {
6468
default:
6569
abort();
6670
}
71+
#else
72+
int optind = 1;
73+
#endif
6774
if (optind >= argc) {
6875
cerr << "Usage: " << argv[0] << " <jsonfile>" << endl;
6976
exit(1);
@@ -278,9 +285,9 @@ int main(int argc, char *argv[]) {
278285
if (dump) {
279286
isok = isok && pj.dump_raw_tape(std::cout);
280287
}
281-
free((void *)p.data());
288+
aligned_free((void *)p.data());
282289
if (!isok) {
283-
printf(" Parsing failed. \n ");
290+
fprintf(stderr, " Parsing failed. \n ");
284291
return EXIT_FAILURE;
285292
}
286293
return EXIT_SUCCESS;

benchmark/parseandstatcompetition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,5 +300,5 @@ int main(int argc, char *argv[]) {
300300
!justdata);
301301
BEST_TIME("sasjon ", sasjon_computestats(p).valid, true, , repeat, volume,
302302
!justdata);
303-
free((void*)p.data());
303+
aligned_free((void*)p.data());
304304
}

benchmark/parsingcompetition.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ int main(int argc, char *argv[]) {
158158
if(!justdata) BEST_TIME("memcpy ",
159159
(memcpy(buffer, p.data(), p.size()) == buffer), true, , repeat,
160160
volume, !justdata);
161-
free((void *)p.data());
161+
aligned_free((void *)p.data());
162162
free(ast_buffer);
163163
free(buffer);
164164
}

benchmark/statisticalmodel.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <iostream>
2+
#ifndef _MSC_VER
23
#include <unistd.h>
3-
4+
#endif
45
#include "simdjson/jsonioutil.h"
56
#include "simdjson/jsonparser.h"
67
#ifdef __linux__
@@ -112,14 +113,17 @@ stat_t simdjson_computestats(const std::string_view &p) {
112113
}
113114

114115
int main(int argc, char *argv[]) {
115-
int c;
116-
117-
while ((c = getopt(argc, argv, "")) != -1)
116+
#ifndef _MSC_VER
117+
int c;
118+
while ((c = getopt(argc, argv, "")) != -1)
118119
switch (c) {
119120

120121
default:
121122
abort();
122123
}
124+
#else
125+
int optind = 1;
126+
#endif
123127
if (optind >= argc) {
124128
cerr << "Reads json, prints stats. " << endl;
125129
cerr << "Usage: " << argv[0] << " <jsonfile>" << endl;

include/simdjson/common_defs.h

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
#pragma once
1+
#ifndef SIMDJSON_COMMON_DEFS_H
2+
#define SIMDJSON_COMMON_DEFS_H
3+
4+
#include "simdjson/portability.h"
25

36
#include <cassert>
47

58
// the input buf should be readable up to buf + SIMDJSON_PADDING
6-
#define SIMDJSON_PADDING sizeof(__m256i)
7-
9+
#define SIMDJSON_PADDING sizeof(__m256i)
810

11+
#ifndef _MSC_VER
12+
// Implemented using Labels as Values which works in GCC and CLANG (and maybe
13+
// also in Intel's compiler), but won't work in MSVC.
14+
#define SIMDJSON_USE_COMPUTED_GOTO
15+
#endif
916

1017

11-
#ifdef _MSC_VER
12-
/* Microsoft C/C++-compatible compiler */
13-
#include <intrin.h>
14-
#else
15-
#include <x86intrin.h>
16-
#endif
1718

1819

1920
// Align to N-byte boundary
@@ -22,6 +23,24 @@
2223

2324
#define ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
2425

26+
#ifdef _MSC_VER
27+
28+
29+
#define really_inline inline
30+
#define never_inline inline
31+
32+
#define UNUSED
33+
#define WARN_UNUSED
34+
35+
#ifndef likely
36+
#define likely(x) x
37+
#endif
38+
#ifndef unlikely
39+
#define unlikely(x) x
40+
#endif
41+
42+
#else
43+
2544
#define really_inline inline __attribute__((always_inline, unused))
2645
#define never_inline inline __attribute__((noinline, unused))
2746

@@ -35,3 +54,6 @@
3554
#define unlikely(x) __builtin_expect(!!(x), 0)
3655
#endif
3756

57+
#endif // MSC_VER
58+
59+
#endif // COMMON_DEFS_H

0 commit comments

Comments
 (0)