diff options
author | Marcus Asteborg <maastebo@microsoft.com> | 2020-04-14 01:51:48 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2020-04-21 05:47:56 +0300 |
commit | a0e14e7117fbb05e0ebcfd891188746096531d02 (patch) | |
tree | 5710a1e24ab4e7007e1908587df20a5f291a0e94 | |
parent | 7628d844b4a0435c676fbe9ef03b3c2f8bf3eb5f (diff) |
cmake - Add variable length detection and alloca detection
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
-rw-r--r-- | CMakeLists.txt | 35 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | cmake/CFeatureCheck.cmake | 39 | ||||
-rw-r--r-- | cmake/vla.c | 7 | ||||
-rw-r--r-- | opus_config.cmake | 14 |
5 files changed, 89 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index ae422c78..c5d04d83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.1) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(opus_functions.cmake) @@ -20,7 +21,6 @@ include(opus_buildtype.cmake) option(OPUS_BUILD_SHARED_LIBRARY "Build shared library" OFF) option(OPUS_STACK_PROTECTOR "Use stack protection" ON) -option(OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)" OFF) option(OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames" OFF) option(OPUS_BUILD_PROGRAMS "Build programs" OFF) @@ -40,6 +40,22 @@ include(GNUInstallDirs) include(CMakeDependentOption) include(FeatureSummary) +cmake_dependent_option(OPUS_VAR_ARRAYS + "Use variable length arrays for stack arrays" + ON + "VLA_SUPPORTED; NOT OPUS_USE_ALLOCA; NOT OPUS_NONTHREADSAFE_PSEUDOSTACK" + OFF) +cmake_dependent_option(OPUS_USE_ALLOCA + "Use alloca for stack arrays (on non-C99 compilers)" + ON + "USE_ALLOCA_SUPPORTED; NOT OPUS_VAR_ARRAYS; NOT OPUS_NONTHREADSAFE_PSEUDOSTACK" + OFF) +cmake_dependent_option(OPUS_NONTHREADSAFE_PSEUDOSTACK + "Use a non threadsafe pseudostack when neither variable length arrays or alloca is supported" + ON + "NOT OPUS_VAR_ARRAYS; NOT OPUS_USE_ALLOCA" + OFF) + if(OPUS_BUILD_SHARED_LIBRARY OR BUILD_SHARED_LIBS) # Global flag to cause add_library() to create shared libraries if on. set(BUILD_SHARED_LIBS ON) @@ -68,7 +84,6 @@ else() endif() endif() - if(OPUS_CPU_X86 OR OPUS_CPU_X64) cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE "Does runtime check for SSE1 support" @@ -140,8 +155,12 @@ set_package_properties(Git add_feature_info(OPUS_BUILD_SHARED_LIBRARY OPUS_BUILD_SHARED_LIBRARY "Build shared library") add_feature_info(OPUS_STACK_PROTECTOR STACK_PROTECTOR_SUPPORTED "Use stack protection") +add_feature_info(OPUS_VAR_ARRAYS OPUS_VAR_ARRAYS + "Use variable length arrays for stack arrays") add_feature_info(OPUS_USE_ALLOCA OPUS_USE_ALLOCA "Use alloca for stack arrays (on non-C99 compilers)") +add_feature_info(OPUS_NONTHREADSAFE_PSEUDOSTACK OPUS_NONTHREADSAFE_PSEUDOSTACK + "Use a non threadsafe pseudostack when neither variable length arrays or alloca is supported") add_feature_info(OPUS_CUSTOM_MODES OPUS_CUSTOM_MODES "Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames") add_feature_info(OPUS_BUILD_TESTING OPUS_BUILD_TESTING "Build test programs") @@ -215,14 +234,14 @@ if(NOT MSVC) target_compile_definitions(opus PRIVATE _FORTIFY_SOURCE=2) endif() -# It is strongly recommended to uncomment one of these VAR_ARRAYS: Use C99 -# variable-length arrays for stack allocation USE_ALLOCA: Use alloca() for stack -# allocation If none is defined, then the fallback is a non-threadsafe global -# array -if(OPUS_USE_ALLOCA OR MSVC) +if(OPUS_VAR_ARRAYS) + target_compile_definitions(opus PRIVATE VAR_ARRAYS) +elseif(OPUS_USE_ALLOCA) target_compile_definitions(opus PRIVATE USE_ALLOCA) +elseif(OPUS_NONTHREADSAFE_PSEUDOSTACK) + target_compile_definitions(opus PRIVATE NONTHREADSAFE_PSEUDOSTACK) else() - target_compile_definitions(opus PRIVATE VAR_ARRAYS) + message(ERROR Neet to set a define for stack allocation) endif() if(OPUS_CUSTOM_MODES) diff --git a/Makefile.am b/Makefile.am index 7f905b09..470b8e70 100644 --- a/Makefile.am +++ b/Makefile.am @@ -217,6 +217,8 @@ EXTRA_DIST = opus.pc.in \ opus_functions.cmake \ opus_sources.cmake \ OpusConfig.cmake.in \ + cmake/CFeatureCheck.cmake \ + cmake/vla.c \ tests/run_vectors.sh \ celt/arm/arm2gnu.pl \ celt/arm/celt_pitch_xcorr_arm.s \ diff --git a/cmake/CFeatureCheck.cmake b/cmake/CFeatureCheck.cmake new file mode 100644 index 00000000..4059f434 --- /dev/null +++ b/cmake/CFeatureCheck.cmake @@ -0,0 +1,39 @@ +# - Compile and run code to check for C features +# +# This functions compiles a source file under the `cmake` folder +# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake +# environment +# +# c_feature_check(<FLAG> [<VARIANT>]) +# +# - Example +# +# include(CFeatureCheck) +# c_feature_check(VLA) + +if(__c_feature_check) + return() +endif() +set(__c_feature_check INCLUDED) + +function(c_feature_check FILE) + string(TOLOWER ${FILE} FILE) + string(TOUPPER ${FILE} VAR) + string(TOUPPER "${VAR}_SUPPORTED" FEATURE) + if (DEFINED ${VAR}_SUPPORTED) + set(${VAR}_SUPPORTED 1 PARENT_SCOPE) + return() + endif() + + if (NOT DEFINED COMPILE_${FEATURE}) + message(STATUS "Performing Test ${FEATURE}") + try_compile(COMPILE_${FEATURE} ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/cmake/${FILE}.c) + endif() + + if(COMPILE_${FEATURE}) + message(STATUS "Performing Test ${FEATURE} -- success") + set(${VAR}_SUPPORTED 1 PARENT_SCOPE) + else() + message(STATUS "Performing Test ${FEATURE} -- failed to compile") + endif() +endfunction()
\ No newline at end of file diff --git a/cmake/vla.c b/cmake/vla.c new file mode 100644 index 00000000..e83829e5 --- /dev/null +++ b/cmake/vla.c @@ -0,0 +1,7 @@ +int main() { + static int x; + char a[++x]; + a[sizeof a - 1] = 0; + int N; + return a[0]; +}
\ No newline at end of file diff --git a/opus_config.cmake b/opus_config.cmake index 5bde77eb..bcc78ccf 100644 --- a/opus_config.cmake +++ b/opus_config.cmake @@ -16,6 +16,20 @@ if(HAVE_LIBM) list(APPEND OPUS_REQUIRED_LIBRARIES m) endif() +include(CFeatureCheck) +c_feature_check(VLA) + +include(CheckIncludeFile) +check_include_file(alloca.h HAVE_ALLOCA_H) + +include(CheckSymbolExists) +if(HAVE_ALLOCA_H) + add_definitions(-DHAVE_ALLOCA_H) + check_symbol_exists(alloca "alloca.h" USE_ALLOCA_SUPPORTED) +else() + check_symbol_exists(alloca "stdlib.h;malloc.h" USE_ALLOCA_SUPPORTED) +endif() + include(CheckFunctionExists) check_function_exists(lrintf HAVE_LRINTF) check_function_exists(lrint HAVE_LRINT) |