Skip to content

Commit efbfc1f

Browse files
committed
Merged PR 7833797: Fix broken 32-bit Linux pipeline. Refactor toolchain files.
!7775773 added a CI build for 32-bit Linux, but the unit tests didn't run correctly due to a mismatch in architecture names. This PR fixes that issue and refactors a number of other things in our CMakeLists and ADO template to make it more flexible and separate out different parameters that were being used as proxies for each other. - Removed platform and architecture from output paths. CMake requires separate top-level build directories for each platform and architecture, so including the platform and architecture as subdirectories of the build directory provides no benefit and complicates the process of invoking the unit test. - Separated whether to use ASM optimizations from environment definition. Previously we were assuming that the Generic environment implied no ASM optimizations and vice versa, so e.g. building with the `LinuxUserMode` environment but no ASM optimizations was not well-supported. Added a new CMake variable `SYMCRYPT_USE_ASM` for this (defaults to enabled). - Added `SYMCRYPT_FIPS_BUILD` CMake variable which can be used to specify whether or not FIPS integrity verification and self-tests will be run in the Linux modules (defaults to enabled). - No longer running perf tests in CI builds since they take a long time and we don't use CI builds for perf comparisons.
1 parent 1fbad55 commit efbfc1f

23 files changed

+364
-356
lines changed

CMakeLists.txt

Lines changed: 31 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.13.0)
22

33
if(WIN32)
44
# Require Windows 10 SDK version 18362 for BCRYPT_TLS_CBC_HMAC_VERIFY_FLAG
5+
# Must be done before the "project" directive
56
set(CMAKE_SYSTEM_VERSION 10.0.18362)
67
endif()
78

@@ -24,140 +25,46 @@ project(SymCrypt
2425
DESCRIPTION "Cryptographic library"
2526
HOMEPAGE_URL "https://github.com/microsoft/SymCrypt")
2627

27-
if(NOT CMAKE_BUILD_TYPE)
28-
set(CMAKE_BUILD_TYPE Debug)
28+
option(
29+
SYMCRYPT_USE_ASM
30+
"When enabled, SymCrypt will use ASM implementations of performance-critical functions where available.
31+
Not supported on all platforms/architectures."
32+
ON)
33+
34+
if(NOT SYMCRYPT_USE_ASM)
35+
add_compile_options("-DSYMCRYPT_IGNORE_PLATFORM")
2936
endif()
3037

31-
# SYMCRYPT_TARGET_ENV should be set by the toolchain file. If no toolchain file is specified, we will build
32-
# with no CPU-specific optimizations. Some toolchain files may require additional arguments; see the files
33-
# under cmake-toolchain for more information.
34-
if(NOT SYMCRYPT_TARGET_ENV)
35-
message(STATUS "No toolchain file specified (or toolchain file did not set SYMCRYPT_TARGET_ENV).")
36-
message(STATUS "Building for generic environment with SYMCRYPT_IGNORE_PLATFORM.")
37-
set(SYMCRYPT_TARGET_ENV Generic)
38-
add_compile_options(-DSYMCRYPT_IGNORE_PLATFORM)
39-
else()
40-
# Just to avoid an unused variable warning
41-
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
38+
option(
39+
SYMCRYPT_FIPS_BUILD
40+
"When enabled, SymCrypt will build FIPS-compliant modules with self-tests enabled. Not supported on all platforms/architectures.
41+
On Windows, this option is ignored, as self-tests are performed at a higher layer."
42+
ON)
43+
44+
if(SYMCRYPT_FIPS_BUILD)
45+
add_compile_options(-DSYMCRYPT_DO_FIPS_SELFTESTS=1)
46+
endif()
47+
48+
include(${CMAKE_SOURCE_DIR}/cmake-configs/SymCrypt-Platforms.cmake)
49+
50+
if(NOT DEFINED CMAKE_BUILD_TYPE)
51+
set(CMAKE_BUILD_TYPE Debug)
4252
endif()
4353

4454
message(STATUS "Host: ${CMAKE_HOST_SYSTEM_NAME} ${CMAKE_HOST_SYSTEM_PROCESSOR}")
45-
message(STATUS "Target: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_PROCESSOR} ${SYMCRYPT_TARGET_ENV}")
55+
message(STATUS "Target: ${CMAKE_SYSTEM_NAME} ${SYMCRYPT_TARGET_ARCH} ${SYMCRYPT_TARGET_ENV}")
56+
message(STATUS "ASM optimizations: ${SYMCRYPT_USE_ASM}")
57+
message(STATUS "FIPS build: ${SYMCRYPT_FIPS_BUILD}")
4658

4759
# Set output directories binaries
48-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
49-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/module/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
50-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/exe/${CMAKE_SYSTEM_PROCESSOR}/${SYMCRYPT_TARGET_ENV})
51-
52-
if(WIN32)
53-
if(NOT SYMCRYPT_TARGET_ENV MATCHES "Generic")
54-
# Enable ASM_MASM. Annoyingly, this has to be done in the main CMake file rather than in the
55-
# toolchain file
56-
enable_language(ASM_MASM)
57-
endif()
58-
add_compile_options(/MP)
59-
add_compile_options(/Zp8)
60-
# Remove /RTC1, incompatible of /Ox
61-
string( REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
62-
string( REPLACE "/RTC1" "" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
63-
string( REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
64-
string( REPLACE "/RTC1" "" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
65-
# /Od incompatible with /Ox
66-
string( REPLACE "/Od" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
67-
string( REPLACE "/Od" "" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
68-
string( REPLACE "/Od" "" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
69-
string( REPLACE "/Od" "" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
70-
71-
if(CMAKE_BUILD_TYPE MATCHES Release)
72-
add_compile_options(/Oxs)
73-
add_compile_options(/GL)
74-
add_compile_options(/GF)
75-
add_compile_options(/Gy)
76-
add_compile_options(/Gw)
77-
endif()
78-
else()
79-
if(NOT SYMCRYPT_TARGET_ENV MATCHES "Generic")
80-
enable_language(ASM)
81-
# Suppress noisy warnings about compile options which are ignored for ASM
82-
# Less messy than restricting most of the below options to only C/CXX!
83-
add_compile_options($<$<COMPILE_LANGUAGE:ASM>:-Wno-unused-command-line-argument>)
84-
endif()
85-
# add_compile_options(-Wall)
86-
# add_compile_options(-Wno-unknown-pragmas)
87-
add_compile_options(-Wno-deprecated-declarations -Wno-deprecated)
88-
add_compile_options(-g)
89-
add_compile_options(-Wno-multichar)
90-
add_compile_options(-fPIC)
91-
add_compile_options(-fno-plt)
92-
add_compile_options(-fno-builtin-bcmp)
93-
94-
# Required for cross-compiling from AMD64 to ARM64
95-
# Avoids error: cast from pointer to smaller type 'uintptr_t' when including <memory> from aarch64-linux-gnu
96-
add_compile_options(-fms-extensions)
97-
98-
# GCC and clang unroll more aggressively than they should for best performance
99-
# When we want to unroll loops, we unroll in the source code, so tell the compiler not to unroll
100-
# (clang seems to respect this option globally, but I could only make GCC behave in AES-GCM by
101-
# using GCC-specific pragmas for the loops of interest)
102-
add_compile_options(-fno-unroll-loops)
103-
104-
# Do not optimize Debug builds
105-
if (CMAKE_BUILD_TYPE MATCHES Debug)
106-
add_compile_options(-O0)
107-
else()
108-
add_compile_options(-O3)
109-
endif()
110-
111-
# In Sanitize version, enable sanitizers
112-
if (CMAKE_BUILD_TYPE MATCHES Sanitize)
113-
add_compile_options(-fsanitize=address)
114-
add_compile_options(-fsanitize=leak)
115-
116-
# add_compile_options(-fsanitize=undefined)
117-
# Not using undefined as we do not want to include alignment sanitizer
118-
add_compile_options(-fsanitize=bool)
119-
add_compile_options(-fsanitize=builtin)
120-
add_compile_options(-fsanitize=bounds)
121-
add_compile_options(-fsanitize=enum)
122-
add_compile_options(-fsanitize=float-cast-overflow)
123-
add_compile_options(-fsanitize=float-divide-by-zero)
124-
add_compile_options(-fsanitize=integer-divide-by-zero)
125-
add_compile_options(-fsanitize=nonnull-attribute)
126-
add_compile_options(-fsanitize=pointer-overflow)
127-
add_compile_options(-fsanitize=return)
128-
add_compile_options(-fsanitize=returns-nonnull-attribute)
129-
add_compile_options(-fsanitize=shift)
130-
add_compile_options(-fsanitize=signed-integer-overflow)
131-
add_compile_options(-fsanitize=unreachable)
132-
add_compile_options(-fsanitize=vla-bound)
133-
add_compile_options(-fsanitize=vptr)
134-
add_compile_options(-fno-sanitize-recover=all)
135-
add_link_options(-fsanitize=address)
136-
add_link_options(-fsanitize=leak)
137-
add_link_options(-fsanitize=bool)
138-
add_link_options(-fsanitize=builtin)
139-
add_link_options(-fsanitize=bounds)
140-
add_link_options(-fsanitize=enum)
141-
add_link_options(-fsanitize=float-cast-overflow)
142-
add_link_options(-fsanitize=float-divide-by-zero)
143-
add_link_options(-fsanitize=integer-divide-by-zero)
144-
add_link_options(-fsanitize=nonnull-attribute)
145-
add_link_options(-fsanitize=pointer-overflow)
146-
add_link_options(-fsanitize=return)
147-
add_link_options(-fsanitize=returns-nonnull-attribute)
148-
add_link_options(-fsanitize=shift)
149-
add_link_options(-fsanitize=signed-integer-overflow)
150-
add_link_options(-fsanitize=unreachable)
151-
add_link_options(-fsanitize=vla-bound)
152-
add_link_options(-fsanitize=vptr)
153-
add_link_options(-fno-sanitize-recover=all)
154-
endif()
155-
endif()
60+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
61+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/module)
62+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/exe)
15663

15764
if(CMAKE_BUILD_TYPE MATCHES Release)
158-
message("Release mode")
65+
message(STATUS "Release mode")
15966
else()
160-
message("Debug mode")
67+
message(STATUS "Debug mode")
16168
add_compile_options(-DDBG=1)
16269
endif()
16370

README.md

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ be portable to various architectures. However, they do not offer optimal perform
4545
advantage of CPU-specific optimizations. To that end, we also have hand-written assembly implementations of
4646
performance-critical internal functions. Our CMake build scripts do not currently support ASM optimizations on all
4747
combinations of architectures and platforms; the Build Instructions section below lists some of the currently supported
48-
combinations, and we're working on adding support for more.
48+
combinations, and we're working on adding support for more.
4949

50-
The ability to build SymCrypt on any particular platform or architecture, with or without CPU optimizations, does not
50+
The ability to build SymCrypt on any particular platform or architecture, with or without ASM optimizations, does not
5151
imply that it has been tested for or is actively supported by Microsoft on that platform/architecture. While we make
5252
every effort to ensure that SymCrypt is reliable, stable and bug-free on every platform we run on, the code in this
5353
repository is provided *as is*, without warranty of any kind, express or implied, including but not limited to the
@@ -57,24 +57,22 @@ warranties of merchantability, fitness for a particular purpose and noninfringem
5757
1. For Microsoft employees building the library internally, to include msbignum and RSA32 implementation benchmarks in the unit tests:
5858
1. Make sure the SymCryptDependencies submodule is initialized by following the steps above (`git submodule update --init`)
5959
1. In step 4 below, add the additional cmake argument `-DSYMCRYPT_INTERNAL_BUILD=1`
60-
1. `mkdir bin; cd bin`
61-
1. Use the appropriate CMake arguments to specify which architecture you want to compile for:
62-
* For x86-64 Windows targets: `cmake .. -DCMAKE_TOOLCHAIN_FILE="../cmake-toolchain/WindowsUserMode-AMD64.cmake"`
63-
* For x86 Windows targets: `cmake .. -DCMAKE_TOOLCHAIN_FILE="../cmake-toolchain/WindowsUserMode-X86.cmake" -A Win32`
64-
* For x86-64 Linux targets: `cmake .. -DCMAKE_TOOLCHAIN_FILE="../cmake-toolchain/LinuxUserMode-AMD64.cmake"`
65-
* For x86 Linux targets **no ASM optimizations**: `cmake .. -DCMAKE_TOOLCHAIN_FILE="../cmake-toolchain/LinuxUserMode-X86.cmake"`
66-
* For ARM64 Linux targets: `cmake .. -DCMAKE_TOOLCHAIN_FILE="../cmake-toolchain/LinuxUserMode-ARM64.cmake"`
67-
* To use the host system architecture **with no ASM optimizations**: `cmake ..`
68-
* Optionally, for a release build, specify `-DCMAKE_BUILD_TYPE=Release`
69-
1. `cmake --build .`
60+
1. Run `cmake -S . -B bin` to configure your build. You can add the following optional CMake arguments to change build options:
61+
* `-DSYMCRYPT_TARGET_ARCH=<AMD64|X86|ARM64>` to choose a target architecture. If not specified, it will default to the host system architecture.
62+
* To cross-compile for Windows X86 from Windows AMD64, you must also use `-A Win32`
63+
* To cross-compile for Linux ARM64, you must also use `--toolchain=cmake-configs/Toolchain-Clang-ARM64.cmake`
64+
* `-DSYMCRYPT_USE_ASM=<ON|OFF>` to choose whether to use assembly optimizations. Defaults to `ON`.
65+
* `-DSYMCRYPT_FIPS_BUILD=<ON|OFF>` to choose whether to enable FIPS self-tests in the SymCrypt shared object module. Defaults to `ON`. Currently only affects Linux builds.
66+
* For a release build, specify `-DCMAKE_BUILD_TYPE=Release`
67+
1. `cmake --build bin`
7068
* Optionally, for a release build on Windows, specify `--config Release`
7169
* Optionally specify `-jN` where N is the number of processes you wish to spawn for the build
7270

7371
After successful compilation, the generated binaries will be placed in the following directories relative
7472
to your build directory:
75-
* `lib/\<arch\>/\<environment\>/` - static libraries
76-
* `module\<arch\>/\<environment\>/` - shared object libraries (currently only on Linux)
77-
* `exe/\<arch\>/\<environment\>/` - unit tests
73+
* `lib` - static libraries
74+
* `module` - shared object libraries (currently only on Linux)
75+
* `exe` - unit tests
7876

7977
# Testing
8078
The SymCrypt unit test runs extensive functional tests on the SymCrypt library. On Windows it also compares results

0 commit comments

Comments
 (0)