1 cmake_minimum_required (VERSION 2.8.11) 2 3 # Report AppleClang separately from Clang. Their version numbers are different. 4 # https://cmake.org/cmake/help/v3.0/policy/CMP0025.html 5 if(POLICY CMP0025) 6 cmake_policy(SET CMP0025 NEW) 7 endif() 8 9 # Defer enabling C and CXX languages. 10 project (BoringSSL NONE) 11 12 if(WIN32) 13 # On Windows, prefer cl over gcc if both are available. By default most of 14 # the CMake generators prefer gcc, even on Windows. 15 set(CMAKE_GENERATOR_CC cl) 16 endif() 17 18 include(sources.cmake) 19 20 enable_language(C) 21 enable_language(CXX) 22 23 if(ANDROID) 24 # Android-NDK CMake files reconfigure the path and so Go and Perl won't be 25 # found. However, ninja will still find them in $PATH if we just name them. 26 if(NOT PERL_EXECUTABLE) 27 set(PERL_EXECUTABLE "perl") 28 endif() 29 if(NOT GO_EXECUTABLE) 30 set(GO_EXECUTABLE "go") 31 endif() 32 else() 33 find_package(Perl REQUIRED) 34 find_program(GO_EXECUTABLE go) 35 endif() 36 37 if (NOT GO_EXECUTABLE) 38 message(FATAL_ERROR "Could not find Go") 39 endif() 40 41 if (BORINGSSL_ALLOW_CXX_RUNTIME) 42 add_definitions(-DBORINGSSL_ALLOW_CXX_RUNTIME) 43 endif() 44 45 if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 46 set(CLANG 1) 47 endif() 48 49 if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) 50 # Note clang-cl is odd and sets both CLANG and MSVC. We base our configuration 51 # primarily on our normal Clang one. 52 set(C_CXX_FLAGS "-Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -Wwrite-strings") 53 if(MSVC) 54 # clang-cl sets different default warnings than clang. It also treats -Wall 55 # as -Weverything, to match MSVC. Instead -W3 is the alias for -Wall. 56 # See http://llvm.org/viewvc/llvm-project?view=revision&revision=319116 57 set(C_CXX_FLAGS "${C_CXX_FLAGS} -W3 -Wno-unused-parameter -fmsc-version=1900") 58 # googletest suppresses warning C4996 via a pragma, but clang-cl does not 59 # honor it. Suppress it here to compensate. See https://crbug.com/772117. 60 set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-deprecated-declarations") 61 else() 62 set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wall -ggdb -fvisibility=hidden -fno-common") 63 endif() 64 65 if(CLANG) 66 set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wnewline-eof -fcolor-diagnostics") 67 else() 68 # GCC (at least 4.8.4) has a bug where it'll find unreachable free() calls 69 # and declare that the code is trying to free a stack pointer. 70 set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-free-nonheap-object") 71 endif() 72 73 if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND 74 NOT "6.0.0" VERSION_GREATER CMAKE_C_COMPILER_VERSION) 75 # Clang's -Wtautological-constant-compare is far too aggressive and does not 76 # account for, say, wanting the same code to work on both 32-bit and 64-bit 77 # platforms. 78 # 79 # Note "Clang" and "AppleClang" version differently, so we check for an 80 # exact match on the COMPILER_ID. As of writing, the warning is not in any 81 # release of AppleClang yet. 82 set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wno-tautological-constant-compare -Wtautological-constant-out-of-range-compare") 83 endif() 84 85 if(CLANG OR NOT "7.0.0" VERSION_GREATER CMAKE_C_COMPILER_VERSION) 86 set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wimplicit-fallthrough") 87 endif() 88 89 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes -Wold-style-definition -Wstrict-prototypes") 90 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_CXX_FLAGS} -Wmissing-declarations") 91 92 if(NOT MSVC) 93 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 94 if(APPLE) 95 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 96 endif() 97 if(NOT BORINGSSL_ALLOW_CXX_RUNTIME) 98 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti") 99 endif() 100 endif() 101 102 # In GCC, -Wmissing-declarations is the C++ spelling of -Wmissing-prototypes 103 # and using the wrong one is an error. In Clang, -Wmissing-prototypes is the 104 # spelling for both and -Wmissing-declarations is some other warning. 105 # 106 # https://gcc.gnu.org/onlinedocs/gcc-7.1.0/gcc/Warning-Options.html#Warning-Options 107 # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-prototypes 108 # https://clang.llvm.org/docs/DiagnosticsReference.html#wmissing-declarations 109 if(CLANG) 110 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-prototypes") 111 endif() 112 113 if(CMAKE_COMPILER_IS_GNUCXX AND "4.8" VERSION_GREATER CMAKE_C_COMPILER_VERSION) 114 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-array-bounds") 115 endif() 116 117 elseif(MSVC) 118 set(MSVC_DISABLED_WARNINGS_LIST 119 "C4061" # enumerator 'identifier' in switch of enum 'enumeration' is not 120 # explicitly handled by a case label 121 # Disable this because it flags even when there is a default. 122 "C4100" # 'exarg' : unreferenced formal parameter 123 "C4127" # conditional expression is constant 124 "C4200" # nonstandard extension used : zero-sized array in 125 # struct/union. 126 "C4204" # nonstandard extension used: non-constant aggregate initializer 127 "C4221" # nonstandard extension used : 'identifier' : cannot be 128 # initialized using address of automatic variable 129 "C4242" # 'function' : conversion from 'int' to 'uint8_t', 130 # possible loss of data 131 "C4244" # 'function' : conversion from 'int' to 'uint8_t', 132 # possible loss of data 133 "C4267" # conversion from 'size_t' to 'int', possible loss of data 134 "C4371" # layout of class may have changed from a previous version of the 135 # compiler due to better packing of member '...' 136 "C4388" # signed/unsigned mismatch 137 "C4296" # '>=' : expression is always true 138 "C4350" # behavior change: 'std::_Wrap_alloc...' 139 "C4365" # '=' : conversion from 'size_t' to 'int', 140 # signed/unsigned mismatch 141 "C4389" # '!=' : signed/unsigned mismatch 142 "C4464" # relative include path contains '..' 143 "C4510" # 'argument' : default constructor could not be generated 144 "C4512" # 'argument' : assignment operator could not be generated 145 "C4514" # 'function': unreferenced inline function has been removed 146 "C4548" # expression before comma has no effect; expected expression with 147 # side-effect" caused by FD_* macros. 148 "C4610" # struct 'argument' can never be instantiated - user defined 149 # constructor required. 150 "C4623" # default constructor was implicitly defined as deleted 151 "C4625" # copy constructor could not be generated because a base class 152 # copy constructor is inaccessible or deleted 153 "C4626" # assignment operator could not be generated because a base class 154 # assignment operator is inaccessible or deleted 155 "C4668" # 'symbol' is not defined as a preprocessor macro, replacing with 156 # '0' for 'directives' 157 # Disable this because GTest uses it everywhere. 158 "C4706" # assignment within conditional expression 159 "C4710" # 'function': function not inlined 160 "C4711" # function 'function' selected for inline expansion 161 "C4800" # 'int' : forcing value to bool 'true' or 'false' 162 # (performance warning) 163 "C4820" # 'bytes' bytes padding added after construct 'member_name' 164 "C5026" # move constructor was implicitly defined as deleted 165 "C5027" # move assignment operator was implicitly defined as deleted 166 ) 167 set(MSVC_LEVEL4_WARNINGS_LIST 168 # See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header 169 "C4265" # class has virtual functions, but destructor is not virtual 170 ) 171 string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR 172 ${MSVC_DISABLED_WARNINGS_LIST}) 173 string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR 174 ${MSVC_LEVEL4_WARNINGS_LIST}) 175 set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}") 176 set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}") 177 endif() 178 179 if(WIN32) 180 add_definitions(-D_HAS_EXCEPTIONS=0) 181 add_definitions(-DWIN32_LEAN_AND_MEAN) 182 add_definitions(-DNOMINMAX) 183 # Allow use of fopen. 184 add_definitions(-D_CRT_SECURE_NO_WARNINGS) 185 # VS 2017 and higher supports STL-only warning suppressions. 186 add_definitions("-D_STL_EXTRA_DISABLED_WARNINGS=4774 4987") 187 endif() 188 189 if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.99") OR 190 CLANG) 191 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow") 192 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow") 193 endif() 194 195 if(CMAKE_COMPILER_IS_GNUCXX) 196 if ((CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR CLANG) 197 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") 198 else() 199 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") 200 endif() 201 endif() 202 203 # pthread_rwlock_t requires a feature flag. 204 if(NOT WIN32) 205 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=700") 206 endif() 207 208 if(FUZZ) 209 if(NOT CLANG) 210 message(FATAL_ERROR "You need to build with Clang for fuzzing to work") 211 endif() 212 213 add_definitions(-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE) 214 set(RUNNER_ARGS "-deterministic") 215 216 if(NOT NO_FUZZER_MODE) 217 add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE) 218 set(RUNNER_ARGS ${RUNNER_ARGS} "-fuzzer" "-shim-config" "fuzzer_mode.json") 219 endif() 220 221 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,trace-pc-guard") 222 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,trace-pc-guard") 223 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") 224 link_directories(.) 225 endif() 226 227 add_definitions(-DBORINGSSL_IMPLEMENTATION) 228 229 if (BUILD_SHARED_LIBS) 230 add_definitions(-DBORINGSSL_SHARED_LIBRARY) 231 # Enable position-independent code globally. This is needed because 232 # some library targets are OBJECT libraries. 233 set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) 234 endif() 235 236 if (MSAN) 237 if(NOT CLANG) 238 message(FATAL_ERROR "Cannot enable MSAN unless using Clang") 239 endif() 240 241 if (ASAN) 242 message(FATAL_ERROR "ASAN and MSAN are mutually exclusive") 243 endif() 244 245 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer") 246 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer") 247 set(OPENSSL_NO_ASM "1") 248 endif() 249 250 if (ASAN) 251 if(NOT CLANG) 252 message(FATAL_ERROR "Cannot enable ASAN unless using Clang") 253 endif() 254 255 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer") 256 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer") 257 set(OPENSSL_NO_ASM "1") 258 endif() 259 260 if(CFI) 261 if(NOT CLANG) 262 message(FATAL_ERROR "Cannot enable CFI unless using Clang") 263 endif() 264 265 # TODO(crbug.com/785442): Remove -fsanitize-cfi-icall-generalize-pointers. 266 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=cfi -fno-sanitize-trap=cfi -fsanitize-cfi-icall-generalize-pointers -flto") 267 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=cfi -fno-sanitize-trap=cfi -fsanitize-cfi-icall-generalize-pointers -flto") 268 # We use Chromium's copy of clang, which requires -fuse-ld=lld if building 269 # with -flto. That, in turn, can't handle -ggdb. 270 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld") 271 string(REPLACE "-ggdb" "-g" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 272 string(REPLACE "-ggdb" "-g" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 273 # -flto causes object files to contain LLVM bitcode. Mixing those with 274 # assembly output in the same static library breaks the linker. 275 set(OPENSSL_NO_ASM "1") 276 endif() 277 278 if (GCOV) 279 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") 280 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") 281 endif() 282 283 if(FIPS) 284 add_definitions(-DBORINGSSL_FIPS) 285 if(FIPS_BREAK_TEST) 286 add_definitions("-DBORINGSSL_FIPS_BREAK_${FIPS_BREAK_TEST}=1") 287 endif() 288 # Delocate does not work for ASan and MSan builds. 289 if(NOT ASAN AND NOT MSAN) 290 set(FIPS_DELOCATE "1") 291 endif() 292 endif() 293 294 # CMake's iOS support uses Apple's multiple-architecture toolchain. It takes an 295 # architecture list from CMAKE_OSX_ARCHITECTURES, leaves CMAKE_SYSTEM_PROCESSOR 296 # alone, and expects all architecture-specific logic to be conditioned within 297 # the source files rather than the build. This does not work for our assembly 298 # files, so we fix CMAKE_SYSTEM_PROCESSOR and only support single-architecture 299 # builds. 300 if (NOT OPENSSL_NO_ASM AND CMAKE_OSX_ARCHITECTURES) 301 list(LENGTH CMAKE_OSX_ARCHITECTURES NUM_ARCHES) 302 if (NOT ${NUM_ARCHES} EQUAL 1) 303 message(FATAL_ERROR "Universal binaries not supported.") 304 endif() 305 list(GET CMAKE_OSX_ARCHITECTURES 0 CMAKE_SYSTEM_PROCESSOR) 306 endif() 307 308 if (OPENSSL_NO_ASM) 309 add_definitions(-DOPENSSL_NO_ASM) 310 set(ARCH "generic") 311 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") 312 set(ARCH "x86_64") 313 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64") 314 set(ARCH "x86_64") 315 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64") 316 # cmake reports AMD64 on Windows, but we might be building for 32-bit. 317 if (CMAKE_CL_64) 318 set(ARCH "x86_64") 319 else() 320 set(ARCH "x86") 321 endif() 322 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86") 323 set(ARCH "x86") 324 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386") 325 set(ARCH "x86") 326 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686") 327 set(ARCH "x86") 328 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") 329 set(ARCH "aarch64") 330 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64") 331 set(ARCH "aarch64") 332 elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm*") 333 set(ARCH "arm") 334 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "mips") 335 # Just to avoid the unknown processor error. 336 set(ARCH "generic") 337 elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ppc64le") 338 set(ARCH "ppc64le") 339 else() 340 message(FATAL_ERROR "Unknown processor:" ${CMAKE_SYSTEM_PROCESSOR}) 341 endif() 342 343 if (ANDROID AND NOT ANDROID_NDK_REVISION AND ${ARCH} STREQUAL "arm") 344 # The third-party Android-NDK CMake files somehow fail to set the -march flag 345 # for assembly files. Without this flag, the compiler believes that it's 346 # building for ARMv5. 347 set(CMAKE_ASM_FLAGS "-march=${CMAKE_SYSTEM_PROCESSOR} ${CMAKE_ASM_FLAGS}") 348 endif() 349 350 if (${ARCH} STREQUAL "x86" AND APPLE AND ${CMAKE_VERSION} VERSION_LESS "3.0") 351 # With CMake 2.8.x, ${CMAKE_SYSTEM_PROCESSOR} evalutes to i386 on OS X, 352 # but clang defaults to 64-bit builds on OS X unless otherwise told. 353 # Set ARCH to x86_64 so clang and CMake agree. This is fixed in CMake 3. 354 set(ARCH "x86_64") 355 endif() 356 357 # Add minimal googletest targets. The provided one has many side-effects, and 358 # googletest has a very straightforward build. 359 add_library(boringssl_gtest third_party/googletest/src/gtest-all.cc) 360 target_include_directories(boringssl_gtest PRIVATE third_party/googletest) 361 362 include_directories(third_party/googletest/include) 363 364 # Declare a dummy target to build all unit tests. Test targets should inject 365 # themselves as dependencies next to the target definition. 366 add_custom_target(all_tests) 367 368 add_custom_command( 369 OUTPUT crypto_test_data.cc 370 COMMAND ${GO_EXECUTABLE} run util/embed_test_data.go ${CRYPTO_TEST_DATA} > 371 ${CMAKE_CURRENT_BINARY_DIR}/crypto_test_data.cc 372 DEPENDS util/embed_test_data.go ${CRYPTO_TEST_DATA} 373 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 374 375 add_library(crypto_test_data OBJECT crypto_test_data.cc) 376 377 add_subdirectory(crypto) 378 add_subdirectory(third_party/fiat) 379 add_subdirectory(ssl) 380 add_subdirectory(ssl/test) 381 add_subdirectory(fipstools) 382 add_subdirectory(tool) 383 add_subdirectory(decrepit) 384 385 if(FUZZ) 386 if(LIBFUZZER_FROM_DEPS) 387 file(GLOB LIBFUZZER_SOURCES "util/bot/libFuzzer/*.cpp") 388 add_library(Fuzzer STATIC ${LIBFUZZER_SOURCES}) 389 # libFuzzer does not pass our aggressive warnings. It also must be built 390 # without -fsanitize-coverage options or clang crashes. 391 set_target_properties(Fuzzer PROPERTIES COMPILE_FLAGS "-Wno-shadow -Wno-format-nonliteral -Wno-missing-prototypes -fsanitize-coverage=0") 392 endif() 393 394 add_subdirectory(fuzz) 395 endif() 396 397 if (NOT ${CMAKE_VERSION} VERSION_LESS "3.2") 398 # USES_TERMINAL is only available in CMake 3.2 or later. 399 set(MAYBE_USES_TERMINAL USES_TERMINAL) 400 endif() 401 402 add_custom_target( 403 run_tests 404 COMMAND ${GO_EXECUTABLE} run util/all_tests.go -build-dir 405 ${CMAKE_BINARY_DIR} 406 COMMAND cd ssl/test/runner && 407 ${GO_EXECUTABLE} test -shim-path $<TARGET_FILE:bssl_shim> 408 ${RUNNER_ARGS} 409 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} 410 DEPENDS all_tests bssl_shim 411 ${MAYBE_USES_TERMINAL}) 412