Commit 65274909 authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #467 from harrishancock/vs2017-ice-workaround

Fix VS2017 ICE and add build matrix to appveyor.yml
parents b1701b88 eabee1af
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
# support for. # support for.
# - Use CMake to ... # - Use CMake to ...
# build Cap'n Proto with MinGW. # build Cap'n Proto with MinGW.
# build Cap'n Proto with VS2015. # build Cap'n Proto with VS2015 and VS2017.
# build Cap'n Proto samples with VS2015. # build Cap'n Proto samples with VS2015 and VS2017.
version: "{build}" version: "{build}"
...@@ -32,6 +32,23 @@ environment: ...@@ -32,6 +32,23 @@ environment:
MINGW_ARCHIVE: x86_64-4.8.5-release-win32-seh-rt_v4-rev0.7z MINGW_ARCHIVE: x86_64-4.8.5-release-win32-seh-rt_v4-rev0.7z
BUILD_TYPE: debug BUILD_TYPE: debug
matrix:
# TODO(someday): Add MSVC x64 builds, MinGW x86 build?
- CMAKE_GENERATOR: Visual Studio 15 2017
BUILD_NAME: vs2017
EXTRA_BUILD_FLAGS: # /maxcpucount
# TODO(someday): Right now /maxcpucount occasionally expresses a filesystem-related race:
# capnp-capnpc++ complains that it can't create test.capnp.h.
- CMAKE_GENERATOR: Visual Studio 14 2015
BUILD_NAME: vs2015
EXTRA_BUILD_FLAGS: # /maxcpucount
- CMAKE_GENERATOR: MinGW Makefiles
BUILD_NAME: mingw
EXTRA_BUILD_FLAGS: -j2
install: install:
- if not exist "%MINGW_ARCHIVE%" appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%" - if not exist "%MINGW_ARCHIVE%" appveyor DownloadFile "%MINGW_URL%" -FileName "%MINGW_ARCHIVE%"
- 7z x -y "%MINGW_ARCHIVE%" > nul - 7z x -y "%MINGW_ARCHIVE%" > nul
...@@ -40,34 +57,30 @@ install: ...@@ -40,34 +57,30 @@ install:
before_build: before_build:
- set PATH=%CD%\%MINGW_DIR%\bin;%PATH% - set PATH=%CD%\%MINGW_DIR%\bin;%PATH%
- set INSTALL_PREFIX_MINGW=%CD%\capnproto-c++-mingw - set BUILD_DIR=build-%BUILD_NAME%
- set INSTALL_PREFIX_VS2015=%CD%\capnproto-c++-vs2015 - set INSTALL_PREFIX=%CD%\capnproto-c++-%BUILD_NAME%
- cmake --version - cmake --version
build_script: build_script:
- echo "Building Cap'n Proto with MinGW" - echo "Building Cap'n Proto with %CMAKE_GENERATOR%"
- >- - >-
cmake -Hc++ -Bbuild-mingw -G "MinGW Makefiles" cmake -Hc++ -B%BUILD_DIR% -G "%CMAKE_GENERATOR%"
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
-DCMAKE_INSTALL_PREFIX=%INSTALL_PREFIX_MINGW% -DCMAKE_INSTALL_PREFIX=%INSTALL_PREFIX%
- cmake --build build-mingw --target install -- -j%NUMBER_OF_PROCESSORS% - cmake --build %BUILD_DIR% --config %BUILD_TYPE% --target install -- %EXTRA_BUILD_FLAGS%
# MinGW wants the build type at configure-time while MSVC wants the build type at build-time. We
# can satisfy both by passing the build type to both cmake invocations. We have to suffer a
# warning, but both generators will work.
- echo "Building Cap'n Proto with Visual Studio 2015" - echo "Building Cap'n Proto samples with %CMAKE_GENERATOR%"
- >- - >-
cmake -Hc++ -Bbuild-vs2015 -G "Visual Studio 14 2015" -A x64 cmake -Hc++/samples -B%BUILD_DIR%-samples -G "%CMAKE_GENERATOR%"
-DCMAKE_INSTALL_PREFIX=%INSTALL_PREFIX_VS2015% -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
- cmake --build build-vs2015 --config %BUILD_TYPE% --target install -DCMAKE_PREFIX_PATH=%INSTALL_PREFIX%
# TODO(someday): pass `-- /maxcpucount` for a parallel build. Right now it occasionally expresses - cmake --build %BUILD_DIR%-samples --config %BUILD_TYPE%
# a filesystem-related race: capnp-capnpc++ complains that it can't create test.capnp.h.
- echo "Building Cap'n Proto samples with Visual Studio 2015"
- >-
cmake -Hc++/samples -Bbuild-vs2015-samples -G "Visual Studio 14 2015" -A x64
-DCMAKE_PREFIX_PATH=%INSTALL_PREFIX_VS2015%
- cmake --build build-vs2015-samples --config %BUILD_TYPE%
test_script: test_script:
- timeout /t 2 - timeout /t 2
# Sleep a little to prevent interleaving test output with build output. # Sleep a little to prevent interleaving test output with build output.
- cd build-vs2015\src - cd %BUILD_DIR%\src
- ctest -V -C %BUILD_TYPE% - ctest -V -C %BUILD_TYPE%
project("Cap'n Proto" CXX) project("Cap'n Proto" CXX)
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.1)
set(VERSION 0.7-dev) set(VERSION 0.7-dev)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
...@@ -63,10 +63,11 @@ else() ...@@ -63,10 +63,11 @@ else()
# recognize as safe. # recognize as safe.
# * sign-compare: Low S/N ratio. # * sign-compare: Low S/N ratio.
# * unused-parameter: Low S/N ratio. # * unused-parameter: Low S/N ratio.
# add_compile_options(-Wall -Wextra -Wno-strict-aliasing -Wno-sign-compare -Wno-unused-parameter)
# We have to use -std=gnu++0x isntead of -std=c++11 because otherwise we lose
# GNU extensions that we need. if(DEFINED CMAKE_CXX_EXTENSIONS AND NOT CMAKE_CXX_EXTENSIONS)
add_compile_options(-std=gnu++0x -Wall -Wextra -Wno-strict-aliasing -Wno-sign-compare -Wno-unused-parameter) message(SEND_ERROR "Cap'n Proto requires compiler-specific extensions (e.g., -std=gnu++11). Please leave CMAKE_CXX_EXTENSIONS undefined or ON.")
endif()
if (NOT ANDROID) if (NOT ANDROID)
add_compile_options(-pthread) add_compile_options(-pthread)
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
# cd capnproto/build # cd capnproto/build
# cmake ../c++ -DCMAKE_INSTALL_PREFIX=$PREFIX # cmake ../c++ -DCMAKE_INSTALL_PREFIX=$PREFIX
# cmake --build . --target install # cmake --build . --target install
# export PATH=$PREFIX/bin:$PATH
# #
# 2. Ensure Cap'n Proto's executables are on the PATH, then build the sample project: # 2. Ensure Cap'n Proto's executables are on the PATH, then build the sample project:
# #
...@@ -16,26 +15,9 @@ ...@@ -16,26 +15,9 @@
# cd ../build-samples # cd ../build-samples
# cmake ../c++/samples # cmake ../c++/samples
# cmake --build . # cmake --build .
#
# Caveat for MSVC:
#
# MSVC cannot yet build the Cap'n Proto executables, so there won't be any `$PREFIX/bin` directory
# to put on the PATH. To work around this, you can use CMAKE_PREFIX_PATH or CMAKE_MODULE_PATH to
# find the installed MSVC-built Cap'n Proto package, and set CAPNP_EXECUTABLE and
# CAPNPC_CXX_EXECUTABLE to the MinGW-built executables manually.
#
# Here's an example step 2, assuming a MinGW-built Cap'n Proto is installed at $PREFIX_MINGW and
# an MSVC-built Cap'n Proto is installed at $PREFIX_MSVC:
#
# mkdir ../build-samples
# cd ../build-samples
# cmake ../c++/samples -DCMAKE_PREFIX_PATH=$PREFIX_MSVC \
# -DCAPNP_EXECUTABLE=$PREFIX_MINGW/bin/capnp.exe \
# -DCAPNPC_CXX_EXECUTABLE=$PREFIX_MINGW/bin/capnpc-c++.exe
# cmake --build .
project("Cap'n Proto Samples" CXX) project("Cap'n Proto Samples" CXX)
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.1)
find_package(CapnProto CONFIG REQUIRED) find_package(CapnProto CONFIG REQUIRED)
......
...@@ -58,7 +58,7 @@ set(capnp_schemas ...@@ -58,7 +58,7 @@ set(capnp_schemas
) )
add_library(capnp ${capnp_sources}) add_library(capnp ${capnp_sources})
add_library(CapnProto::capnp ALIAS capnp) add_library(CapnProto::capnp ALIAS capnp)
target_link_libraries(capnp kj) target_link_libraries(capnp PUBLIC kj)
#make sure external consumers don't need to manually set the include dirs #make sure external consumers don't need to manually set the include dirs
target_include_directories(capnp INTERFACE target_include_directories(capnp INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
...@@ -96,7 +96,7 @@ set(capnp-rpc_schemas ...@@ -96,7 +96,7 @@ set(capnp-rpc_schemas
if(NOT CAPNP_LITE) if(NOT CAPNP_LITE)
add_library(capnp-rpc ${capnp-rpc_sources}) add_library(capnp-rpc ${capnp-rpc_sources})
add_library(CapnProto::capnp-rpc ALIAS capnp-rpc) add_library(CapnProto::capnp-rpc ALIAS capnp-rpc)
target_link_libraries(capnp-rpc capnp kj-async kj) target_link_libraries(capnp-rpc PUBLIC capnp kj-async kj)
install(TARGETS capnp-rpc ${INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS capnp-rpc ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${capnp-rpc_headers} ${capnp-rpc_schemas} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/capnp") install(FILES ${capnp-rpc_headers} ${capnp-rpc_schemas} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/capnp")
endif() endif()
...@@ -117,7 +117,7 @@ set(capnp-json_schemas ...@@ -117,7 +117,7 @@ set(capnp-json_schemas
if(NOT CAPNP_LITE) if(NOT CAPNP_LITE)
add_library(capnp-json ${capnp-json_sources}) add_library(capnp-json ${capnp-json_sources})
add_library(CapnProto::capnp-json ALIAS capnp-json) add_library(CapnProto::capnp-json ALIAS capnp-json)
target_link_libraries(capnp-json capnp kj-async kj) target_link_libraries(capnp-json PUBLIC capnp kj-async kj)
install(TARGETS capnp-json ${INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS capnp-json ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${capnp-json_headers} ${capnp-json_schemas} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/capnp/compat") install(FILES ${capnp-json_headers} ${capnp-json_schemas} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/capnp/compat")
endif() endif()
...@@ -138,7 +138,7 @@ set(capnpc_sources ...@@ -138,7 +138,7 @@ set(capnpc_sources
) )
if(NOT CAPNP_LITE) if(NOT CAPNP_LITE)
add_library(capnpc ${capnpc_sources}) add_library(capnpc ${capnpc_sources})
target_link_libraries(capnpc capnp kj) target_link_libraries(capnpc PUBLIC capnp kj)
install(TARGETS capnpc ${INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS capnpc ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${capnpc_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/capnp") install(FILES ${capnpc_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/capnp")
endif() endif()
......
...@@ -59,6 +59,9 @@ set(kj-std_headers ...@@ -59,6 +59,9 @@ set(kj-std_headers
) )
add_library(kj ${kj_sources}) add_library(kj ${kj_sources})
add_library(CapnProto::kj ALIAS kj) add_library(CapnProto::kj ALIAS kj)
target_compile_features(kj PUBLIC cxx_constexpr)
# Requiring the cxx_std_11 metafeature would be preferable, but that doesn't exist until CMake 3.8.
if(UNIX AND NOT ANDROID) if(UNIX AND NOT ANDROID)
target_link_libraries(kj PUBLIC pthread) target_link_libraries(kj PUBLIC pthread)
endif() endif()
...@@ -85,7 +88,7 @@ set(kj-test-compat_headers ...@@ -85,7 +88,7 @@ set(kj-test-compat_headers
) )
add_library(kj-test ${kj-test_sources}) add_library(kj-test ${kj-test_sources})
add_library(CapnProto::kj-test ALIAS kj-test) add_library(CapnProto::kj-test ALIAS kj-test)
target_link_libraries(kj-test kj) target_link_libraries(kj-test PUBLIC kj)
install(TARGETS kj-test ${INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS kj-test ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${kj-test_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/kj") install(FILES ${kj-test_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/kj")
install(FILES ${kj-test-compat_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/kj/compat") install(FILES ${kj-test-compat_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/kj/compat")
...@@ -133,7 +136,7 @@ set(kj-http_headers ...@@ -133,7 +136,7 @@ set(kj-http_headers
if(NOT CAPNP_LITE) if(NOT CAPNP_LITE)
add_library(kj-http ${kj-http_sources}) add_library(kj-http ${kj-http_sources})
add_library(CapnProto::kj-http ALIAS kj-http) add_library(CapnProto::kj-http ALIAS kj-http)
target_link_libraries(kj-http kj-async kj) target_link_libraries(kj-http PUBLIC kj-async kj)
install(TARGETS kj-http ${INSTALL_TARGETS_DEFAULT_ARGS}) install(TARGETS kj-http ${INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES ${kj-http_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/kj/compat") install(FILES ${kj-http_headers} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/kj/compat")
endif() endif()
......
...@@ -853,15 +853,6 @@ class Maybe; ...@@ -853,15 +853,6 @@ class Maybe;
namespace _ { // private namespace _ { // private
#if _MSC_VER
// TODO(msvc): MSVC barfs on noexcept(instance<T&>().~T()) where T = kj::Exception and
// kj::_::Void. It and every other factorization I've tried produces:
// error C2325: 'kj::Blah' unexpected type to the right of '.~': expected 'void'
#define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) __is_nothrow_destructible(T)
#else
#define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) noexcept(instance<T&>().~T())
#endif
template <typename T> template <typename T>
class NullableValue { class NullableValue {
// Class whose interface behaves much like T*, but actually contains an instance of T and a // Class whose interface behaves much like T*, but actually contains an instance of T and a
...@@ -886,7 +877,15 @@ public: ...@@ -886,7 +877,15 @@ public:
ctor(value, other.value); ctor(value, other.value);
} }
} }
inline ~NullableValue() noexcept(MSVC_NOEXCEPT_DTOR_WORKAROUND(T)) { inline ~NullableValue()
#if _MSC_VER
// TODO(msvc): MSVC has a hard time with noexcept specifier expressions that are more complex
// than `true` or `false`. We had a workaround for VS2015, but VS2017 regressed.
noexcept(false)
#else
noexcept(noexcept(instance<T&>().~T()))
#endif
{
if (isSet) { if (isSet) {
dtor(value); dtor(value);
} }
......
...@@ -164,7 +164,7 @@ private: ...@@ -164,7 +164,7 @@ private:
struct WrapperImplInstance { struct WrapperImplInstance {
#if _MSC_VER #if _MSC_VER
// TODO(msvc): MSVC currently fails to initialize vtable pointers for constexpr values so // TODO(msvc): MSVC currently fails to initialize vtable pointers for constexpr values so
// we have to make this just const instead. // we have to make this just const instead.
static const WrapperImpl<ParserImpl> instance; static const WrapperImpl<ParserImpl> instance;
#else #else
static constexpr WrapperImpl<ParserImpl> instance = WrapperImpl<ParserImpl>(); static constexpr WrapperImpl<ParserImpl> instance = WrapperImpl<ParserImpl>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment