Skip to content

Commit 1c5e4f1

Browse files
committed
Add clang-cl support
1 parent 0a8a00b commit 1c5e4f1

File tree

3 files changed

+204
-13
lines changed

3 files changed

+204
-13
lines changed

azure-pipelines.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
trigger:
2+
- master
3+
4+
jobs:
5+
6+
# Configure, build, install, and test job
7+
- job: 'build'
8+
pool:
9+
vmImage: 'vs2015-win2012r2'
10+
timeoutInMinutes: 360
11+
steps:
12+
13+
# Install Chocolatey (https://chocolatey.org/install#install-with-powershellexe)
14+
- powershell: |
15+
Set-ExecutionPolicy Bypass -Scope Process -Force
16+
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
17+
Write-Host "##vso[task.setvariable variable=PATH]$env:PATH"
18+
choco --version
19+
displayName: "Install Chocolatey"
20+
21+
# Install Miniconda
22+
- script: |
23+
choco install miniconda3 --yes
24+
set PATH=C:\tools\miniconda3\Scripts;C:\tools\miniconda3;C:\tools\miniconda3\Library\bin;%PATH%
25+
echo '##vso[task.setvariable variable=PATH]%PATH%'
26+
set LIB=C:\tools\miniconda3\Library\lib;%LIB%
27+
echo '##vso[task.setvariable variable=LIB]%LIB%'
28+
conda --version
29+
displayName: "Install Miniconda"
30+
31+
# Configure Miniconda
32+
- script: |
33+
conda config --set always_yes yes
34+
conda config --append channels conda-forge
35+
conda info
36+
displayName: "Configure Miniconda"
37+
38+
# Create conda enviroment
39+
# Note: conda activate doesn't work here, because it creates a new shell!
40+
- script: |
41+
conda install cmake ^
42+
gtest ^
43+
ninja ^
44+
pybind11 ^
45+
pytest ^
46+
numpy ^
47+
xtensor==0.20.4 ^
48+
python=3.6
49+
conda list
50+
displayName: "Install conda packages"
51+
52+
# Install LLVM
53+
# Note: LLVM distributed by conda is too old
54+
- script: |
55+
choco install llvm --yes
56+
set PATH=C:\Program Files\LLVM\bin;%PATH%
57+
echo '##vso[task.setvariable variable=PATH]%PATH%'
58+
clang-cl --version
59+
displayName: "Install LLVM"
60+
61+
# Configure
62+
- script: |
63+
setlocal EnableDelayedExpansion
64+
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
65+
mkdir build & cd build
66+
cmake -G Ninja ^
67+
-DCMAKE_BUILD_TYPE=Release ^
68+
-DCMAKE_C_COMPILER=clang-cl ^
69+
-DCMAKE_CXX_COMPILER=clang-cl ^
70+
-DBUILD_TESTS=ON ^
71+
-DCMAKE_INSTALL_PREFIX=C:\tools\miniconda3 ^
72+
$(Build.SourcesDirectory)
73+
displayName: "Configure xtensor-python"
74+
workingDirectory: $(Build.BinariesDirectory)
75+
76+
# Build
77+
- script: |
78+
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
79+
cmake --build . ^
80+
--config Release ^
81+
--target test_xtensor_python ^
82+
-- -v
83+
displayName: "Build xtensor-python"
84+
workingDirectory: $(Build.BinariesDirectory)/build
85+
86+
# Install
87+
- script: |
88+
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
89+
cmake --build . ^
90+
--config Release ^
91+
--target install ^
92+
-- -v
93+
displayName: "Install xtensor-python"
94+
workingDirectory: $(Build.BinariesDirectory)/build
95+
96+
# Test
97+
- script: |
98+
setlocal EnableDelayedExpansion
99+
py.test -s
100+
cd test
101+
.\test_xtensor_python
102+
displayName: "Test xtensor-python"
103+
workingDirectory: $(Build.BinariesDirectory)/build/test

test/CMakeLists.txt

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,10 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
1212
project(xtensor-python-test)
1313

1414
find_package(pybind11 REQUIRED)
15-
set(PYBIND11_INCLUDE_DIR ${pybind11_INCLUDE_DIRS})
1615

1716
find_package(xtensor REQUIRED CONFIG)
18-
set(XTENSOR_INCLUDE_DIR ${xtensor_INCLUDE_DIRS})
1917

2018
find_package(xtensor-python REQUIRED CONFIG)
21-
set(XTENSOR_PYTHON_INCLUDE_DIR ${xtensor-python_INCLUDE_DIRS})
2219
endif ()
2320

2421
message(STATUS "Forcing tests build type to Release")
@@ -28,20 +25,45 @@ include(CheckCXXCompilerFlag)
2825

2926
string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)
3027

31-
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
32-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native -Wunused-parameter -Wextra -Wreorder -Wconversion -fvisibility=hidden")
33-
CHECK_CXX_COMPILER_FLAG("-std=c++14" HAS_CPP14_FLAG)
28+
include(set_compiler_flag.cmake)
29+
30+
if(CPP17)
31+
# User requested C++17, but compiler might not oblige.
32+
set_compiler_flag(
33+
_cxx_std_flag CXX
34+
"-std=c++17" # this should work with GNU, Intel, PGI
35+
"/std:c++17" # this should work with MSVC
36+
)
37+
if(_cxx_std_flag)
38+
message(STATUS "Building with C++17")
39+
endif()
40+
else()
41+
set_compiler_flag(
42+
_cxx_std_flag CXX REQUIRED
43+
"-std=c++14" # this should work with GNU, Intel, PGI
44+
"/std:c++14" # this should work with MSVC
45+
)
46+
message(STATUS "Building with C++14")
47+
endif()
3448

35-
if (HAS_CPP14_FLAG)
36-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
37-
else()
38-
message(FATAL_ERROR "Unsupported compiler -- xtensor requires C++14 support!")
39-
endif()
49+
if(NOT _cxx_std_flag)
50+
message(FATAL_ERROR "xtensor-blas needs a C++14-compliant compiler.")
4051
endif()
4152

42-
if(MSVC)
43-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /bigobj")
53+
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR (CMAKE_CXX_COMPILER_ID MATCHES "Intel" AND NOT WIN32))
54+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_cxx_std_flag} -march=native -Wunused-parameter -Wextra -Wreorder -Wconversion -fvisibility=hidden")
55+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
56+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_cxx_std_flag} /EHsc /MP /bigobj")
57+
set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO)
58+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
59+
if(NOT WIN32)
60+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_cxx_std_flag} -march=native -Wunused-parameter -Wextra -Wreorder -Wconversion -fvisibility-hidden")
61+
else() # We are using clang-cl
62+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_cxx_std_flag} /EHsc /MP /bigobj")
4463
set(CMAKE_EXE_LINKER_FLAGS /MANIFEST:NO)
64+
endif()
65+
else()
66+
message(FATAL_ERROR "Unsupported compiler: ${CMAKE_CXX_COMPILER_ID}")
4567
endif()
4668

4769
if (DOWNLOAD_GTEST OR GTEST_SRC_DIR)

test/set_compiler_flag.cmake

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Copied from
2+
# https://github.com/dev-cafe/cmake-cookbook/blob/master/chapter-07/recipe-03/c-cxx-example/set_compiler_flag.cmake
3+
# Adapted from
4+
# https://github.com/robertodr/ddPCM/blob/expose-C-api/cmake/custom/compilers/SetCompilerFlag.cmake
5+
# which was adapted by Roberto Di Remigio from
6+
# https://github.com/SethMMorton/cmake_fortran_template/blob/master/cmake/Modules/SetCompileFlag.cmake
7+
8+
# Given a list of flags, this stateless function will try each, one at a time,
9+
# and set result to the first flag that works.
10+
# If none of the flags works, result is "".
11+
# If the REQUIRED key is given and no flag is found, a FATAL_ERROR is raised.
12+
#
13+
# Call is:
14+
# set_compile_flag(result (Fortran|C|CXX) <REQUIRED> flag1 flag2 ...)
15+
#
16+
# Example:
17+
# set_compiler_flag(working_compile_flag C REQUIRED "-Wall" "-warn all")
18+
19+
include(CheckCCompilerFlag)
20+
include(CheckCXXCompilerFlag)
21+
include(CheckFortranCompilerFlag)
22+
23+
function(set_compiler_flag _result _lang)
24+
# build a list of flags from the arguments
25+
set(_list_of_flags)
26+
# also figure out whether the function
27+
# is required to find a flag
28+
set(_flag_is_required FALSE)
29+
foreach(_arg IN ITEMS ${ARGN})
30+
string(TOUPPER "${_arg}" _arg_uppercase)
31+
if(_arg_uppercase STREQUAL "REQUIRED")
32+
set(_flag_is_required TRUE)
33+
else()
34+
list(APPEND _list_of_flags "${_arg}")
35+
endif()
36+
endforeach()
37+
38+
set(_flag_found FALSE)
39+
# loop over all flags, try to find the first which works
40+
foreach(flag IN ITEMS ${_list_of_flags})
41+
42+
unset(_flag_works CACHE)
43+
if(_lang STREQUAL "C")
44+
check_c_compiler_flag("${flag}" _flag_works)
45+
elseif(_lang STREQUAL "CXX")
46+
check_cxx_compiler_flag("${flag}" _flag_works)
47+
elseif(_lang STREQUAL "Fortran")
48+
check_Fortran_compiler_flag("${flag}" _flag_works)
49+
else()
50+
message(FATAL_ERROR "Unknown language in set_compiler_flag: ${_lang}")
51+
endif()
52+
53+
# if the flag works, use it, and exit
54+
# otherwise try next flag
55+
if(_flag_works)
56+
set(${_result} "${flag}" PARENT_SCOPE)
57+
set(_flag_found TRUE)
58+
break()
59+
endif()
60+
endforeach()
61+
62+
# raise an error if no flag was found
63+
if(_flag_is_required AND NOT _flag_found)
64+
message(FATAL_ERROR "None of the required flags were supported")
65+
endif()
66+
endfunction()

0 commit comments

Comments
 (0)