Initial commit of CMake build support

This commit is contained in:
Paul Reeves 2023-05-13 09:44:49 +02:00
parent 5803eacbcb
commit e0be67f243
9 changed files with 1254 additions and 0 deletions

2
.gitignore vendored
View File

@ -34,3 +34,5 @@ rsatest
rsatest.exe
timing
timing.exe
/Build/
/cmake/sources.txt

464
CMake.sh Executable file
View File

@ -0,0 +1,464 @@
#!/bin/bash
todo() {
<< TODO
- Continue with adding platform(s)
- Add support for other platforms such as x86.
- Add support for Release | Debug | DebugInfo etc.
- If generating CodeBlocks support...
- Parse the source and for each CMakeLists found add it to the workspace
TODO
}
load_opts() {
GETOPT=$( getopt -o bcdDfhiru \
--long build,cmakehelp,debug,dry-run,fbver:,fresh,help,info,reset,usecodeblocks,verbose \
-n "$0" -- "$@" )
}
ShowHelp(){
tabs 3,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77
DOCNOTE=$(cat << MSG > ${BASENAME}-readme.md
# CMake wrapper script
This script encapsulates the necessary calls to the CMake binary to configure
and generate the makefiles required to build this application.
Optionally a full build can also be executed.
### Options
- (boolean) help
Outputs this help screen and quits.
- (boolean) build
Will execute make in the build dir if makefile generation was successful.
- (boolean) cmakehelp
Outputs the CMake help screen and quits.
- (string) --fbver
The firebird version to build against.
This must be in the format 'fb4', 'fb5' etc.
The script will exit if this parameter is not supplied.
NOTE: Currently this application does not need to know the firebird version.
This setting is just a formality. However, firebird __MUST__ be installed.
- (boolean) --fresh
Pass --fresh to cmake, removing existing cache files.
- (boolean) --reset
Delete the Build dir. Recommended if thinks start to go wrong after
successive runs of CMake but should not usually be required.
- (boolean) --usecodeblocks
Generates CodeBlocks project files in addition to standard make files
These will be placed under the Build dir.
(Not tested.)
### Examples
- Configure and Generate make files for all platforms
CMake.sh --fbver fb4
- Check the CMake Help screen
CMake.sh --cmakehelp
- Configure, Generate and build all platforms
CMake.sh --fbver fb4 -build
MSG
)
cat ${BASENAME}-readme.md
}
######################### START OF GENERIC FUNCTIONS #########################
Pause(){
local _aprompt=""
if [ "${1:-}" = "" ]; then
_aprompt="Press any key to continue..."
else
_aprompt="$*"
fi
#shellcheck disable=SC2162
read -p "$_aprompt"
}
GetTime(){
export LOGSTAMP=$(date "+%Y-%m-%d %H:%M:%S")
export DATESTAMP=$(date +%Y%m%d)
export TIMESTAMP=$(date +%Y%m%d-%H%M%S)
export TAGSTAMP=$(date +:%Y%m%d%H%M)
case "${1:-}" in
LOGSTAMP)
echo LOGSTAMP is "$LOGSTAMP"
;;
DATESTAMP)
echo DATE is "$DATESTAMP"
;;
TIMESTAMP)
echo TIMESTAMP is "$TIMESTAMP"
;;
TAGSTAMP)
echo TAGSTAMP is "$TAGSTAMP"
;;
esac
}
GetLogStamp() {
GetTime "LOGSTAMP"
}
Debug() {
# Debug is intended for printing values assigned to variables etc.
if [ "${DEBUG:-}" == "1" ]; then
GetTime
local FUNC=$1
shift
echo -e $LOGSTAMP $FUNC "-" "$@"
fi
}
Verbose() {
# Verbose is intended to give the user a more
# detailed narrative of programm execution.
# shellcheck disable=SC2166
if [ "${VERBOSE:-}" == "1" -o "${DEBUG:-}" == "1" ]; then
GetTime
if [ "${2:-}" = "" ]; then
echo -e $LOGSTAMP "$@"
else
local FUNC=${1:-}
shift
echo -e $LOGSTAMP $FUNC "-" "$@"
fi
fi
}
EchoSpacer() {
set +x
# Echo a divider line to output
if [ -z ${1:-} ]; then
_spacer="-"
else
_spacer=$1
fi
if [ -z ${2:-} ]; then
_repeat="80"
else
_repeat=$2
fi
echo -e "\n"
for a in $(seq 1 ${_repeat} )
do
echo -n "$_spacer"
done
echo -e "\n"
}
WriteLog() {
# Param 1 - Logfile
# Param 2 - FUNCNAME
# We automatically call Verbose after shifting LOGFILE
# We then shift FUNCNAME and write out to the log.
GetTime
local LOGFILE=${1:-}
shift
Verbose "$@"
# shellcheck disable=SC2166
if [ ! "${VERBOSE:-}" = 1 -o ! "${DEBUG:-}" = 1 ]; then
shift
fi
if [ ! "${LOGFILE:-}" = "" ]; then
echo -e $LOGSTAMP "-" "$@" >> $LOGFILE
fi
}
Stop() {
# echo an error code and a message and stop execution.
local _err=0
if [ "${1:-}" -ge 0 ] 2>/dev/null ; then
_err=$1
shift
fi
echo "$@"
exit $_err
}
Error(){
local _err=0
if [ "${1:-}" -ge 0 ] 2>/dev/null ; then
_err=$1
shift
fi
EchoSpacer
echo ""
echo " Error in $0"
echo " $* "
echo ""
EchoSpacer
return $_err
<< COMMENT
Use Error on its own thus:
Error 1 A remark about the error
In this case it is up to the caller to test the error code
Or use it with Stop:
Error 1 A remark about the error
Stop $?
COMMENT
}
######################### END OF GENERIC FUNCTIONS #########################
ResetVars() {
unset BUILD
unset CMAKEHELP
unset DEBUG
unset DRYRUN
unset FRESH
unset FBVER
unset RESET
unset SHOWINFO
unset USECODEBLOCKS
BASENAME=$(basename "$0" .sh)
GENERATOR="Unix Makefiles"
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
}
ParseCommandLine() {
#set -x
if [ $# -le 0 ]; then
ShowHelp
return 1
fi
eval set -- "$GETOPT"
while true; do
case "${1:-}" in
-h|--help) return 1 ;;
-b|--build)
BUILD=" --build ";
shift;
;;
-c|--cmakehelp)
CMAKEHELP=" --help ";
shift;
;;
-d|--debug)
DEBUG=1;
shift;
;;
-D|--dry-run)
DRYRUN=1;
shift;
;;
-f|--fresh)
FRESH=" --fresh ";
shift;
;;
--fbver)
if [ "$2" ] > /dev/null 2>&1; then
FBVER="$2";
fi
shift; shift;
;;
-i|--info)
SHOWINFO=1;
shift;
;;
-r|--reset)
RESET=1;
shift;
;;
-u|--usecodeblocks)
GENERATOR="CodeBlocks - Unix Makefiles";
shift;
;;
-v|--verbose)
VERBOSE=1;
shift;
;;
--)
shift;
break;
;;
*)
echo "Invalid Option ${1:-}";
#ShowHelp
shift; shift;
return 1;
;;
esac
done
}
RemoveBuildDir() {
if [ -d $SCRIPTPATH/Build ]; then
Verbose Removing $SCRIPTPATH/Build directory
rm $SCRIPTPATH/Build --recursive
else
Verbose $SCRIPTPATH/Build directory does not exist.
fi
}
CheckParams() {
if [ "${RESET:-}" == "1" ]; then
RemoveBuildDir
fi
if [ ! "${CMAKEHELP:-}" == "" ]; then
cmake $CMAKEHELP
Stop $?
fi
}
ShowInfo() {
Debug Entering FUNCNAME "$FUNCNAME"
if [ "${SHOWINFO:-}" == "1" ]; then
echo
echo g++ version is...........$(g++ --version) | cut -c1-80
echo cmake version is ........$(cmake --version) | cut -c1-80
echo make version is..........$(make --version) | cut -c1-80
echo
fi
return 0
}
Generate() {
Debug Entering FUNCNAME "$FUNCNAME"
local _err=0
# Be sure that we are actually in the root of our repo.
pushd $SCRIPTPATH > /dev/null
_cmdstr='cmake ${FRESH:-} -G "${GENERATOR}" -S . -B Build '
Verbose Executing "$_cmdstr"
eval "$_cmdstr"
_err=$?
popd > /dev/null
return $_err
}
Build() {
if [ "${BUILD:-}" != "" ]; then
pushd $SCRIPTPATH/Build > /dev/null
make
popd > /dev/null
fi
}
main () {
EchoSpacer "="
ResetVars
load_opts "$@"
#set -x
ParseCommandLine "$@" || return 1
CheckParams
ShowInfo
Generate || return $?
Build
EchoSpacer "="
}
main "$@"
if [ $? -ne 0 ]; then echo "An error occurred."; fi
set +x

223
CMakeLists.txt Normal file
View File

@ -0,0 +1,223 @@
##
## THIS IS THE MASTER FILE
## It contains some basic defaults and defintions that are inherited by the projects
##
################################################################################
# CONTENTS
#
# Project header
# CMake globals
# Project Settings
# Options
# Targets
# Testing (TODO)
# Packaging (TODO)
################################################################################
cmake_minimum_required(VERSION 3.25 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
include(ConfigSafeGuards)
################################################################################
#
# Project header
#
#################################################################################
# Suppress "Policy CMP0066 is not set"
# This policy provides compatibility for projects that do not expect
# config-specific compiler flags to be used.
# See https://cmake.org/cmake/help/latest/policy/CMP0066.html
#set (CMAKE_POLICY_WARNING_CMP0066 OFF)
cmake_minimum_required(VERSION 3.10)
# tomsfastmath - modified from CMakeLists.txt created for libtomath
project (TOMSFASTMATH
VERSION 0.13.1
DESCRIPTION "TomsFastMath is meant to be a very fast yet still fairly portable and easy to port large integer arithmetic library written in ISO C."
HOMEPAGE_URL "https://github.com/libtom/tomsfastmath"
LANGUAGES C)
# package release version
# bump if re-releasing the same VERSION + patches
# set to 1 if releasing a new VERSION
set(PACKAGE_RELEASE_VERSION 1)
################################################################################
#
# CMake Global Settings
#
################################################################################
# Allow use of function cmake_print_variables to print vars to output
# See https://cmake.org/cmake/help/latest/module/CMakePrintHelpers.html
include(CMakePrintHelpers)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "Export compile_commands.json to support editors such as Kate, Visual Studio Code, Vim etc.")
set(CMAKE_VERBOSE_MAKEFILE ON CACHE INTERNAL "Generate verbose makefile")
# For tomsfastmath we use Build, although convention is to use all lowercase
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/Build)
################################################################################
#
# Project Settings
#
#################################################################################
# Define build mode - this must be executed AFTER the project command otherwise
# the cmake compiler will complain that CMAKE_BUILD_TYPE is uninitialised.
message(STATUS "CMAKE_BUILD_TYPE is ${CMAKE_BUILD_TYPE}")
if (NOT DEFINED CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build...")
endif()
if ( UNIX )
set(CMAKE_INSTALL_PREFIX /opt/fireswarm CACHE PATH "Default installation directory" FORCE)
elseif ( WIN32 )
set(CMAKE_INSTALL_PREFIX $ENV{ProgramFiles}/fireswarm CACHE PATH "Default installation directory" FORCE)
endif()
################################################################################
#
# Option Settings
#
#################################################################################
# ### Options: Things you can set via commandline options to cmake (e.g. -DTOMSFASTMATH_DISABLE_LIBCXX=[ON|OFF])
option(BUILD_SHARED_LIBS "Build shared library" ON)
option(TOMSFASTMATH_DISABLE_LIBCXX "Do not use libc++, even if available" ON)
option(ENABLE_WARNINGS_SETTINGS "Allow target_set_warnings to add flags and defines.
Set this to OFF if you want to provide your own warning parameters.
See cmake/Warnings.cmake for more info." ON)
option(ENABLE_LTO "Enable link time optimization" ON)
include(LTO)
include(Warnings)
include(functions)
include(sources)
include(CompilerSettings)
# Check for LTO (Link-time optimisation) support.
find_lto(CXX)
include_directories( "src/" "src/headers" )
include(cmake/sources.cmake)
# The only direct cmake argument for now
option(BUILD_SHARED_LIBS "Build shared library and only the shared library if \"ON\", default is static" OFF)
#-----------------------------------------------------------------------------
# Compose CFLAGS
#-----------------------------------------------------------------------------
# Some information ported from makefile_include.mk
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE "Release")
endif()
# We only differentiate between MSVC and GCC-compatible compilers
if(MSVC)
set(LTM_C_FLAGS -W3)
elseif(WATCOM)
set(LTM_C_FLAGS -fo=.obj -oaxt -3r -w3)
else()
set(LTM_C_FLAGS -Wall -Wsign-compare -Wextra -Wshadow
-Wdeclaration-after-statement -Wbad-function-cast -Wcast-align
-Wstrict-prototypes -Wpointer-arith -Wsystem-headers)
set(CMAKE_C_FLAGS_DEBUG "-g3")
set(CMAKE_C_FLAGS_RELEASE "-O3 -funroll-loops -fomit-frame-pointer")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-g3 -O2")
set(CMAKE_C_FLAGS_MINSIZEREL "-Os")
endif()
# What compiler do we have and what are their...uhm... peculiarities
if(CMAKE_C_COMPILER_ID MATCHES "(C|c?)lang")
list(APPEND LTM_C_FLAGS -Wno-typedef-redefinition -Wno-tautological-compare -Wno-builtin-requires-header)
# Clang requires at least '-O1' for dead code elimination
set(CMAKE_C_FLAGS_DEBUG "-O1 ${CMAKE_C_FLAGS_DEBUG}")
endif()
if(CMAKE_C_COMPILER MATCHES "mingw")
list(APPEND LTM_C_FLAGS -Wno-shadow -Wno-expansion-to-defined -Wno-declaration-after-statement -Wno-bad-function-cast)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
list(APPEND LTM_C_FLAGS -Wno-nullability-completeness)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
list(APPEND LTM_C_FLAGS -no-undefined)
endif()
# TODO: coverage (lgcov)
# If the user set the environment variables at generate-time, append them
# in order to allow overriding our defaults.
# ${LTM_CFLAGS} means the user passed it via sth like:
# $ cmake -DLTM_CFLAGS="foo"
list(APPEND LTM_C_FLAGS ${LTM_CFLAGS})
list(APPEND LTM_LD_FLAGS ${LTM_LDFLAGS})
#-----------------------------------------------------------------------------
# library target
#-----------------------------------------------------------------------------
add_library( ${PROJECT_NAME} SHARED
${TFM_SOURCE}
${TFM_HEADERS}
)
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}>
)
target_compile_options(${PROJECT_NAME} BEFORE PRIVATE
${LTM_C_FLAGS}
)
target_link_options(${PROJECT_NAME} BEFORE PRIVATE
${LTM_LD_FLAGS}
)
set(PUBLIC_HEADERS tfm.h)
set_target_properties(${PROJECT_NAME} PROPERTIES
OUTPUT_NAME tomsfastmath
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
PUBLIC_HEADER "${PUBLIC_HEADERS}"
)
option(COMPILE_LTO "Build with LTO enabled")
if(COMPILE_LTO)
check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO)
if(COMPILER_SUPPORTS_LTO)
set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(SEND_ERROR "This compiler does not support LTO. Reconfigure ${PROJECT_NAME} with -DCOMPILE_LTO=OFF.")
endif()
endif()
################################################################################
################################################################################
################################################################################
################################################################################

View File

@ -0,0 +1,54 @@
################################################################################
#
# Compiler Settings
#
################################################################################
# Require and enable C++ 0x/11/14/17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
message(STATUS "tomsfastmath pre-check compiler: C++${CMAKE_CXX_STANDARD} with CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_COMPILER_IS_GNUCXX)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wnarrowing -Werror ")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wnarrowing -Wextra")
set(CMAKE_CXX_FLAGS " -Werror -Wshadow -Wextra -Wall -fexceptions -fno-omit-frame-pointer -fno-rtti -DUNICODE ${CMAKE_CXX_FLAGS} ")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
include(CheckCXXCompilerFlag)
if(NOT TOMSFASTMATH_DISABLE_LIBCXX)
check_cxx_compiler_flag("-stdlib=libc++" CXX_SUPPORTS_STDLIB)
if(CXX_SUPPORTS_STDLIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -stdlib=libc++")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -stdlib=libc++")
endif()
set(TOMSFASTMATH_DISABLE_LIBCXX ${TOMSFASTMATH_DISABLE_LIBCXX} CACHE BOOL "Do not use libc++, if available." FORCE)
endif()
message(STATUS "tomsfastmath build: Disable linking libc++ - ${TOMSFASTMATH_DISABLE_LIBCXX}")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel")
string(REGEX REPLACE "[/-]W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
if (NOT (CMAKE_VERSION VERSION_LESS 3.6.0)) # Compiler features for Intel in CMake 3.6+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qstd=c++17")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /QaxCORE-AVX2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O3")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Qipo")
elseif(MSVC)
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
if(MSVC_VERSION LESS 1900)
message(FATAL_ERROR "tomsfastmath : Build requires C++17-compliant compiler")
endif()
endif()
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "tomsfastmath : Global compiler flags - ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}")
elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
message(STATUS "tomsfastmath : Global compiler flags - ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
elseif(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "tomsfastmath : Global compiler flags - ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE}")
endif()

View File

@ -0,0 +1,22 @@
# https://github.com/bsamseth/cpp-project
# guard against in-source builds
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.")
endif()
# guard against bad build-type strings
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Debug")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower)
string(TOUPPER "${CMAKE_BUILD_TYPE}" cmake_build_type_toupper)
if( NOT cmake_build_type_tolower STREQUAL "debug"
AND NOT cmake_build_type_tolower STREQUAL "release"
AND NOT cmake_build_type_tolower STREQUAL "profile"
AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo"
AND NOT cmake_build_type_tolower STREQUAL "coverage")
message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are Debug, Coverage, Release, Profile, RelWithDebInfo (case-insensitive).")
endif()

255
cmake/LTO.cmake Normal file
View File

@ -0,0 +1,255 @@
################################################################################
#
# LTO - Link-time optimisation
#
################################################################################
#
# Usage :
#
# Variable : ENABLE_LTO | Enable or disable LTO support for this build
#
# find_lto(lang)
# - lang is C or CXX (the language to test LTO for)
# - call it after project() so that the compiler is already detected
#
# This will check for LTO support and create a target_enable_lto(target [debug,optimized,general]) macro.
# The 2nd parameter has the same meaning as in target_link_libraries, and is used to enable LTO only for those build configurations
# 'debug' is by default the Debug configuration, and 'optimized' all the other configurations
#
# if ENABLE_LTO is set to false, an empty macro will be generated
#
# Then to enable LTO for your target use
#
# target_enable_lto(mytarget general)
#
# It is however recommended to use it only for non debug builds the following way :
#
# target_enable_lto(mytarget optimized)
#
# Note : For CMake versions < 3.9, target_link_library is used in it's non plain version.
# You will need to specify PUBLIC/PRIVATE/INTERFACE to all your other target_link_library calls for the target
#
# WARNING for cmake versions older than 3.9 :
# This module will override CMAKE_AR CMAKE_RANLIB and CMAKE_NM by the gcc versions if found when building with gcc
# License:
#
# Copyright (C) 2016 Lectem <lectem@gmail.com>
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the 'Software') deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
macro(find_lto lang)
if(ENABLE_LTO AND NOT LTO_${lang}_CHECKED)
#LTO support was added for clang/gcc in 3.9
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 3.9)
cmake_policy(SET CMP0054 NEW)
message(STATUS "Checking for LTO Compatibility")
# Since GCC 4.9 we need to use gcc-ar / gcc-ranlib / gcc-nm
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_GCC_AR OR NOT CMAKE_GCC_RANLIB OR NOT CMAKE_GCC_NM)
find_program(CMAKE_GCC_AR NAMES
"${_CMAKE_TOOLCHAIN_PREFIX}gcc-ar"
"${_CMAKE_TOOLCHAIN_PREFIX}gcc-ar-${_version}"
DOC "gcc provided wrapper for ar which adds the --plugin option"
)
find_program(CMAKE_GCC_RANLIB NAMES
"${_CMAKE_TOOLCHAIN_PREFIX}gcc-ranlib"
"${_CMAKE_TOOLCHAIN_PREFIX}gcc-ranlib-${_version}"
DOC "gcc provided wrapper for ranlib which adds the --plugin option"
)
# Not needed, but at least stay coherent
find_program(CMAKE_GCC_NM NAMES
"${_CMAKE_TOOLCHAIN_PREFIX}gcc-nm"
"${_CMAKE_TOOLCHAIN_PREFIX}gcc-nm-${_version}"
DOC "gcc provided wrapper for nm which adds the --plugin option"
)
mark_as_advanced(CMAKE_GCC_AR CMAKE_GCC_RANLIB CMAKE_GCC_NM)
set(CMAKE_LTO_AR ${CMAKE_GCC_AR})
set(CMAKE_LTO_RANLIB ${CMAKE_GCC_RANLIB})
set(CMAKE_LTO_NM ${CMAKE_GCC_NM})
endif()
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_LTO_AR ${CMAKE_AR})
set(CMAKE_LTO_RANLIB ${CMAKE_RANLIB})
set(CMAKE_LTO_NM ${CMAKE_NM})
endif()
if(CMAKE_LTO_AR AND CMAKE_LTO_RANLIB)
set(__lto_flags -flto)
if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 4.7)
list(APPEND __lto_flags -fno-fat-lto-objects)
endif()
if(NOT DEFINED CMAKE_${lang}_PASSED_LTO_TEST)
set(__output_dir "${CMAKE_PLATFORM_INFO_DIR}/LtoTest1${lang}")
file(MAKE_DIRECTORY "${__output_dir}")
set(__output_base "${__output_dir}/lto-test-${lang}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E echo "void foo() {}"
COMMAND ${CMAKE_${lang}_COMPILER} ${__lto_flags} -c -xc -
-o "${__output_base}.o"
RESULT_VARIABLE __result
ERROR_QUIET
OUTPUT_QUIET
)
if("${__result}" STREQUAL "0")
execute_process(
COMMAND ${CMAKE_LTO_AR} cr "${__output_base}.a" "${__output_base}.o"
RESULT_VARIABLE __result
ERROR_QUIET
OUTPUT_QUIET
)
endif()
if("${__result}" STREQUAL "0")
execute_process(
COMMAND ${CMAKE_LTO_RANLIB} "${__output_base}.a"
RESULT_VARIABLE __result
ERROR_QUIET
OUTPUT_QUIET
)
endif()
if("${__result}" STREQUAL "0")
execute_process(
COMMAND ${CMAKE_COMMAND} -E echo "void foo(); int main() {foo();}"
COMMAND ${CMAKE_${lang}_COMPILER} ${__lto_flags} -xc -
-x none "${__output_base}.a" -o "${__output_base}"
RESULT_VARIABLE __result
ERROR_QUIET
OUTPUT_QUIET
)
endif()
if("${__result}" STREQUAL "0")
set(__lto_found TRUE)
endif()
set(CMAKE_${lang}_PASSED_LTO_TEST
${__lto_found} CACHE INTERNAL
"If the compiler passed a simple LTO test compile")
endif()
if(CMAKE_${lang}_PASSED_LTO_TEST)
message(STATUS "Checking for LTO Compatibility - works")
set(LTO_${lang}_SUPPORT TRUE CACHE BOOL "Do we have LTO support ?")
set(LTO_COMPILE_FLAGS -flto CACHE STRING "Link Time Optimization compile flags")
set(LTO_LINK_FLAGS -flto CACHE STRING "Link Time Optimization link flags")
else()
message(STATUS "Checking for LTO Compatibility - not working")
endif()
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(STATUS "Checking for LTO Compatibility - works (assumed for clang)")
set(LTO_${lang}_SUPPORT TRUE CACHE BOOL "Do we have LTO support ?")
set(LTO_COMPILE_FLAGS -flto CACHE STRING "Link Time Optimization compile flags")
set(LTO_LINK_FLAGS -flto CACHE STRING "Link Time Optimization link flags")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
message(STATUS "Checking for LTO Compatibility - works")
set(LTO_${lang}_SUPPORT TRUE CACHE BOOL "Do we have LTO support ?")
set(LTO_COMPILE_FLAGS /GL CACHE STRING "Link Time Optimization compile flags")
set(LTO_LINK_FLAGS -LTCG:INCREMENTAL CACHE STRING "Link Time Optimization link flags")
else()
message(STATUS "Checking for LTO Compatibility - compiler not handled by module")
endif()
mark_as_advanced(LTO_${lang}_SUPPORT LTO_COMPILE_FLAGS LTO_LINK_FLAGS)
set(LTO_${lang}_CHECKED TRUE CACHE INTERNAL "" )
if(CMAKE_GCC_AR AND CMAKE_GCC_RANLIB AND CMAKE_GCC_NM)
# THIS IS HACKY BUT THERE IS NO OTHER SOLUTION ATM
set(CMAKE_AR ${CMAKE_GCC_AR} CACHE FILEPATH "Forcing gcc-ar instead of ar" FORCE)
set(CMAKE_NM ${CMAKE_GCC_NM} CACHE FILEPATH "Forcing gcc-nm instead of nm" FORCE)
set(CMAKE_RANLIB ${CMAKE_GCC_RANLIB} CACHE FILEPATH "Forcing gcc-ranlib instead of ranlib" FORCE)
endif()
endif(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 3.9)
endif(ENABLE_LTO AND NOT LTO_${lang}_CHECKED)
if(ENABLE_LTO)
#Special case for cmake older than 3.9, using a library for gcc/clang, but could setup the flags directly.
#Taking advantage of the [debug,optimized] parameter of target_link_libraries
if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 3.9)
if(LTO_${lang}_SUPPORT)
if(NOT TARGET __enable_lto_tgt)
add_library(__enable_lto_tgt INTERFACE)
endif()
target_compile_options(__enable_lto_tgt INTERFACE ${LTO_COMPILE_FLAGS})
#this might not work for all platforms... in which case we'll have to set the link flags on the target directly
target_link_libraries(__enable_lto_tgt INTERFACE ${LTO_LINK_FLAGS} )
macro(target_enable_lto _target _build_configuration)
if(${_build_configuration} STREQUAL "optimized" OR ${_build_configuration} STREQUAL "debug" )
target_link_libraries(${_target} PRIVATE ${_build_configuration} __enable_lto_tgt)
else()
target_link_libraries(${_target} PRIVATE __enable_lto_tgt)
endif()
endmacro()
else()
#In old cmake versions, we can set INTERPROCEDURAL_OPTIMIZATION even if not supported by the compiler
#So if we didn't detect it, let cmake give it a try
set(__IPO_SUPPORTED TRUE)
endif()
else()
cmake_policy(SET CMP0069 NEW)
include(CheckIPOSupported)
# Optional IPO. Do not use IPO if it's not supported by compiler.
check_ipo_supported(RESULT __IPO_SUPPORTED OUTPUT output)
if(NOT __IPO_SUPPORTED)
message(STATUS "IPO (interprocedural optimization) is not supported or broken.")
else()
message(STATUS "IPO (interprocedural optimization) is supported")
endif()
endif()
if(__IPO_SUPPORTED)
macro(target_enable_lto _target _build_configuration)
if(NOT ${_build_configuration} STREQUAL "debug" )
#enable for all configurations
set_target_properties(${_target} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if(${_build_configuration} STREQUAL "optimized" )
#blacklist debug configurations
set(__enable_debug_lto FALSE)
else()
#enable only for debug configurations
set(__enable_debug_lto TRUE)
endif()
get_property(DEBUG_CONFIGURATIONS GLOBAL PROPERTY DEBUG_CONFIGURATIONS)
if(NOT DEBUG_CONFIGURATIONS)
set(DEBUG_CONFIGURATIONS DEBUG) # This is what is done by CMAKE internally... since DEBUG_CONFIGURATIONS is empty by default
endif()
foreach(config IN LISTS DEBUG_CONFIGURATIONS)
set_target_properties(${_target} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_${config} ${__enable_debug_lto})
endforeach()
endmacro()
endif()
endif()
if(NOT COMMAND target_enable_lto)
macro(target_enable_lto _target _build_configuration)
endmacro()
endif()
endmacro()

100
cmake/Warnings.cmake Normal file
View File

@ -0,0 +1,100 @@
# MIT License
#
# Copyright (c) 2017 Lectem
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
function(target_set_warnings)
if(NOT ENABLE_WARNINGS_SETTINGS)
return()
endif()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(WMSVC TRUE)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(WGCC TRUE)
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(WCLANG TRUE)
endif()
set(multiValueArgs ENABLE DISABLE AS_ERROR)
cmake_parse_arguments(this "" "" "${multiValueArgs}" ${ARGN})
list(FIND this_ENABLE "ALL" enable_all)
list(FIND this_DISABLE "ALL" disable_all)
list(FIND this_AS_ERROR "ALL" as_error_all)
if(NOT ${enable_all} EQUAL -1)
if(WMSVC)
# Not all the warnings, but WAll is unusable when using libraries
# Unless you'd like to support MSVC in the code with pragmas, this is probably the best option
list(APPEND WarningFlags "/W4")
elseif(WGCC)
list(APPEND WarningFlags "-Wall" "-Wextra" "-Wpedantic")
elseif(WCLANG)
list(APPEND WarningFlags "-Wall" "-Weverything" "-Wpedantic")
endif()
elseif(NOT ${disable_all} EQUAL -1)
set(SystemIncludes TRUE) # Treat includes as if coming from system
if(WMSVC)
list(APPEND WarningFlags "/w" "/W0")
elseif(WGCC OR WCLANG)
list(APPEND WarningFlags "-w")
endif()
endif()
list(FIND this_DISABLE "Annoying" disable_annoying)
if(NOT ${disable_annoying} EQUAL -1)
if(WMSVC)
# bounds-checked functions require to set __STDC_WANT_LIB_EXT1__ which we usually don't need/want
list(APPEND WarningDefinitions -D_CRT_SECURE_NO_WARNINGS)
# disable C4514 C4710 C4711... Those are useless to add most of the time
#list(APPEND WarningFlags "/wd4514" "/wd4710" "/wd4711")
#list(APPEND WarningFlags "/wd4365") #signed/unsigned mismatch
#list(APPEND WarningFlags "/wd4668") # is not defined as a preprocessor macro, replacing with '0' for
elseif(WGCC OR WCLANG)
list(APPEND WarningFlags -Wno-switch-enum)
if(WCLANG)
list(APPEND WarningFlags -Wno-unknown-warning-option -Wno-padded -Wno-undef -Wno-reserved-id-macro -fcomment-block-commands=test,retval)
if(NOT CMAKE_CXX_STANDARD EQUAL 98)
list(APPEND WarningFlags -Wno-c++98-compat -Wno-c++98-compat-pedantic)
endif()
if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") # clang-cl has some VCC flags by default that it will not recognize...
list(APPEND WarningFlags -Wno-unused-command-line-argument)
endif()
endif(WCLANG)
endif()
endif()
if(NOT ${as_error_all} EQUAL -1)
if(WMSVC)
list(APPEND WarningFlags "/WX")
elseif(WGCC OR WCLANG)
list(APPEND WarningFlags "-Werror")
endif()
endif()
foreach(target IN LISTS this_UNPARSED_ARGUMENTS)
if(WarningFlags)
target_compile_options(${target} PRIVATE ${WarningFlags})
endif()
if(WarningDefinitions)
target_compile_definitions(${target} PRIVATE ${WarningDefinitions})
endif()
if(SystemIncludes)
set_target_properties(${target} PROPERTIES
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:${target},INTERFACE_INCLUDE_DIRECTORIES>)
endif()
endforeach()
endfunction(target_set_warnings)

13
cmake/functions.cmake Normal file
View File

@ -0,0 +1,13 @@
# ##############################################################################
# cmake function library
# ##############################################################################
# Taken from https://jeremimucha.com/2021/01/cmake-fundamentals-part3/
# See also https://jeremimucha.com/2021/02/cmake-functions-and-macros/
function(PrintTargetLibraries target msg)
get_target_property(linkedLibs ${target} LINK_LIBRARIES)
get_target_property(interfaceLibs ${target} INTERFACE_LINK_LIBRARIES)
message(STATUS "${msg}")
message(STATUS "${target} LINK_LIBRARIES: ${linkedLibs}")
message(STATUS "${target} INTERFACE_LINK_LIBRARIES: ${interfaceLibs}")
endfunction()

121
cmake/sources.cmake Normal file
View File

@ -0,0 +1,121 @@
# ### ###########################################################################
# ### Definitions taken from CMakeLists.txt for tomsfastmath in ClamAV
# ### https://github.com/Cisco-Talos/clamav/blob/main/libclamav/CMakeLists.txt
# ### ###########################################################################
# Enable overflow checks in TomsFastMath's fp_exptmod() function.
add_definitions(-DTFM_CHECK)
# Just enable ASM in in TomsFastMath's on x86-64 where we know it works.
# on i686 we run out of registers with -fPIC, and on ia64 we miscompile.
if(NOT CMAKE_COMPILER_IS_GNUCC OR NOT (CMAKE_SIZEOF_VOID_P EQUAL 8))
add_definitions(-DTFM_NO_ASM)
endif()
# ### ###########################################################################
# ### SOURCES and HEADERS
# ### ###########################################################################
# to generate the source list cd to extern/tomsfastmath and execute:
# `find -type f -name *.c | grep -v generators |sort | cut -c 3- | awk '{ print "\"../src/"$0"\""}' > sources.txt`
# then copy/paste here as required.
set ( TFM_SOURCE
"../src/addsub/fp_add.c"
"../src/addsub/fp_add_d.c"
"../src/addsub/fp_addmod.c"
"../src/addsub/fp_cmp.c"
"../src/addsub/fp_cmp_d.c"
"../src/addsub/fp_cmp_mag.c"
"../src/addsub/fp_sub.c"
"../src/addsub/fp_sub_d.c"
"../src/addsub/fp_submod.c"
"../src/addsub/s_fp_add.c"
"../src/addsub/s_fp_sub.c"
"../src/bin/fp_radix_size.c"
"../src/bin/fp_read_radix.c"
"../src/bin/fp_read_signed_bin.c"
"../src/bin/fp_read_unsigned_bin.c"
"../src/bin/fp_reverse.c"
"../src/bin/fp_signed_bin_size.c"
"../src/bin/fp_s_rmap.c"
"../src/bin/fp_toradix.c"
"../src/bin/fp_toradix_n.c"
"../src/bin/fp_to_signed_bin.c"
"../src/bin/fp_to_unsigned_bin.c"
"../src/bin/fp_unsigned_bin_size.c"
"../src/bit/fp_cnt_lsb.c"
"../src/bit/fp_count_bits.c"
"../src/bit/fp_div_2.c"
"../src/bit/fp_div_2d.c"
"../src/bit/fp_lshd.c"
"../src/bit/fp_mod_2d.c"
"../src/bit/fp_rshd.c"
"../src/divide/fp_div.c"
"../src/divide/fp_div_d.c"
"../src/divide/fp_mod.c"
"../src/divide/fp_mod_d.c"
"../src/exptmod/fp_2expt.c"
"../src/exptmod/fp_exptmod.c"
"../src/misc/fp_ident.c"
"../src/misc/fp_rand.c"
"../src/misc/fp_set.c"
"../src/mont/fp_montgomery_calc_normalization.c"
"../src/mont/fp_montgomery_reduce.c"
"../src/mont/fp_montgomery_setup.c"
"../src/mul/fp_mul_2.c"
"../src/mul/fp_mul_2d.c"
"../src/mul/fp_mul.c"
"../src/mul/fp_mul_comba_12.c"
"../src/mul/fp_mul_comba_17.c"
"../src/mul/fp_mul_comba_20.c"
"../src/mul/fp_mul_comba_24.c"
"../src/mul/fp_mul_comba_28.c"
"../src/mul/fp_mul_comba_32.c"
"../src/mul/fp_mul_comba_3.c"
"../src/mul/fp_mul_comba_48.c"
"../src/mul/fp_mul_comba_4.c"
"../src/mul/fp_mul_comba_64.c"
"../src/mul/fp_mul_comba_6.c"
"../src/mul/fp_mul_comba_7.c"
"../src/mul/fp_mul_comba_8.c"
"../src/mul/fp_mul_comba_9.c"
"../src/mul/fp_mul_comba.c"
"../src/mul/fp_mul_comba_small_set.c"
"../src/mul/fp_mul_d.c"
"../src/mul/fp_mulmod.c"
"../src/numtheory/fp_gcd.c"
"../src/numtheory/fp_invmod.c"
"../src/numtheory/fp_isprime.c"
"../src/numtheory/fp_isprime_ex.c"
"../src/numtheory/fp_lcm.c"
"../src/numtheory/fp_prime_miller_rabin.c"
"../src/numtheory/fp_prime_random_ex.c"
"../src/sqr/fp_sqr.c"
"../src/sqr/fp_sqr_comba_12.c"
"../src/sqr/fp_sqr_comba_17.c"
"../src/sqr/fp_sqr_comba_20.c"
"../src/sqr/fp_sqr_comba_24.c"
"../src/sqr/fp_sqr_comba_28.c"
"../src/sqr/fp_sqr_comba_32.c"
"../src/sqr/fp_sqr_comba_3.c"
"../src/sqr/fp_sqr_comba_48.c"
"../src/sqr/fp_sqr_comba_4.c"
"../src/sqr/fp_sqr_comba_64.c"
"../src/sqr/fp_sqr_comba_6.c"
"../src/sqr/fp_sqr_comba_7.c"
"../src/sqr/fp_sqr_comba_8.c"
"../src/sqr/fp_sqr_comba_9.c"
"../src/sqr/fp_sqr_comba.c"
"../src/sqr/fp_sqr_comba_generic.c"
"../src/sqr/fp_sqr_comba_small_set.c"
"../src/sqr/fp_sqrmod.c"
)
set ( TFM_HEADERS
"../src/headers/tfm.h"
# "tfm_private.h"
)