Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify build workflow #469

Merged
merged 11 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,19 @@ endif()

set(hacl_VERSION_TWEAK "")

# Load global config from exteral file.
# This file must be generated before running cmake with ./mach.py --configure
# Load global config from external file.
# For a Clang build, this file can be generated before running cmake with
# ./mach.py --configure
# If the build is invoked through ./mach.py, a separate configuration is not
# needed.
# If the file is not present, i.e. cmake was invoked directly, we copy the default
# config from config/default_config.cmake
# We copy a default config from config/default_config.cmake or
# config/default_config_msvc.cmake
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/build/config.cmake)
configure_file(${PROJECT_SOURCE_DIR}/config/default_config.cmake ${PROJECT_SOURCE_DIR}/build/config.cmake COPYONLY)
if(USE_MSVC)
configure_file(${PROJECT_SOURCE_DIR}/config/default_config_msvc.cmake ${PROJECT_SOURCE_DIR}/build/config.cmake COPYONLY)
else()
configure_file(${PROJECT_SOURCE_DIR}/config/default_config.cmake ${PROJECT_SOURCE_DIR}/build/config.cmake COPYONLY)
endif()
endif()

# Now include the config.
Expand Down Expand Up @@ -85,8 +90,11 @@ set(CMAKE_C_STANDARD_REQUIRED True)
include(build/config.cmake)

# Configure different targets
# TODO: Set flags for MSVC
if(NOT MSVC)
if(MSVC)
add_compile_options(
$<$<COMPILE_LANGUAGE:C,CXX>:/Ob3>
)
else()
add_compile_options(
# -Wall
# -Wextra
Expand All @@ -99,12 +107,20 @@ if(NOT MSVC)
)
endif()

if(WIN32 AND NOT MSVC)
# Enable everywhere for windows as long as libintvector.h is not included correctly.
add_compile_options(
-mavx
-mavx2
)
if(WIN32)
# Enable AVX and AVX2 everywhere for Windows as long as libintvector.h is not included correctly.
if(MSVC)
add_compile_options(
$<$<COMPILE_LANGUAGE:C,CXX>:/arch:AVX>
$<$<COMPILE_LANGUAGE:C,CXX>:/arch:AVX2>
)
else()
# On Windows with clang-cl (our default) we take the Linux assembly
add_compile_options(
-mavx
-mavx2
)
endif()
endif()

# Set include paths
Expand Down
110 changes: 110 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 19,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default Config",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"CMAKE_INSTALL_PREFIX": "${sourceDir}/install/${presetName}",
"BUILD_LIBCRUX": "ON",
"ENABLE_TESTS": "ON",
"ENABLE_BENCHMARKS": "ON"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [ "Windows" ]
}
}
},
{
"name": "ninja.msvc",
"inherits": "default",
"displayName": "x64 Ninja Multi-Config MSVC",
"description": "x64 MSVC build using Ninja Multi-Config generator",
"cacheVariables": {
"USE_MSVC": "ON"
}
},
{
"name": "ninja.clang",
"inherits": "default",
"displayName": "x64 Ninja Multi-Config Clang",
"description": "x64 Clang build using Ninja Multi-Config generator"
}
],
"buildPresets": [
{
"name": "ninja.msvc.Release",
"description": "x64 MSVC build using Ninja Multi-Config generator - Release",
"displayName": "Release",
"configurePreset": "ninja.msvc",
"configuration": "Release"
},
{
"name": "ninja.msvc.Debug",
"description": "x64 MSVC build using Ninja Multi-Config generator - Debug",
"displayName": "Debug",
"configurePreset": "ninja.msvc",
"configuration": "Debug"
},
{
"name": "ninja.msvc.MinSizeRel",
"description": "x64 MSVC build using Ninja Multi-Config generator - MinSizeRel",
"displayName": "MinSizeRel",
"configurePreset": "ninja.msvc",
"configuration": "MinSizeRel"
},
{
"name": "ninja.msvc.RelWithDebInfo",
"description": "x64 MSVC build using Ninja Multi-Config generator - RelWithDebInfo",
"displayName": "RelWithDebInfo",
"configurePreset": "ninja.msvc",
"configuration": "RelWithDebInfo"
},
{
"name": "ninja.clang.Release",
"description": "x64 Clang build using Ninja Multi-Config generator - Release",
"displayName": "Release",
"configurePreset": "ninja.clang",
"configuration": "Release"
},
{
"name": "ninja.clang.Debug",
"description": "x64 Clang build using Ninja Multi-Config generator - Debug",
"displayName": "Debug",
"configurePreset": "ninja.clang",
"configuration": "Debug"
},
{
"name": "ninja.clang.MinSizeRel",
"description": "x64 Clang build using Ninja Multi-Config generator - MinSizeRel",
"displayName": "MinSizeRel",
"configurePreset": "ninja.clang",
"configuration": "MinSizeRel"
},
{
"name": "ninja.clang.RelWithDebInfo",
"description": "x64 Clang build using Ninja Multi-Config generator - RelWithDebInfo",
"displayName": "RelWithDebInfo",
"configurePreset": "ninja.clang",
"configuration": "RelWithDebInfo"
}
]
}
112 changes: 93 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ We need the following dependencies ...
- [cmake] (3.17 or newer)
- [ninja] (1.10 or newer)
- [python] (3.6 or newer)
- [clang] (7 or newer) or [gcc] (7 or newer)
- [clang] (7 or newer), [gcc] (7 or newer), or MSVC on Windows (tested with 19.39.33519)

Depending on your system you can install them as follows (click to expand) ...

Expand Down Expand Up @@ -73,38 +73,112 @@ $ brew install gcc
```
</details>

<details>
<summary><b>Windows</b></summary>

```powershell
> winget install vswhere
> winget install python
> winget install Ninja-build.Ninja
```

To use WinGet to install Visual Studio 2022 with all the required components, first create an installation configuration file `vsconfig` with
the following contents:

```json
{
"version": "1.0",
"components": [
"Microsoft.Component.MSBuild",
"Microsoft.VisualStudio.Component.CoreEditor",
"Microsoft.VisualStudio.Component.NuGet",
"Microsoft.VisualStudio.Component.Roslyn.Compiler",
"Microsoft.VisualStudio.Component.TextTemplating",
"Microsoft.VisualStudio.Component.VC.CoreIde",
"Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.VC.Llvm.Clang",
"Microsoft.VisualStudio.ComponentGroup.ArchitectureTools.Native",
"Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.CMake",
"Microsoft.VisualStudio.Component.VC.CMake.Project",
"Microsoft.VisualStudio.Component.Windows11SDK.22621",
"Microsoft.VisualStudio.Component.Windows11Sdk.WindowsPerformanceToolkit",
"Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core",
"Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.VisualStudio.Workload.NativeDesktop"
]
}
```

Then, for instance, to install the Community edition of Visual Studio 2022 run the following command:

```powershell
> winget install --source winget --exact --id Microsoft.VisualStudio.2022.Community --override "--passive --config C:\vsconfig"
```
</details>

## Build (and test) HACL Packages

You can run ...

```sh
$ ./mach build --test
$ python mach build --test
```

... to build HACL Packages and run the tests. All actions are driven by [mach]. See `python mach --help` for details.

## Detailed build instructions

### Using `mach`

When switching between MSVC and Clang builds, invalidate the CMake cache by deleting `build\.cache` and `build\CMakeCache.txt`

<details>
<summary><b>x64 Release distribution for Windows using Clang</b></summary>

From a Developer Command Prompt for VS 2022.
```powershell
python mach build --release --benchmark --no-openssl
```
</details>

... to build HACL Packages and run the tests. All actions are driven by [mach]. See `./mach --help` for details.
<details>
<summary><b>x64 Release distribution for Windows using MSVC</b></summary>

### MSVC Build
From a Developer Command Prompt for VS 2022.
```powershell
python mach build --release --benchmark --msvc --no-openssl
```
</details>

The hacl-packages build is designed for non-MSVC compilers.
Building with MSVC can be achieved as follows.

### Using CMake

CMake presets have the advantage to provide a consistent build experience across VS, VS Code, and CLI ([CMake Presets integration in Visual Studio and Visual Studio Code](https://devblogs.microsoft.com/cppblog/cmake-presets-integration-in-visual-studio-and-visual-studio-code/)). For instance, when loading the `hacl-packages` folder in Visual Studio 2022, configuration and build presets can be selected from drop-down lists in the toolbar. The presets provided use the Ninja Multi-Config generator. The examples below, show how to build with these presets from a CLI.

<details>
<summary><b>x64 Release distribution for Windows using Clang</b></summary>

From a Developer Command Prompt for VS 2022.
```powershell
cmake --preset ninja.clang
# The build will be in build\ninja.clang\Release
cmake --build --preset ninja.clang.Release
```
</details>

<details>
<summary><b>MSVC Build</b></summary>
<summary><b>x64 Release distribution for Windows using MSVC</b></summary>

From a Developer Command Prompt for VS 2022.
```powershell
# Setup build directory
mkdir build
cp config\default_config_msvc.cmake build\config.cmake
cp config\default_config_msvc.h build\config.h

# Build
cmake -B build -DBUILD_LIBCRUX=1 -G "Visual Studio 17 2022" -A x64 -DUSE_MSVC=1 -DENABLE_TESTS=ON -DENABLE_BENCHMARKS=ON
# Use --config Release to build in release mode
cmake --build build
cmake --preset ninja.msvc
# The build will be in build\ninja.msvc\Release
cmake --build --preset ninja.msvc.Release
```
</details>


## Platform support

The HACL Packages are supported based on the following tiers.
Expand Down Expand Up @@ -185,7 +259,7 @@ packages.

Testing is done with [gtest] and requires a C++11 compiler (or C++20 MSVC).

### Measure Test Coverage
### Measure Test Coverage (on Linux using LLVM)

Test coverage in HACL Packages can be measured with ...

Expand All @@ -195,13 +269,13 @@ Test coverage in HACL Packages can be measured with ...
./tools/coverage.sh
```

Note that only clang is supported as a compiler and you may get an error ...
Note that only Clang is supported as a compiler and you may get an error ...

```
cc: error: unrecognized command-line option ‘-fprofile-instr-generate’; did you mean ‘-fprofile-generate’?
```

... when your default compiler is not clang.
... when your default compiler is not Clang.
In this case, try to set the `CC` and `CXX` environment variables accordingly ...

```sh
Expand Down
33 changes: 0 additions & 33 deletions config/default_config_msvc.h

This file was deleted.

4 changes: 2 additions & 2 deletions tools/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ def dependencies(self, source_dir, algorithm, source_file):
"""
# With old compilers like GCC 4.8 we have to set -march=native for this
# to work.
copmiler_version = subprocess.run(
compiler_version = subprocess.run(
self.compiler + " --version", stdout=subprocess.PIPE, shell=True, check=True
)
stdout = copmiler_version.stdout.decode("utf-8")
stdout = compiler_version.stdout.decode("utf-8")
args = ""
if "4.8" in stdout and "gcc" in stdout:
processor = platform.processor()
Expand Down
Loading