Skip to content

Commit 96e06e2

Browse files
authored
Support building on MSVC (ccache#632)
With these changes, the project builds with Visual Studio 2019, unit tests pass and it works correctly with mingw gcc. NOTE: The very latest version of Visual Studio 2019 is required, because there was just a necessary fix for template arguments. Tested building and running unit tests on Windows+MSVC, Windows+MinGW, Linux and macOS. - Enable `ZSTD_FROM_INTERNET` by default for MSVC when not using vcpkg or conan. - Add include tests for some standard UNIX headers not available on MSVC. - Add necessary MSVC compiler flags. - In `Args::from_gcc_atfile()` iterate over the string via `c_str()` instead of `cbegin()`, the MSVC string character iterator does not include the ending null byte. - Misc. minor cmake fix-ups. - Add some headers that are not implicitly included from other headers like `<algorithm>`, `<ios>`, `<cstdint>` and `<cstdarg>` in some places, gcc does this but MSVC does not. - Add `std::filesystem` version of `Util::traverse()` when dirent.h is not available, which is preferred for performance reasons. - Add implementations of the following functions that are not available in MSVC in Win32Util.cpp: `gettimeofday()`, `localtime_r()`, `asprintf()`. - Add Windows implementation of `getopt_long()` from https://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso to third_party/win32. - Add some compatibility typedefs, constants and macros to the `_WIN32` section of system.hpp, as well as the prototypes for the functions added to Win32Util.cpp. - Fix up unit tests expecting '/' separated paths to expect paths delimited by `DIR_DELIM_CH`. - Invoke test/run with bash from cmake, necessary on msys2+mingw64, many fail, there is more work to do here. - Set the warning level to `/W4` and silence all the uninteresting warning types. Compiles with no warnings now. - Switch to using standard C++ attributes `[[nodiscard]]` and `[[maybe_unused]]` and define macros for gcc for their equivalents. - `#define DOCTEST_CONFIG_USE_STD_HEADERS` for MSVC only, because it requires explicitly including `<ostream>`. - Add vim files to .gitignore. Signed-off-by: Rafael Kitover <[email protected]>
1 parent 2bb9008 commit 96e06e2

28 files changed

+1654
-58
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ testdir/
2323

2424
# Visual Studio Code
2525
/.vscode/
26+
27+
# Vim
28+
.*.sw?
29+
.*.un~

CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,14 @@ endif()
3838
#
3939
# Third party
4040
#
41-
option(ZSTD_FROM_INTERNET "Download and use libzstd from the Internet" OFF)
41+
set(ZSTD_FROM_INTERNET_DEFAULT OFF)
42+
43+
# Default to downloading deps for Visual Studio, unless using a package manager.
44+
if(MSVC AND NOT CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg|conan")
45+
set(ZSTD_FROM_INTERNET_DEFAULT ON)
46+
endif()
47+
48+
option(ZSTD_FROM_INTERNET "Download and use libzstd from the Internet" ${ZSTD_FROM_INTERNET_DEFAULT})
4249
find_package(zstd 1.1.2 REQUIRED)
4350

4451
#

LGPL-3.0.txt

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
GNU LESSER GENERAL PUBLIC LICENSE
2+
Version 3, 29 June 2007
3+
4+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5+
Everyone is permitted to copy and distribute verbatim copies
6+
of this license document, but changing it is not allowed.
7+
8+
9+
This version of the GNU Lesser General Public License incorporates
10+
the terms and conditions of version 3 of the GNU General Public
11+
License, supplemented by the additional permissions listed below.
12+
13+
0. Additional Definitions.
14+
15+
As used herein, "this License" refers to version 3 of the GNU Lesser
16+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
17+
General Public License.
18+
19+
"The Library" refers to a covered work governed by this License,
20+
other than an Application or a Combined Work as defined below.
21+
22+
An "Application" is any work that makes use of an interface provided
23+
by the Library, but which is not otherwise based on the Library.
24+
Defining a subclass of a class defined by the Library is deemed a mode
25+
of using an interface provided by the Library.
26+
27+
A "Combined Work" is a work produced by combining or linking an
28+
Application with the Library. The particular version of the Library
29+
with which the Combined Work was made is also called the "Linked
30+
Version".
31+
32+
The "Minimal Corresponding Source" for a Combined Work means the
33+
Corresponding Source for the Combined Work, excluding any source code
34+
for portions of the Combined Work that, considered in isolation, are
35+
based on the Application, and not on the Linked Version.
36+
37+
The "Corresponding Application Code" for a Combined Work means the
38+
object code and/or source code for the Application, including any data
39+
and utility programs needed for reproducing the Combined Work from the
40+
Application, but excluding the System Libraries of the Combined Work.
41+
42+
1. Exception to Section 3 of the GNU GPL.
43+
44+
You may convey a covered work under sections 3 and 4 of this License
45+
without being bound by section 3 of the GNU GPL.
46+
47+
2. Conveying Modified Versions.
48+
49+
If you modify a copy of the Library, and, in your modifications, a
50+
facility refers to a function or data to be supplied by an Application
51+
that uses the facility (other than as an argument passed when the
52+
facility is invoked), then you may convey a copy of the modified
53+
version:
54+
55+
a) under this License, provided that you make a good faith effort to
56+
ensure that, in the event an Application does not supply the
57+
function or data, the facility still operates, and performs
58+
whatever part of its purpose remains meaningful, or
59+
60+
b) under the GNU GPL, with none of the additional permissions of
61+
this License applicable to that copy.
62+
63+
3. Object Code Incorporating Material from Library Header Files.
64+
65+
The object code form of an Application may incorporate material from
66+
a header file that is part of the Library. You may convey such object
67+
code under terms of your choice, provided that, if the incorporated
68+
material is not limited to numerical parameters, data structure
69+
layouts and accessors, or small macros, inline functions and templates
70+
(ten or fewer lines in length), you do both of the following:
71+
72+
a) Give prominent notice with each copy of the object code that the
73+
Library is used in it and that the Library and its use are
74+
covered by this License.
75+
76+
b) Accompany the object code with a copy of the GNU GPL and this license
77+
document.
78+
79+
4. Combined Works.
80+
81+
You may convey a Combined Work under terms of your choice that,
82+
taken together, effectively do not restrict modification of the
83+
portions of the Library contained in the Combined Work and reverse
84+
engineering for debugging such modifications, if you also do each of
85+
the following:
86+
87+
a) Give prominent notice with each copy of the Combined Work that
88+
the Library is used in it and that the Library and its use are
89+
covered by this License.
90+
91+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
92+
document.
93+
94+
c) For a Combined Work that displays copyright notices during
95+
execution, include the copyright notice for the Library among
96+
these notices, as well as a reference directing the user to the
97+
copies of the GNU GPL and this license document.
98+
99+
d) Do one of the following:
100+
101+
0) Convey the Minimal Corresponding Source under the terms of this
102+
License, and the Corresponding Application Code in a form
103+
suitable for, and under terms that permit, the user to
104+
recombine or relink the Application with a modified version of
105+
the Linked Version to produce a modified Combined Work, in the
106+
manner specified by section 6 of the GNU GPL for conveying
107+
Corresponding Source.
108+
109+
1) Use a suitable shared library mechanism for linking with the
110+
Library. A suitable mechanism is one that (a) uses at run time
111+
a copy of the Library already present on the user's computer
112+
system, and (b) will operate properly with a modified version
113+
of the Library that is interface-compatible with the Linked
114+
Version.
115+
116+
e) Provide Installation Information, but only if you would otherwise
117+
be required to provide such information under section 6 of the
118+
GNU GPL, and only to the extent that such information is
119+
necessary to install and execute a modified version of the
120+
Combined Work produced by recombining or relinking the
121+
Application with a modified version of the Linked Version. (If
122+
you use option 4d0, the Installation Information must accompany
123+
the Minimal Corresponding Source and Corresponding Application
124+
Code. If you use option 4d1, you must provide the Installation
125+
Information in the manner specified by section 6 of the GNU GPL
126+
for conveying Corresponding Source.)
127+
128+
5. Combined Libraries.
129+
130+
You may place library facilities that are a work based on the
131+
Library side by side in a single library together with other library
132+
facilities that are not Applications and are not covered by this
133+
License, and convey such a combined library under terms of your
134+
choice, if you do both of the following:
135+
136+
a) Accompany the combined library with a copy of the same work based
137+
on the Library, uncombined with any other library facilities,
138+
conveyed under the terms of this License.
139+
140+
b) Give prominent notice with the combined library that part of it
141+
is a work based on the Library, and explaining where to find the
142+
accompanying uncombined form of the same work.
143+
144+
6. Revised Versions of the GNU Lesser General Public License.
145+
146+
The Free Software Foundation may publish revised and/or new versions
147+
of the GNU Lesser General Public License from time to time. Such new
148+
versions will be similar in spirit to the present version, but may
149+
differ in detail to address new problems or concerns.
150+
151+
Each version is given a distinguishing version number. If the
152+
Library as you received it specifies that a certain numbered version
153+
of the GNU Lesser General Public License "or any later version"
154+
applies to it, you have the option of following the terms and
155+
conditions either of that published version or of any later version
156+
published by the Free Software Foundation. If the Library as you
157+
received it does not specify a version number of the GNU Lesser
158+
General Public License, you may choose any version of the GNU Lesser
159+
General Public License ever published by the Free Software Foundation.
160+
161+
If the Library as you received it specifies that a proxy can decide
162+
whether future versions of the GNU Lesser General Public License shall
163+
apply, that proxy's public statement of acceptance of any version is
164+
permanent authorization for you to choose that version for the
165+
Library.

LICENSE.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,17 @@ https://www.postgresql.org[PostgreSQL] and has the following license text:
158158
-------------------------------------------------------------------------------
159159
160160
161+
src/third_party/win32/getopt.[hc]
162+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163+
164+
This implementation of `getopt_long()` for Win32 was taken from
165+
https://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso
166+
and is licensed under the LGPL.
167+
168+
The full license text can be found in LGPL-3.0.txt and at
169+
https://www.gnu.org/licenses/lgpl-3.0.html.
170+
171+
161172
src/third_party/nonstd/optional.hpp
162173
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163174

cmake/GenerateConfigurationFile.cmake

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ set(include_files
77
sys/mman.h
88
sys/time.h
99
sys/wait.h
10+
sys/file.h
1011
syslog.h
11-
termios.h)
12+
termios.h
13+
dirent.h
14+
strings.h
15+
unistd.h
16+
utime.h
17+
sys/utime.h
18+
varargs.h)
1219
foreach(include_file IN ITEMS ${include_files})
1320
string(TOUPPER ${include_file} include_var)
1421
string(REGEX REPLACE "[/.]" "_" include_var ${include_var})
@@ -65,5 +72,9 @@ endif()
6572
# alias
6673
set(MTR_ENABLED "${ENABLE_TRACING}")
6774

75+
# Check sizeof(int).
76+
include(CheckTypeSize)
77+
check_type_size(int SIZEOF_INT)
78+
6879
configure_file(${CMAKE_SOURCE_DIR}/cmake/config.h.in
6980
${CMAKE_BINARY_DIR}/config.h @ONLY)

cmake/StandardSettings.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "^GNU|Clang$")
4747
standard_settings
4848
INTERFACE -fsanitize=${LIST_OF_SANITIZERS})
4949
endif()
50+
elseif(MSVC)
51+
target_compile_options(standard_settings INTERFACE /std:c++latest /Zc:preprocessor /Zc:__cplusplus /D_CRT_SECURE_NO_WARNINGS)
5052
endif()

cmake/StandardWarnings.cmake

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,24 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
137137
add_target_compile_flag_if_supported(
138138
standard_warnings "-Wno-unused-variable")
139139
endif()
140+
elseif(MSVC)
141+
# Remove any warning level flags added by cmake.
142+
string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
143+
string(REGEX REPLACE "/W[0-4]" "" CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS}")
144+
string(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
145+
146+
target_compile_options(
147+
standard_warnings
148+
INTERFACE
149+
/W4
150+
# Ignore bad macro in winbase.h triggered by /Zc:preprocessor
151+
/wd5105
152+
# Conversion warnings.
153+
/wd4244
154+
/wd4267
155+
# Assignment in conditional.
156+
/wd4706
157+
# Non-underscore-prefixed POSIX functions.
158+
/wd4996
159+
)
140160
endif()

cmake/config.h.in

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
# pragma clang diagnostic pop
5353
#endif
5454

55+
#define SIZEOF_INT @SIZEOF_INT@
56+
5557
#cmakedefine MTR_ENABLED
5658

5759
/* Define to 1 if you have the `asctime_r' function. */
@@ -126,9 +128,30 @@
126128
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
127129
#cmakedefine HAVE_SYS_WAIT_H
128130

131+
/* Define to 1 if you have the <sys/file.h> header file. */
132+
#cmakedefine HAVE_SYS_FILE_H
133+
129134
/* Define to 1 if you have the <termios.h> header file. */
130135
#cmakedefine HAVE_TERMIOS_H
131136

137+
/* Define to 1 if you have the <dirent.h> header file. */
138+
#cmakedefine HAVE_DIRENT_H
139+
140+
/* Define to 1 if you have the <strings.h> header file. */
141+
#cmakedefine HAVE_STRINGS_H
142+
143+
/* Define to 1 if you have the <unistd.h> header file. */
144+
#cmakedefine HAVE_UNISTD_H
145+
146+
/* Define to 1 if you have the <utime.h> header file. */
147+
#cmakedefine HAVE_UTIME_H
148+
149+
/* Define to 1 if you have the <sys/utime.h> header file. */
150+
#cmakedefine HAVE_SYS_UTIME_H
151+
152+
/* Define to 1 if you have the <varargs.h> header file. */
153+
#cmakedefine HAVE_VARARGS_H
154+
132155
/* Define to 1 if you have the `unsetenv' function. */
133156
#cmakedefine HAVE_UNSETENV
134157

misc/format-files

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ for arg in "$@"; do
2424
done
2525

2626
if [ -n "$all" ]; then
27-
exec "$0" $check $(git ls-files '*.[ch]' '*.[ch]pp' ':!:src/third_party')
27+
exec sh "$0" $check $(git ls-files '*.[ch]' '*.[ch]pp' ':!:src/third_party')
2828
fi
2929

3030
clang_format=${CLANG_FORMAT:-clang-format}

src/Args.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Args::from_gcc_atfile(const std::string& filename)
5353
}
5454

5555
Args args;
56-
auto pos = argtext.cbegin();
56+
auto pos = argtext.c_str();
5757
std::string argbuf;
5858
argbuf.resize(argtext.length() + 1);
5959
auto argpos = argbuf.begin();

0 commit comments

Comments
 (0)