1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-04-29 23:29:41 +02:00
audacity/CMakeLists.txt
Emily Mabrey 5105641a83
Merge pull request from tenacityteam/emabrey/vcpkg-update
Vcpkg update / Python 3 package update

Signed-off-by: Emily Mabrey <emabrey@tenacityaudio.org>
Reference-to: https://github.com/tenacityteam/tenacity/pull/650
2022-01-23 23:35:20 -05:00

968 lines
35 KiB
CMake

# /\_/\
# ________(' - ' )
# _____( )
# / ( ______________ )
# ' | | | |
# | | | | hello
# '"' '"'
# If you want built-in pre-compiled header support then make sure you have cmake 3.16 or higher.
#
# Minimum required is 3.15 due to use of multiple values in generator expressions.
cmake_minimum_required( VERSION 3.15 FATAL_ERROR )
# ~~~~~~~~~~~~~~
# CMake Policies
# ~~~~~~~~~~~~~~
# Ignore compile definitions for all build types (compatibility override for CMake <2.8.10)
cmake_policy( SET CMP0043 NEW )
# Link libraries by full path even in implicit directories (compatibility override for CMake <3.3)
cmake_policy( SET CMP0060 NEW )
# If inter-procedural optimization is manually enabled fail if we cannot optimize
cmake_policy( SET CMP0069 NEW )
# Use libGLVND by default when using openGL (compatibility override for CMake <3.11)
cmake_policy( SET CMP0072 NEW )
# Prefer required libraries in file check macros (compatibility override for CMake <3.12)
cmake_policy( SET CMP0075 NEW )
# ~~~~~~~~~~~~~~~~~
# Build Information
# ~~~~~~~~~~~~~~~~~
# The type of build this is ( 0 => alpha ; 1 => beta ; 2 => release )
# If set to non-release build it changes the welcome screen
# If set to non-alpha build it disables the development only menu
set( AUDACITY_BUILD_LEVEL 0 )
# Define Tenacity's build output name
if( APPLE OR WIN32 )
set( AUDACITY_NAME "Tenacity")
else()
set( AUDACITY_NAME "tenacity")
endif()
if(NOT GIT_FOUND)
find_package( Git )
endif()
# ~~~~~~~~~
# Version
# ~~~~~~~~~
# Audacity version that Tenacity is based on
set( AUDACITY_VERSION 3 ) # Major version
set( AUDACITY_RELEASE 0 ) # Minor version
set( AUDACITY_REVISION 4 ) # Revision version
set( AUDACITY_MODLEVEL 0 ) # Additional version detail
# Tenacity's version
set( TENACITY_VERSION 0 ) # Major version
set( TENACITY_RELEASE 1 ) # Minor version
set( TENACITY_REVISION 0 ) # Revision version
set( TENACITY_MODLEVEL 0 ) # Additional version detail
set( GIT_DESCRIBE "unknown" )
if( GIT_FOUND )
# Attempt to first get "Tenacity-" tags
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=7 --exclude="Audacity-*" --exclude="DarkAudacity-*"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
)
if( DEFINED GIT_DESCRIBE AND GIT_DESCRIBE STREQUAL "" )
# Retry, this time accepting "Audacity-" tags
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=7 --exclude="DarkAudacity-*"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
)
endif()
if( DEFINED GIT_DESCRIBE AND NOT GIT_DESCRIBE STREQUAL "" )
# Copy to new variable for string manipulation
set( git_output ${GIT_DESCRIBE} )
string( REPLACE "Audacity-" "" git_output "${git_output}" )
string( REPLACE "DarkAudacity-" "" git_output "${git_output}" )
string( REGEX REPLACE "-.*" "" git_output "${git_output}" )
string( REPLACE "." ";" git_output "${git_output}" )
list( LENGTH git_output GIT_OUTPUT_LIST_LENGTH )
if( GIT_OUTPUT_LIST_LENGTH GREATER_EQUAL 3 )
list( GET git_output 0 AUDACITY_VERSION )
list( GET git_output 1 AUDACITY_RELEASE )
list( GET git_output 2 AUDACITY_REVISION )
endif()
endif()
endif()
# ~~~~~~~
# Vcpkg
# ~~~~~~~
if( WIN32 OR APPLE )
option( VCPKG "Use vcpkg for dependencies" ON )
else()
option( VCPKG "Use vcpkg for dependencies" OFF )
endif()
if( VCPKG )
set( ENV{VCPKG_DISABLE_METRICS} true )
if( NOT DEFINED ENV{VCPKG_BINARY_SOURCES} )
set( ENV{VCPKG_BINARY_SOURCES} "clear;default;nuget,tenacityteam_github_auto,read;" )
endif()
set( ENV{VCPKG_FEATURE_FLAGS} "-compilertracking,manifests,registries,versions" )
if( VCPKG_ROOT )
message( STATUS "Using dependencies from vcpkg repository at ${VCPKG_ROOT}" )
if( NOT EXISTS "${VCPKG_ROOT}/bootstrap-vcpkg.sh" )
message( FATAL_ERROR "${VCPKG_ROOT} is not a vcpkg Git repository." )
endif()
else()
message( STATUS "Using dependencies from vcpkg Git submodule" )
set( VCPKG_ROOT "${CMAKE_SOURCE_DIR}/vcpkg" )
if( NOT EXISTS "${VCPKG_ROOT}/bootstrap-vcpkg.sh" )
# Make sure we have actually attempted to find Git
if( NOT GIT_FOUND )
find_package( Git )
endif()
if( GIT_FOUND )
message( STATUS "Initializing vcpkg Git submodule" )
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule init
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
else()
message( FATAL_ERROR "Unable to initialize vcpkg Git submodule because CMake was unable to find a git installation" )
endif()
endif()
endif()
if( NOT DEFINED ENV{CI} AND NOT EXISTS ${CMAKE_SOURCE_DIR}/nuget.config AND (EXISTS ${VCPKG_ROOT}/vcpkg OR EXISTS ${VCPKG_ROOT}/vcpkg.exe) )
execute_process(
COMMAND vcpkg fetch nuget
WORKING_DIRECTORY ${VCPKG_ROOT}
OUTPUT_VARIABLE NUGET_EXECUTABLE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
message( STATUS "Automatically setting Nuget api key to allow nuget cache usage locally" )
file( READ ${CMAKE_SOURCE_DIR}/nuget.config.in NUGET_CONFIG_CONTENT )
file( WRITE ${CMAKE_SOURCE_DIR}/nuget.config ${NUGET_CONFIG_CONTENT} )
set( GITHUB_PACKAGES_TOKEN_SUFFIX "ZdXoXftxDTV20UjAmIL2Mw95kckhbo0hmiYz" )
execute_process(
COMMAND "${NUGET_EXECUTABLE}" sources add -Name tenacityteam_github_auto -Source https://nuget.pkg.github.com/tenacityteam/index.json -Config nuget.config -Username tenacityteamci -Password ghp_${GITHUB_PACKAGES_TOKEN_SUFFIX} -StorePasswordInClearText -ForceEnglishOutput -NonInteractive
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
execute_process(
COMMAND "${NUGET_EXECUTABLE}" setapikey -Source tenacityteam_github_auto -Config nuget.config ghp_${GITHUB_PACKAGES_TOKEN_SUFFIX}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE SETAPI_KEY_RESULT
ERROR_VARIABLE SETAPI_KEY_RESULT
)
endif()
if( NOT DEFINED VCPKG_OVERLAY_PORTS )
set( VCPKG_OVERLAY_PORTS "${VCPKG_ROOT}/overlay/ports" )
endif()
if( NOT DEFINED VCPKG_OVERLAY_TRIPLETS )
set( VCPKG_OVERLAY_TRIPLETS "${VCPKG_ROOT}/overlay/triplets" )
endif()
if( NOT DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET )
if( APPLE )
set( VCPKG_TARGET_TRIPLET "x64-osx-10.12min" )
endif()
elseif( DEFINED ENV{VCPKG_DEFAULT_TRIPLET} )
set( VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" )
endif()
set( CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" )
else()
message( STATUS "Searching for dependencies from system, not using vcpkg." )
endif()
# ~~~~~~~~~~~~~~~~~~~~~~
# CMake input validation
# ~~~~~~~~~~~~~~~~~~~~~~
# Don't allow in-source builds
if( "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}" )
message( SEND_ERROR "In-source builds not allowed" )
message( SEND_ERROR "Create a new directory and run cmake from there, i.e.:" )
message( SEND_ERROR " mkdir build" )
message( SEND_ERROR " cmake -B build" )
message( SEND_ERROR "You will need to delete CMakeCache.txt and CMakeFiles from this directory to clean up." )
message( FATAL_ERROR "Failed because you attempted to build in the source tree" )
endif()
# Determine if this is being generated by a multi-config CMake generator
get_property( IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG )
# If the user has not provided us with the build target then we generate sensible defaults
if( NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES )
if( IS_MULTI_CONFIG )
message( STATUS "Detected that we are using a multi-config generator without build types defined..." )
message( STATUS "To fix this we are using default values for CMAKE_CONFIGURATION_TYPES" )
set( CMAKE_CONFIGURATION_TYPES "Debug;MinSizeRel;Release;RelWithDebInfo" )
else()
message( STATUS "Detected that we are using a single config generator without a build type defined..." )
message( STATUS "To fix this we are using default value for CMAKE_BUILD_TYPE" )
set( CMAKE_BUILD_TYPE "Debug" )
endif()
endif()
# If the user has provided us with duplicate config definitions use the singular build type
if( CMAKE_BUILD_TYPE AND CMAKE_CONFIGURATION_TYPES )
message( STATUS "Using CMAKE_BUILD_TYPE and ignoring CMAKE_CONFIGURATION_TYPES" )
set ( CMAKE_CONFIGURATION_TYPES )
endif()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Definitions that must happen before the project() command
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if( APPLE )
# These values are used within builds on MacOS to link the target
# version of the SDK if the linker supports platform versioning
set( MIN_MACOS_VERSION 10.12 )
# Target 10.13 to prevent high CPU usage and slow drawing on Mojave or newer
set( TARGET_MACOS_VERSION 10.13 )
# Define the OSX compatibility parameters
set( CMAKE_OSX_ARCHITECTURES x86_64 CACHE INTERNAL "" )
set( CMAKE_OSX_DEPLOYMENT_TARGET ${MIN_MACOS_VERSION} CACHE INTERNAL "" )
set( CMAKE_OSX_SYSROOT macosx CACHE INTERNAL "" )
endif()
# Add our module path
set( AUDACITY_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-proxies/cmake-modules" )
set( CMAKE_MODULE_PATH ${AUDACITY_MODULE_PATH} ${CMAKE_BINARY_DIR} ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake-modules" )
set( CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR} ${CMAKE_PREFIX_PATH} )
# ~~~~~~~~~~~~~~
# C++ standard
# ~~~~~~~~~~~~~~
# Set the required C++ standard
set( CMAKE_CXX_STANDARD 17 )
set( CMAKE_CXX_STANDARD_REQUIRED ON )
# List of defines which are intended to silence C++17 warnings
# These will be added to each CMAKE target as PRIVATE compilation definitions
list( APPEND CXX_WARNINGS_SILENCE_DEFINES _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING=1 )
list( APPEND CXX_WARNINGS_SILENCE_DEFINES _SILENCE_CXX17_NEGATORS_DEPRECATION_WARNING=1 )
# ~~~~~~~~~~~~~~~~~~
# Tenacity project
# ~~~~~~~~~~~~~~~~~~
project( Tenacity )
# Load our functions/macros
include( AudacityFunctions )
set_from_env( AUDACITY_ARCH_LABEL ) # e.g. x86_64
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Configure optional settings
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Pull all the modules we'll need
include( CheckCXXCompilerFlag )
include( CheckIncludeFile )
include( CheckIncludeFiles )
include( CheckLibraryExists )
include( CheckSymbolExists )
include( CheckTypeSize )
include( CMakeDetermineASM_NASMCompiler )
include( CMakePushCheckState )
include( GNUInstallDirs )
include( TestBigEndian )
# Generator specific configurations
if( CMAKE_GENERATOR MATCHES "Visual Studio*" )
# Make sure Tenacity is the startup project
set_directory_properties( PROPERTIES VS_STARTUP_PROJECT "${CMAKE_PROJECT_NAME}" )
# Define system library information, but we'll do the install
set( CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP YES )
set( CMAKE_INSTALL_UCRT_LIBRARIES NO )
set( CMAKE_INSTALL_MFC_LIBRARIES NO )
set( CMAKE_INSTALL_OPENMP_LIBRARIES NO )
include( InstallRequiredSystemLibraries )
elseif( CMAKE_GENERATOR MATCHES "Xcode" )
# Generate schema files
set( CMAKE_XCODE_GENERATE_SCHEME ON )
# Tell XCode to use a blank code signing identity
set( CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "" CACHE INTERNAL "" )
# This prevents a link error when building with the 10.9 or older SDKs
set( CMAKE_XCODE_ATTRIBUTE_CLANG_LINK_OBJC_RUNTIME OFF )
endif()
# Organize subdirectories/targets into folders for the IDE generators
set_property( GLOBAL PROPERTY USE_FOLDERS ON )
# Enable inter-procedural optimization if this compiler supports it
# This must appear after the project declaration so it can detect ENABLED_LANGUAGES
include( CheckIPOSupported )
check_ipo_supported( RESULT IPO_SUPPORTED OUTPUT IPO_OUTPUT )
mark_as_advanced( FORCE IPO_SUPPORTED )
if( IPO_SUPPORTED )
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION ON )
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON )
set( CMAKE_INTERPROCEDURAL_OPTIMIZATION_DEBUG OFF )
add_definitions( -DHAVE_IPO )
message( STATUS "Inter-procedural optimization is supported" )
else()
message( STATUS "Inter-procedural optimization is not supported: ${IPO_OUTPUT}" )
endif()
# Attempt to find optional ccache program
find_program( CCACHE_PROGRAM ccache )
mark_as_advanced( FORCE CCACHE_PROGRAM )
if( NOT "${CCACHE_PROGRAM}" STREQUAL "CCACHE_PROGRAM-NOTFOUND" )
option( CCACHE "Use ccache for compiler caching to speed up rebuilds." ON )
endif()
# Attempt to find optional sccache program
find_program( SCCACHE_PROGRAM sccache )
mark_as_advanced( FORCE SCCACHE_PROGRAM )
if( NOT "${SCCACHE_PROGRAM}" STREQUAL "SCCACHE_PROGRAM-NOTFOUND" )
option( SCCACHE "Use sccache for compiler caching to speed up rebuilds." ON )
endif()
# Prefer sccache if both ccache and sccache are found
if( SCCACHE )
message( STATUS "Using sccache for compiler caching to speed up rebuilds" )
set( CMAKE_C_COMPILER_LAUNCHER "${SCCACHE_PROGRAM}" )
set( CMAKE_CXX_COMPILER_LAUNCHER "${SCCACHE_PROGRAM}" )
# Instruct MSVC to generate symbolic debug information within object files for sccache
if( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
if( IS_MULTI_CONFIG )
foreach( config ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER "${config}" config )
string( REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_${config} "${CMAKE_CXX_FLAGS_${config}}" )
string( REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_${config} "${CMAKE_C_FLAGS_${config}}" )
endforeach()
else()
string( REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}" )
string( REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE} "${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE}}" )
endif()
endif()
elseif( CCACHE AND NOT WIN32 )
# Don't use ccache on Windows because it is probably mingw and it will muck things up
message( STATUS "Using ccache for compiler caching to speed up rebuilds" )
set( CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" )
set( CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" )
else()
if( WIN32 )
message( STATUS "No compiler caching enabled. Install sccache to enable compiler caching." )
else()
message( STATUS "No compiler caching enabled. Install sccache or ccache to enable compiler caching." )
endif()
endif()
# Determine total number of processors to enable us to only use total_available - 2 processors
# This helps prevent slow down of the other applications during the build process
if( NOT DISABLE_AUTO_CPU_COUNT_OPT )
include( ProcessorCount )
ProcessorCount( CMAKE_BUILD_CPU_COUNT )
if( CMAKE_BUILD_CPU_COUNT GREATER 0 )
math( EXPR CMAKE_BUILD_CPU_COUNT "${CMAKE_BUILD_CPU_COUNT} - 2" OUTPUT_FORMAT DECIMAL )
endif()
if( CMAKE_BUILD_CPU_COUNT LESS_EQUAL 0 )
message( WARNING "Unable to optimize build CPU usage, defaulting to use all processors" )
set( CMAKE_BUILD_CPU_COUNT 0 )
elseif( NOT DEFINED CMAKE_BUILD_PARALLEL_LEVEL )
message( STATUS "Build automatically optimized to use processor count: ${CMAKE_BUILD_CPU_COUNT}" )
set( CMAKE_BUILD_PARALLEL_LEVEL ${CMAKE_BUILD_CPU_COUNT} )
endif()
if( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
set( MULTI_PROC_COMPILER_FLAG "/MP" )
elseif( CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang|GNU" )
set( MULTI_PROC_COMPILER_FLAG "-j" )
endif()
if( IS_MULTI_CONFIG AND CMAKE_CONFIGURATION_TYPES )
foreach( config ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER "${config}" config )
if( NOT CMAKE_BUILD_CPU_COUNT EQUAL 0 )
string( APPEND CMAKE_C_FLAGS_${config} " ${MULTI_PROC_COMPILER_FLAG}${CMAKE_BUILD_CPU_COUNT}" )
string( APPEND CMAKE_CXX_FLAGS_${config} " ${MULTI_PROC_COMPILER_FLAG}${CMAKE_BUILD_CPU_COUNT}" )
else()
string( APPEND CMAKE_C_FLAGS_${config} " ${MULTI_PROC_COMPILER_FLAG}" )
string( APPEND CMAKE_CXX_FLAGS_${config} " ${MULTI_PROC_COMPILER_FLAG}" )
endif()
endforeach()
elseif( CMAKE_BUILD_TYPE )
if( NOT CMAKE_BUILD_CPU_COUNT EQUAL 0 )
string( APPEND CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE} " ${MULTI_PROC_COMPILER_FLAG}${CMAKE_BUILD_CPU_COUNT}" )
string( APPEND CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE} " ${MULTI_PROC_COMPILER_FLAG}${CMAKE_BUILD_CPU_COUNT}" )
else()
string( APPEND CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE} " ${MULTI_PROC_COMPILER_FLAG}" )
string( APPEND CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE} " ${MULTI_PROC_COMPILER_FLAG}" )
endif()
endif()
endif()
# Determine 32-bit or 64-bit target
if( CMAKE_C_COMPILER_ID MATCHES "MSVC" AND CMAKE_VS_PLATFORM_NAME MATCHES "Win64|x64" )
set( IS_64BIT ON )
elseif( CMAKE_SIZEOF_VOID_P STREQUAL "8" )
set( IS_64BIT ON )
endif()
# Determine 32-bit or 64-bit host
cmake_host_system_information( RESULT IS_64BIT_HOST QUERY "IS_64BIT" )
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Output debugging information
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
message( STATUS "Build Info:" )
message( STATUS "\tHost System Name: ${CMAKE_HOST_SYSTEM_NAME}" )
message( STATUS "\tHost System Version: ${CMAKE_HOST_SYSTEM_VERSION}" )
message( STATUS "\tHost System Processor: ${CMAKE_HOST_SYSTEM_PROCESSOR}" )
if( IS_64BIT_HOST )
message( STATUS "\tHost System Arch: 64-bit" )
else()
message( STATUS "\tHost System Arch: 32-bit" )
endif()
message( STATUS )
message( STATUS "\tTarget System Name: ${CMAKE_SYSTEM_NAME}" )
message( STATUS "\tTarget System Version: ${CMAKE_SYSTEM_VERSION}" )
message( STATUS "\tTarget System Processor: ${CMAKE_SYSTEM_PROCESSOR}" )
if( IS_64BIT )
message( STATUS "\tTarget System Arch: 64-bit" )
else()
message( STATUS "\tTarget System Arch: 32-bit" )
endif()
message( STATUS )
message( STATUS "\tCompiler: ${CMAKE_CXX_COMPILER}" )
message( STATUS "\tCompiler Version: ${CMAKE_CXX_COMPILER_VERSION}" )
message( STATUS "\tCompiler Standard: ${CMAKE_CXX_STANDARD}" )
message( STATUS "\tCompiler Standard Required: ${CMAKE_CXX_STANDARD_REQUIRED}" )
message( STATUS "\tCompiler Extensions: ${CMAKE_CXX_EXTENSIONS}" )
message( STATUS )
if( MSVC )
message( STATUS "\tMSVC Version: ${MSVC_VERSION}" )
message( STATUS "\tMSVC Toolset: ${MSVC_TOOLSET_VERSION}" )
endif()
if( CMAKE_GENERATOR MATCHES "Xcode" )
message( STATUS "\tXcode Version: ${XCODE_VERSION}" )
endif()
if( CMAKE_SYSTEM_NAME MATCHES "Darwin" )
message( STATUS "\tMacOS SDK: ${CMAKE_OSX_SYSROOT}" )
endif()
message( STATUS )
message( STATUS "\tCurrent Commit: ${GIT_DESCRIBE}" )
message( STATUS )
# ~~~~~~~~~~~~~~
# Output paths
# ~~~~~~~~~~~~~~
set( _SHARED_PROXY_BASE "shared" )
set( _SHARED_PROXY_BASE_PATH "${CMAKE_BINARY_DIR}/${_SHARED_PROXY_BASE}" )
# Define the non-install and executable paths and where the final product is stored
if( IS_MULTI_CONFIG AND CMAKE_CONFIGURATION_TYPES )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
set( _DESTDIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}" )
set( _SHARED_PROXY_PATH "${_SHARED_PROXY_BASE_PATH}/${CMAKE_CFG_INTDIR}" )
else()
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/${CMAKE_BUILD_TYPE} )
set( _DESTDIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/" )
set( _SHARED_PROXY_PATH "${_SHARED_PROXY_BASE_PATH}/${CMAKE_BUILD_TYPE}" )
endif()
set( _DEST "${_DESTDIR}" )
set( _PREFIX "${CMAKE_INSTALL_PREFIX}" )
set( _LIBDIR "${CMAKE_INSTALL_LIBDIR}" )
set( _DATADIR "${CMAKE_INSTALL_DATADIR}" )
set( _PKGLIB "${_LIBDIR}/tenacity" )
set( _PKGDATA "${_DATADIR}/tenacity/" )
set( _MANDIR "${CMAKE_INSTALL_MANDIR}" )
set( _MODDIR "${_DEST}/modules" )
set( _EXEDIR "${_DEST}" )
# Setup RPATH handling
set( CMAKE_BUILD_RPATH "${_DEST}/${_PKGLIB}" )
set( CMAKE_BUILD_WITH_INSTALL_RPATH FALSE )
set( CMAKE_INSTALL_RPATH "${_PREFIX}/${_PKGLIB}" )
set( CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE )
# Adjust them for the Mac
if( CMAKE_SYSTEM_NAME MATCHES "Darwin" )
set( _APPDIR "Tenacity.app/Contents" )
set( _DEST "${_DESTDIR}/${_APPDIR}" )
set( _EXEDIR "${_DEST}/MacOS" )
set( _MODDIR "${_DEST}/modules" )
set( _PKGLIB "${_DEST}/Frameworks" )
set( CMAKE_MACOSX_RPATH OFF )
endif()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Add optional capability expanding libraries if we can find them
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check_library_exists( m pow "" HAVE_LIBM )
check_library_exists( atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC )
# Add the math library( if found ) to the list of required libraries so that later checks will be able to see it
if( HAVE_LIBM )
list( APPEND CMAKE_REQUIRED_LIBRARIES -lm )
endif()
# Add the atomic library( if found ) to the list of required libraries so that later checks will be able to see it
if( HAVE_LIBATOMIC )
list( APPEND CMAKE_REQUIRED_LIBRARIES -latomic )
endif()
# Add the dynamic linker library( if needed ) to the list of required libraries
list( APPEND CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS} )
# Make sure we link required libraries
set( CMAKE_LINK_INTERFACE_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} )
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Check supported compile-time features
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Various common checks whose results are used by the different targets
test_big_endian( WORDS_BIGENDIAN )
# Check for MMX and SSE support
set( MMX_FLAG "" CACHE INTERNAL "" )
set( SSE_FLAG "" CACHE INTERNAL "" )
if( CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang|GNU" )
check_cxx_compiler_flag( "-mmmx" HAVE_MMX )
if( HAVE_MMX AND NOT IS_64BIT )
set( MMX_FLAG "-mmmx" CACHE INTERNAL "" )
endif()
check_cxx_compiler_flag( "-msse" HAVE_SSE )
if( HAVE_SSE AND NOT IS_64BIT )
set( SSE_FLAG "-msse" CACHE INTERNAL "" )
endif()
check_cxx_compiler_flag( "-msse2" HAVE_SSE2 )
if( HAVE_SSE2 AND NOT IS_64BIT )
set( SSE_FLAG "-msse2" CACHE INTERNAL "" )
endif()
elseif( CMAKE_CXX_COMPILER_ID MATCHES "MSVC" )
set( HAVE_MMX ON )
set( HAVE_SSE ON )
set( HAVE_SSE2 ON )
if( NOT IS_64BIT )
set( SSE_FLAG "/arch:SSE2" )
endif()
endif()
check_include_files( "float.h;stdarg.h;stdlib.h;string.h" STDC_HEADERS )
check_include_file( "assert.h" HAVE_ASSERT_H )
check_include_file( "errno.h" HAVE_ERRNO_H )
check_include_file( "fcntl.h" HAVE_FCNTL_H )
check_include_file( "fenv.h" HAVE_FENV_H )
check_include_file( "inttypes.h" HAVE_INTTYPES_H )
check_include_file( "limits.h" HAVE_LIMITS_H )
if( CMAKE_SYSTEM_NAME MATCHES "FreeBSD" )
check_include_file( "stdlib.h" HAVE_MALLOC_H )
check_include_file( "sys/endian.h" HAVE_ENDIAN_H )
else()
check_include_file( "malloc.h" HAVE_MALLOC_H )
check_include_file( "byteswap.h" HAVE_BYTESWAP_H )
endif()
check_include_file( "memory.h" HAVE_MEMORY_H )
check_include_file( "stdbool.h" HAVE_STDBOOL_H )
check_include_file( "stdint.h" HAVE_STDINT_H )
check_include_file( "stdlib.h" HAVE_STDLIB_H )
check_include_file( "string.h" HAVE_STRING_H )
check_include_file( "strings.h" HAVE_STRINGS_H )
check_include_file( "unistd.h" HAVE_UNISTD_H )
check_include_file( "xmmintrin.h" HAVE_XMMINTRIN_H )
check_include_file( "sys/param.h" HAVE_SYS_PARAM_H )
check_include_file( "sys/stat.h" HAVE_SYS_STAT_H )
check_include_file( "sys/types.h" HAVE_SYS_TYPES_H )
check_include_file( "sys/wait.h" HAVE_SYS_WAIT_H )
check_symbol_exists( bcopy "strings.h" HAVE_BCOPY )
check_symbol_exists( fileno "stdio.h" HAVE_FILENO )
check_symbol_exists( flock "sys/file.h" HAVE_FLOCK )
check_symbol_exists( fork "unistd.h" HAVE_FORK )
check_symbol_exists( fsync "unistd.h" HAVE_FSYNC )
check_symbol_exists( ftruncate "unistd.h" HAVE_FTRUNCATE )
check_symbol_exists( getpagesize "unistd.h" HAVE_GETPAGESIZE )
check_symbol_exists( gettimeofday "sys/time.h" HAVE_GETTIMEOFDAY )
check_symbol_exists( gmtime "time.h" HAVE_GMTIME )
check_symbol_exists( gmtime_r "time.h" HAVE_GMTIME_R )
check_symbol_exists( lrint "math.h" HAVE_LRINT )
check_symbol_exists( lrintf "math.h" HAVE_LRINTF )
check_symbol_exists( lround "math.h" HAVE_LROUND )
check_symbol_exists( lstat "sys/stat.h" HAVE_LSTAT )
check_symbol_exists( memcpy "string.h" HAVE_MEMCPY )
check_symbol_exists( memmove "string.h" HAVE_MEMMOVE )
check_symbol_exists( mlock "sys/mman.h" HAVE_MLOCK )
check_symbol_exists( pipe "unistd.h" HAVE_PIPE )
check_symbol_exists( posix_fadvise "fcntl.h" HAVE_POSIX_FADVISE )
check_symbol_exists( posix_memalign "stdlib.h" HAVE_POSIX_MEMALIGN )
check_symbol_exists( strchr "string.h" HAVE_STRCHR )
check_symbol_exists( waitpid "sys/wait.h" HAVE_WAITPID )
check_type_size( "int8_t" SIZEOF_INT8 LANGUAGE C )
check_type_size( "int16_t" SIZEOF_INT16 LANGUAGE C )
check_type_size( "uint16_t" SIZEOF_UINT16 LANGUAGE C )
check_type_size( "u_int16_t" SIZEOF_U_INT16 LANGUAGE C )
check_type_size( "int32_t" SIZEOF_INT32 LANGUAGE C )
check_type_size( "uint32_t" SIZEOF_UINT32 LANGUAGE C )
check_type_size( "u_int32_t" SIZEOF_U_INT32 LANGUAGE C )
check_type_size( "int64_t" SIZEOF_INT64 LANGUAGE C )
check_type_size( "short" SIZEOF_SHORT LANGUAGE C )
check_type_size( "unsigned short" SIZEOF_UNSIGNED_SHORT LANGUAGE C )
check_type_size( "int" SIZEOF_INT LANGUAGE C )
check_type_size( "unsigned int" SIZEOF_UNSIGNED_INT LANGUAGE C )
check_type_size( "long" SIZEOF_LONG LANGUAGE C )
check_type_size( "unsigned long" SIZEOF_UNSIGNED_LONG LANGUAGE C )
check_type_size( "long long" SIZEOF_LONG_LONG LANGUAGE C )
check_type_size( "unsigned long long" SIZEOF_UNSIGNED_LONG_LONG LANGUAGE C )
check_type_size( "float" SIZEOF_FLOAT LANGUAGE C )
check_type_size( "double" SIZEOF_DOUBLE LANGUAGE C )
check_type_size( "long double" SIZEOF_LONG_DOUBLE LANGUAGE C )
check_type_size( "loff_t" SIZEOF_LOFF LANGUAGE C )
check_type_size( "off_t" SIZEOF_OFF LANGUAGE C )
check_type_size( "off64_t" SIZEOF_OFF64 LANGUAGE C )
check_type_size( "size_t" SIZEOF_SIZE LANGUAGE C )
check_type_size( "wchar_t" SIZEOF_WCHAR LANGUAGE C )
check_type_size( "void*" SIZEOF_POINTER LANGUAGE C )
# ~~~~~~~~~~~~~~~~~~~~
# 3rd party Libraries
# ~~~~~~~~~~~~~~~~~~~~
# We'll be using it if it's available
find_package( PkgConfig QUIET )
# Mostly just to make the CMP0072 policy happy
find_package( OpenGL QUIET )
# Initialize the lib and lib64 directories
if( NOT EXISTS "${CMAKE_BINARY_DIR}/lib" )
file( MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/lib" )
endif()
# Create symbolic link to use the lib directory contents on 64-bit targets
if( NOT CMAKE_INSTALL_LIBDIR STREQUAL "lib" AND NOT EXISTS "${CMAKE_BINARY_DIR}/lib64" )
file( CREATE_LINK "${CMAKE_BINARY_DIR}/lib" "${CMAKE_BINARY_DIR}/lib64" SYMBOLIC )
endif()
# Python is used for the manual and( possibly ) message catalogs
find_package( Python3 )
if( Python3_FOUND )
set( PYTHON "${Python3_EXECUTABLE}" )
elseif( DEFINED NUGET_EXECUTABLE AND EXISTS "${NUGET_EXECUTABLE}" )
message( STATUS "Finding vcpkg nuget python" )
execute_process( COMMAND "${NUGET_EXECUTABLE}" install python -Version 3.9.7 -OutputDirectory "${CMAKE_BINARY_DIR}/packages/" )
file( TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/packages/python.3.9.7/tools/python.exe" PYTHON )
elseif( CMAKE_SYSTEM_NAME MATCHES "Windows" )
# This is defined in AudacityFunctions; maybe we can remove it by simply relying on vcpkg nuget?
nuget_package( pkgdir "python3" "3.9.7" )
file( TO_NATIVE_PATH "${pkgdir}/tools/python.exe" PYTHON )
endif()
# Define the EXPERIMENTAL flags Do this before consistency checks for added third-party libraries
include( "src/Experimental.cmake" )
include( CMakeDependentOption )
find_package( Threads REQUIRED )
find_package( ZLIB REQUIRED )
find_package( EXPAT REQUIRED )
find_package( mp3lame REQUIRED )
find_package( SndFile REQUIRED )
find_package( Soxr REQUIRED )
find_package( SQLite3 REQUIRED )
find_package( PortAudio REQUIRED )
find_package( PortMidi )
find_package( PortSMF )
cmake_dependent_option( MIDI "MIDI support requires PortMidi and PortSMF." ON "PortMidi_FOUND;PortSMF_FOUND" OFF )
if( MIDI )
set( USE_MIDI ON )
message( STATUS "MIDI support enabled." )
else()
message( STATUS "MIDI support disabled. Requires both PortMidi and PortSMF." )
endif()
find_package( id3tag )
cmake_dependent_option( ID3TAG "ID3 Tag support for MP3s." ON "id3tag_FOUND" OFF )
if( ID3TAG )
set( USE_LIBID3TAG ON )
message( STATUS "ID3 tag support for MP3s enabled." )
else()
message( STATUS "ID3 tag support for MP3s disabled. Requires libid3tag." )
endif()
find_package( MAD )
cmake_dependent_option( MP3_DECODING "MP3 decoding support with libmad" ON "MAD_FOUND" OFF )
if( MP3_DECODING )
set( USE_LIBMAD ON )
message( STATUS "MP3 decoding support enabled." )
else()
message( STATUS "MP3 decoding support disabled. Requires libmad." )
endif()
find_package( libtwolame )
cmake_dependent_option( MP2_ENCODING "MP2 support with Twolame" ON "libtwolame_FOUND" OFF )
if( MP2_ENCODING )
set( USE_LIBTWOLAME ON )
message( STATUS "MP2 encoding support enabled." )
else()
message( STATUS "MP2 encoding support disabled. Requires Twolame library." )
endif()
find_package( Ogg )
cmake_dependent_option( OGG "OGG container format support" ON "Ogg_FOUND" OFF )
if( OGG )
set( USE_LIBOGG ON )
message( STATUS "OGG container format support enabled." )
else()
message( STATUS "OGG container format support disabled. Requires libogg." )
endif()
find_package( Vorbis )
cmake_dependent_option( VORBIS "Vorbis codec support" ON "Vorbis_FOUND" OFF )
if( VORBIS )
set( USE_LIBVORBIS ON )
message( STATUS "Vorbis codec support enabled." )
else()
message( STATUS "Voribs codec support disabled. Requires libvorbis." )
endif()
find_package( FLAC++ )
cmake_dependent_option( FLAC "FLAC codec support" ON "FLAC++_FOUND" OFF )
if( FLAC )
set( USE_LIBFLAC ON )
message( STATUS "FLAC codec support enabled." )
else()
message( STATUS "FLAC codec support disabled. Requires libflac and libflac++ C++ bindings." )
endif()
find_package(sbsms)
cmake_dependent_option(SBSMS "SBSMS timestretching" ON "sbsms_FOUND" OFF)
if(SBSMS)
set(USE_SBSMS ON)
message(STATUS "SBSMS timestretching support enabled.")
else()
message( STATUS "SBSMS timestretching support disabled. Requires libsbsms." )
endif()
find_package( SoundTouch )
cmake_dependent_option( SOUNDTOUCH "SoundTouch timestretching" ON "SoundTouch_FOUND" OFF )
if( SOUNDTOUCH )
set( USE_SOUNDTOUCH ON )
message( STATUS "SoundTouch timestretching support enabled." )
else()
message( STATUS "SoundTouch timestretching support disabled. Requires SoundTouch library." )
endif()
find_package( FFMPEG )
cmake_dependent_option( FFMPEG "FFMPEG codecs support." ON "FFMPEG_FOUND" OFF )
if( FFMPEG )
set( USE_FFMPEG ON )
message( STATUS "FFMPEG codecs support enabled." )
else()
message( STATUS "FFMPEG codecs support disabled. Requires FFMPEG libraries." )
endif()
find_package( VampHostSDK )
cmake_dependent_option( VAMP "VAMP plugin hosting." ON "VampHostSDK_FOUND" OFF )
if( VAMP )
set( USE_VAMP ON )
message( STATUS "VAMP plugin hosting enabled. Requires VAMP host SDK." )
else()
message( STATUS "VAMP plugin hosting disabled." )
endif()
find_package( LV2 )
find_package( lilv )
find_package( suil )
cmake_dependent_option( LV2 "LV2 plugin host support" ON "LV2_FOUND;lilv_FOUND;suil_FOUND" OFF )
if( LV2 )
message( STATUS "LV2 plugin hosting enabled." )
set( USE_LV2 ON )
else()
message( STATUS "LV2 plugin hosting disabled. Requires LV2, lilv, and suil libraries." )
endif()
if( NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|Windows" )
find_package( GLIB REQUIRED )
find_package( GTK 3.0 REQUIRED )
pkg_check_modules(GDK3_X11 gdk-x11-3.0)
endif()
if( NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|Windows" )
cmake_dependent_option( VST2 "Use VST2 plug-in support [ON, OFF]" ON "GDK3_X11_FOUND" OFF)
else()
option( VST2 "Use VST2 plug-in support" ON)
endif()
set(USE_VST ${VST2} CACHE INTERNAL "")
if( NOT WIN32 )
# wxWidgets 3.1 can be explicitly selected if both 3.0 and 3.1 are installed by setting
# the WX_CONFIG environment variable to path of the wx-config script for 3.1.
find_package(
wxWidgets 3.0
COMPONENTS adv base core html qa xml net
)
if(NOT wxWidgets_FOUND)
message(FATAL_ERROR "wxWidgets NOT found. "
"Install wxWidgets and its development headers and try again. "
"If wxWidgets is installed, set the WX_CONFIG environment variable to the path of the wx-config script.")
endif()
include( ${wxWidgets_USE_FILE} )
# The FindwxWidgets.cmake module does not create an IMPORT target, so hack one together. This makes it easy to add the compile definitions
# to the lib-strings and lib-strings-utils targets.
if( NOT TARGET wxWidgets::wxWidgets )
add_library( wxWidgets::wxWidgets INTERFACE IMPORTED )
target_link_libraries( wxWidgets::wxWidgets INTERFACE ${wxWidgets_LIBRARIES} )
target_compile_definitions( wxWidgets::wxWidgets INTERFACE ${CXX_WARNINGS_SILENCE_DEFINES} )
target_compile_definitions( wxWidgets::wxWidgets INTERFACE ${wxWidgets_DEFINITIONS} ${wxWidgets_DEFINITIONS_DEBUG} )
endif()
else()
# On Windows we are using wxWidgets from an unmerged vcpkg branch in our vcpkg overlay https://github.com/microsoft/vcpkg/pull/17111 This
# requires using 'unofficial-wxWidgets' rather than simply 'wxWidgets'. This is required for CMAKE_BUILD_TYPE=Debug to work. Refer to
# https://github.com/microsoft/vcpkg/issues/18066 for background about the bug.
find_package(
unofficial-wxWidgets
COMPONENTS adv base core html qa xml net
)
if( NOT TARGET wxWidgets::wxWidgets )
add_library( wxWidgets::wxWidgets INTERFACE IMPORTED )
target_link_libraries(
wxWidgets::wxWidgets
INTERFACE wx::wxadv wx::wxbase wx::wxcore wx::wxhtml wx::wxqa wx::wxxml wx::wxnet
)
endif()
endif()
add_subdirectory( lib-src/libnyquist )
set( USE_NYQUIST ON )
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Tenacity source directories
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
add_subdirectory( "help" )
add_subdirectory( "images" )
add_subdirectory( "libraries" )
add_subdirectory( "locale" )
add_subdirectory( "src" )
add_subdirectory( "modules" )
add_subdirectory( "nyquist" )
add_subdirectory( "plug-ins" )
add_subdirectory( "scripts" )
# Generate config file
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
configure_file( src/audacity_config.h.in src/private/configwin.h )
elseif( CMAKE_SYSTEM_NAME MATCHES "Darwin" )
set( HAVE_VISIBILITY 1 )
configure_file( src/audacity_config.h.in src/private/configmac.h )
else()
set( HAVE_VISIBILITY 1 )
configure_file( src/audacity_config.h.in src/private/configunix.h )
endif()
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Generate module graph information as image
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# TODO: is this even needed?
#[[
string( JOIN "\n" GRAPH_EDGES ${GRAPH_EDGES} )
# Choose edge attributes making it easy to hover at either end of edge and see a tooltip describing the edge, in svg image
file( WRITE "${CMAKE_CURRENT_BINARY_DIR}/modules.dot" "digraph { graph [rankdir=LR] edge [dir=both,arrowtail=inv] \n" "${GRAPH_EDGES}" "\n}\n")
execute_process( COMMAND dot -O -Tsvg "${CMAKE_CURRENT_BINARY_DIR}/modules.dot" )
#]]
# ~~~~~~~~~~~~
# Code signing
# ~~~~~~~~~~~~
cmd_option( perform_codesign "Perform code signing during the install step. This only works on Windows and macOS." OFF )
cmake_dependent_option( perform_notarization "Perform notarization during the install step. This only works on macOS." OFF "perform_codesign;APPLE" OFF )
if( perform_codesign )
include( AudacityCodeSigning )
endif()
# ~~~~~~~~~~
# Packaging
# ~~~~~~~~~~
cmd_option( package_manual "Package the manual along with the DMG and InnoSetup targets" OFF )
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
include( AudacityInnoSetup )
endif()
include( Package ) # do this last