--- a/CMakeLists.txt 1970-01-01 03:00:00.000000000 +0300 +++ b/CMakeLists.txt 2018-04-11 15:19:34.000000000 +0300 @@ -0,0 +1,202 @@ +# Written in 2016-2017 by Henrik Steffen Gaßmann henrik@gassmann.onl +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# +# http://creativecommons.org/publicdomain/zero/1.0/ +# +######################################################################## +cmake_minimum_required(VERSION 3.1) + +project(base64 LANGUAGES C VERSION 0.3.0) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") + +####################################################################### +# platform detection +include(TargetArch) +detect_target_architecture(_TARGET_ARCH) + + +######################################################################## +# Compilation options +option(BASE64_INSTALL_TARGET "add an install target" ON) +option(BASE64_BUILD_TESTS "add test projects" ON) +option(BASE64_WITH_OpenMP "use openmp" OFF) + +if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") + option(BASE64_WITH_FAST_UNALIGNED_ACCESS "vectorization: unaligned access enabled" ON) + option(BASE64_WITH_SSSE3 "add SSSE 3 codepath" ON) + option(BASE64_WITH_SSE41 "add SSE 4.1 codepath" ON) + option(BASE64_WITH_SSE42 "add SSE 4.2 codepath" ON) + option(BASE64_WITH_AVX "add AVX codepath" ON) + option(BASE64_WITH_AVX2 "add AVX 2 codepath" ON) + +elseif (_TARGET_ARCH STREQUAL "arm") + option(BASE64_WITH_NEON32 "add NEON32 codepath" OFF) + +elseif (_TARGET_ARCH STREQUAL "arm64") + option(BASE64_WITH_NEON64 "add NEON64 codepath" ON) + +endif() + +################################################################### +# OpenMP +if(BASE64_WITH_OpenMP) + find_package(OpenMP) + if (OPENMP_FOUND) + option(BASE64_USE_OpenMP "Utilize OpenMP to parallelize encoding and decoding." ON) + endif() +endif() + +######################################################################## +# library project +add_library(base64 STATIC + # library files + lib/lib.c + lib/codec_choose.c + include/libbase64.h + + # codec implementations + lib/arch/generic/codec.c + + lib/arch/ssse3/codec.c + lib/arch/sse41/codec.c + lib/arch/sse42/codec.c + lib/arch/avx/codec.c + lib/arch/avx2/codec.c + + lib/arch/neon32/codec.c + lib/arch/neon64/codec.c +) + +if (NOT BASE64_STANDALONE_PROJECT) + # export inlucde path if base64 added as subdirectory + target_include_directories(base64 INTERFACE + $ + ) +endif() + +#################################################################### +# platform/compiler specific configuration +set_target_properties(base64 PROPERTIES + C_STANDARD 99 + C_STANDARD_REQUIRED YES + C_EXTENSIONS OFF +) + +target_compile_options(base64 PRIVATE + $<$: + /W4 + /WX # All warnings as error + /we4013 # Error warning C4013: 'function' undefined; assuming extern returning int + /we4700 # Error warning C4700: uninitialized local variable + /we4715 # not all control paths return a value + /we4003 # not enough actual parameters for macro + /wd4456 # disable warning C4456: declaration of 'xxx' hides previous local declaration + > + $<$>: + -Wall + -Wextra + -Wpedantic + > +) + +target_compile_definitions(base64 PRIVATE + $<$: + # remove unnecessary warnings about unchecked iterators + _SCL_SECURE_NO_WARNINGS + > +) + +######################################################################## +# SIMD settings +include(TargetSIMDInstructionSet) +define_SIMD_compile_flags() + +if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") + macro(configure_codec _TYPE) + if (BASE64_WITH_${_TYPE}) + message(STATUS "Add codec: lib/arch/${_DIR}/codec.c") + string(TOLOWER "${_TYPE}" _DIR) + set_source_files_properties("lib/arch/${_DIR}/codec.c" PROPERTIES + COMPILE_FLAGS "${COMPILE_FLAGS_${_TYPE}}" + ) + + if (${ARGC} GREATER 1 AND MSVC) + set_source_files_properties("lib/arch/${_DIR}/codec.c" PROPERTIES + COMPILE_DEFINITIONS ${ARGV1} + ) + endif() + endif() + endmacro() + + configure_codec(SSSE3 __SSSE3__) + configure_codec(SSE41 __SSSE4_1__) + configure_codec(SSE42 __SSSE4_2__) + configure_codec(AVX) + configure_codec(AVX2) + +elseif (_TARGET_ARCH STREQUAL "arm") + set(BASE64_NEON32_CFLAGS "${COMPILE_FLAGS_NEON32}" CACHE STRING "the NEON32 compile flags (for 'lib/arch/neon32/codec.c')") + mark_as_advanced(BASE64_NEON32_CFLAGS) + + if (BASE64_WITH_NEON32) + set_source_files_properties("lib/arch/neon32/codec.c" PROPERTIES + COMPILE_FLAGS "${BASE64_NEON32_CFLAGS} " + ) + endif() + +#elseif (_TARGET_ARCH STREQUAL "arm64" AND BASE64_WITH_NEON64) + +endif() + +configure_file("${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) +target_include_directories(base64 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + +######################################################################## +# OpenMP Settings +if (BASE64_USE_OpenMP) + target_compile_options(base64 + PRIVATE + ${OpenMP_C_FLAGS} + ) +endif() + +######################################################################## +if (BASE64_BUILD_TESTS) + enable_testing() + add_subdirectory(test) +endif() + +######################################################################## +# install target +if (BASE64_INSTALL_TARGET) + install(TARGETS base64 EXPORT base64-targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + INCLUDES DESTINATION include + ) + install(FILES include/libbase64.h DESTINATION include) + + include(CMakePackageConfigHelpers) + write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" + VERSION ${BASE64_VERSION} + COMPATIBILITY ExactVersion + ) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" DESTINATION cmake) + + configure_file(cmake/base64-config.cmake + "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" + COPYONLY + ) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" DESTINATION cmake) + + install(EXPORT base64-targets DESTINATION cmake) +endif() --- a/cmake/base64-config.cmake 1970-01-01 03:00:00.000000000 +0300 +++ b/cmake/base64-config.cmake 2020-12-02 10:29:31.014613200 +0300 @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake") --- a/cmake/config.h.in 1970-01-01 03:00:00.000000000 +0300 +++ b/cmake/config.h.in 2018-04-11 15:19:34.000000000 +0300 @@ -0,0 +1,28 @@ +#ifndef BASE64_CONFIG_H +#define BASE64_CONFIG_H + +#cmakedefine01 BASE64_WITH_SSSE3 +#define HAVE_SSSE3 BASE64_WITH_SSSE3 + +#cmakedefine01 BASE64_WITH_SSE41 +#define HAVE_SSE41 BASE64_WITH_SSE41 + +#cmakedefine01 BASE64_WITH_SSE42 +#define HAVE_SSE42 BASE64_WITH_SSE42 + +#cmakedefine01 BASE64_WITH_AVX +#define HAVE_AVX BASE64_WITH_AVX + +#cmakedefine01 BASE64_WITH_AVX2 +#define HAVE_AVX2 BASE64_WITH_AVX2 + +#cmakedefine01 BASE64_WITH_NEON32 +#define HAVE_NEON32 BASE64_WITH_NEON32 + +#cmakedefine01 BASE64_WITH_NEON64 +#define HAVE_NEON64 BASE64_WITH_NEON64 + +#cmakedefine01 BASE64_WITH_FAST_UNALIGNED_ACCESS +#define HAVE_FAST_UNALIGNED_ACCESS BASE64_WITH_FAST_UNALIGNED_ACCESS + +#endif // BASE64_CONFIG_H --- a/cmake/Modules/TargetArch.cmake 1970-01-01 03:00:00.000000000 +0300 +++ b/cmake/Modules/TargetArch.cmake 2018-04-11 15:19:34.000000000 +0300 @@ -0,0 +1,29 @@ +# Written in 2017 by Henrik Steffen Gaßmann henrik@gassmann.onl +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# +# http://creativecommons.org/publicdomain/zero/1.0/ +# +######################################################################## + +set(TARGET_ARCHITECTURE_TEST_FILE "${CMAKE_CURRENT_LIST_DIR}/../test-arch.c") + +function(detect_target_architecture OUTPUT_VARIABLE) + message(STATUS "${CMAKE_CURRENT_LIST_DIR}") + try_compile(_IGNORED "${CMAKE_CURRENT_BINARY_DIR}" + "${TARGET_ARCHITECTURE_TEST_FILE}" + OUTPUT_VARIABLE _LOG + ) + + string(REGEX MATCH "##arch=([^#]+)##" _IGNORED "${_LOG}") + + set(${OUTPUT_VARIABLE} "${CMAKE_MATCH_1}" PARENT_SCOPE) + if (CMAKE_MATCH_1 STREQUAL "unknown") + message(WARNING "could not detect the target architecture.") + endif() +endfunction() --- a/cmake/Modules/TargetSIMDInstructionSet.cmake 1970-01-01 03:00:00.000000000 +0300 +++ b/cmake/Modules/TargetSIMDInstructionSet.cmake 2018-04-11 15:19:34.000000000 +0300 @@ -0,0 +1,34 @@ +# Written in 2016-2017 by Henrik Steffen Gaßmann henrik@gassmann.onl +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# +# http://creativecommons.org/publicdomain/zero/1.0/ +# +######################################################################## + +######################################################################## +# compiler flags definition +macro(define_SIMD_compile_flags) + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + # x86 + set(COMPILE_FLAGS_SSSE3 "-mssse3") + set(COMPILE_FLAGS_SSE41 "-msse4.1") + set(COMPILE_FLAGS_SSE42 "-msse4.2") + set(COMPILE_FLAGS_AVX "-mavx") + set(COMPILE_FLAGS_AVX2 "-mavx2") + + #arm + set(COMPILE_FLAGS_NEON32 "-mfpu=neon") + elseif(MSVC) + set(COMPILE_FLAGS_SSSE3 " ") + set(COMPILE_FLAGS_SSE41 " ") + set(COMPILE_FLAGS_SSE42 " ") + set(COMPILE_FLAGS_AVX "/arch:AVX2") + set(COMPILE_FLAGS_AVX2 "/arch:AVX2") + endif() +endmacro(define_SIMD_compile_flags) --- a/cmake/test-arch.c 1970-01-01 03:00:00.000000000 +0300 +++ b/cmake/test-arch.c 2018-04-11 15:19:34.000000000 +0300 @@ -0,0 +1,35 @@ +// Written in 2017 by Henrik Steffen Gaßmann henrik@gassmann.onl +// +// To the extent possible under law, the author(s) have dedicated all +// copyright and related and neighboring rights to this software to the +// public domain worldwide. This software is distributed without any warranty. +// +// You should have received a copy of the CC0 Public Domain Dedication +// along with this software. If not, see +// +// http://creativecommons.org/publicdomain/zero/1.0/ +// +//////////////////////////////////////////////////////////////////////////////// + +// ARM 64-Bit +#if defined(__aarch64__) +#error ##arch=arm64## + +// ARM 32-Bit +#elif defined(__arm__) \ + || defined(_M_ARM) +#error ##arch=arm## + +// x86 64-Bit +#elif defined(__x86_64__) \ + || defined(_M_X64) +#error ##arch=x64## + +// x86 32-Bit +#elif defined(__i386__) \ + || defined(_M_IX86) +#error ##arch=x86## + +#else +#error ##arch=unknown## +#endif --- a/test/CMakeLists.txt 1970-01-01 03:00:00.000000000 +0300 +++ b/test/CMakeLists.txt 2020-12-01 13:59:57.970624200 +0300 @@ -0,0 +1,38 @@ +# Written in 2016 by Henrik Steffen Gaßmann henrik@gassmann.onl +# +# To the extent possible under law, the author(s) have dedicated all +# copyright and related and neighboring rights to this software to the +# public domain worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication +# along with this software. If not, see +# +# http://creativecommons.org/publicdomain/zero/1.0/ +# +######################################################################## +cmake_minimum_required(VERSION 3.1) + +function(add_base64_test TEST_NAME) + unset(SRC_FILE) + foreach(SRC_FILE ${ARGN}) + list(APPEND SRC_FILES "${SRC_FILE}") + endforeach() + + add_executable(${TEST_NAME} ${SRC_FILES}) + target_link_libraries(${TEST_NAME} base64) + + add_test(NAME ${TEST_NAME} + COMMAND ${TEST_NAME} + ) +endfunction() + + +add_base64_test(test_base64 + codec_supported.c + test_base64.c +) + +add_base64_test(benchmark + codec_supported.c + benchmark.c +)