From e12e3cd7c77b51560705e7df4bfeb132ccfd4d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Sat, 16 Jan 2016 16:55:00 +0100 Subject: [PATCH 01/26] ADD CMake PROJECT FILES Add static library target. Add SIMD support on x86 platforms. Add install target. Make config.h optional, i.e. the HAVE_* definitions can be supplied via the commandline. Add test driver projects and makefile commands. --- CMakeLists.txt | 162 +++++++++++++++++++ cmake/Modules/TargetArch.cmake | 4 + cmake/Modules/TargetSIMDInstructionSet.cmake | 86 ++++++++++ cmake/base64-config.cmake | 1 + lib/codec_choose.c | 2 + test/CMakeLists.txt | 37 +++++ 6 files changed, 292 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/Modules/TargetArch.cmake create mode 100644 cmake/Modules/TargetSIMDInstructionSet.cmake create mode 100644 cmake/base64-config.cmake create mode 100644 test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..5eed4121 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,162 @@ +# 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 2.8.12) +project(base64) +set(BASE64_VERSION 0.2.1) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") + +if (CMAKE_C_COMPILER_ID STREQUAL "GNU" + OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(BASE64_GNU_C_COMPATIBLE 1) +endif() +if (CMAKE_C_COMPILER_ID STREQUAL "GNU" + OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(BASE64_GNU_CXX_COMPATIBLE 1) +endif() + +# set BASE64_INCLUDED to 1 if you include this project from another +# cmake project (this is handy in combination with git submodules :) +if (NOT BASE64_INCLUDED) + option(BASE64_INSTALL_TARGET "add an install target" ON) + option(BASE64_BUILD_TESTS "add test projects" OFF) + + include(TargetSIMDInstructionSet) + option(BASE64_WITH_SSSE3 "add SSSE3 codepath" OFF) + option(BASE64_WITH_AVX2 "add AVX2 codepath" OFF) + + #list(APPEND BASE64_NEON_OPTIONS NEON32) + #list(APPEND BASE64_NEON_OPTIONS NEON32-DEFAULTED) + #list(APPEND BASE64_NEON_OPTIONS NEON64) + #if (BASE64_NEON_OPTIONS) + #set(BASE64_WITH_NEON "none" CACHE STRING "which NEON codepath should be choosen") + # list(APPEND BASE64_NEON_OPTIONS none) + # set_property(CACHE BASE64_WITH_NEON PROPERTY STRINGS ${BASE64_NEON_OPTIONS}) + # if (NOT ";${BASE64_WITH_NEON};" MATCHES ";${BASE64_NEON_OPTIONS};") + # message(FATAL_ERROR "invalid neon option selected ${BASE64_WITH_NEON}") + #endif() + + #################################################################### + # platform/compiler specific configuration + if(MSVC) + # Force to always compile with W4 + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + if(${CMAKE_C_FLAGS} MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") + endif() + endif() + if (BASE64_GNU_C_COMPATIBLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Wpedantic") + endif() +endif() + +add_library(base64 STATIC + lib/lib.c + lib/codec_avx2.c + lib/codec_choose.c + lib/codec_neon32.c + lib/codec_neon64.c + lib/codec_plain.c + lib/codec_ssse3.c + + include/libbase64.h +) + +######################################################################## +# SIMD settings +define_SIMD_compile_flags() +if (BASE64_WITH_SSSE3) + set_source_files_properties(lib/codec_ssse3.c PROPERTIES + COMPILE_FLAGS ${COMPILE_FLAGS_SSSE3} + ) + if (MSVC) + # if SSSE3 is available it is always enabled by default, + # but MSVC _never_ defines __SSSE3__ + set_source_files_properties(lib/codec_ssse3.c PROPERTIES + COMPILE_DEFINITIONS __SSSE3__ + ) + endif() + set(HAVE_SSSE3 1) +else() + set(HAVE_SSSE3 0) +endif() +if (BASE64_WITH_AVX2) + set_source_files_properties(lib/codec_avx2.c PROPERTIES + COMPILE_FLAGS ${COMPILE_FLAGS_AVX2} + ) + set(HAVE_AVX2 1) +else() + set(HAVE_AVX2 0) +endif() +# this needs much more love... +set(HAVE_NEON32 0) +set(HAVE_NEON64 0) +if (BASE64_WITH_NEON MATCHES NEON32) + if(BASE64_WITH_NEON MATCHES NEON32-DEFAULTED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS_NEON32}") + else() + set_source_files_properties(lib/codec_neon32.c PROPERTIES + COMPILE_FLAGS ${COMPILE_FLAGS_NEON32} + ) + endif() + set(HAVE_NEON32 1) +elseif (BASE64_WITH_NEON STREQUAL NEON64) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS_NEON64}") + set(HAVE_NEON64 1) +endif() + + +target_compile_definitions(base64 + PRIVATE + CMD_DEFINED_CONFIG + HAVE_SSSE3=${HAVE_SSSE3} + HAVE_AVX2=${HAVE_AVX2} + HAVE_NEON32=${HAVE_NEON32} + HAVE_NEON64=${HAVE_NEON64} +) + +######################################################################## +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() diff --git a/cmake/Modules/TargetArch.cmake b/cmake/Modules/TargetArch.cmake new file mode 100644 index 00000000..215e4662 --- /dev/null +++ b/cmake/Modules/TargetArch.cmake @@ -0,0 +1,4 @@ + +macro(target_architecture OUTPUT_VARIABLE) + message(FATAL_ERROR "the target_architecture macro has not been implemented") +endmacro() diff --git a/cmake/Modules/TargetSIMDInstructionSet.cmake b/cmake/Modules/TargetSIMDInstructionSet.cmake new file mode 100644 index 00000000..d4a1fed9 --- /dev/null +++ b/cmake/Modules/TargetSIMDInstructionSet.cmake @@ -0,0 +1,86 @@ +# 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/ +# +######################################################################## + +include(TargetArch) +include(CheckSymbolExists) + +######################################################################## +# compiler flags definition +macro(define_SIMD_compile_flags) + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(COMPILE_FLAGS_SSSE3 "-mssse3") + set(COMPILE_FLAGS_AVX2 "-mavx2") + #elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") <- sorry about that, but old cmake versions think "MSVC" is a variable and must be dereferenced :( + elseif(MSVC) + set(COMPILE_FLAGS_SSSE3 " ") + set(COMPILE_FLAGS_AVX2 "/arch:AVX2") + endif() +endmacro(define_SIMD_compile_flags) + +######################################################################## +# compiler feature detection (incomplete & currently unused) +function(detect_target_SIMD_instruction_set_SSSE3 OUTPUT_VARIABLE) + define_SIMD_compile_flags() + + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILE_FLAGS_SSSE3}") + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + check_symbol_exists(__SSSE3__ "tmmintrin.h" DTCTN_VALUE) + #elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + elseif(MSVC) + # with msvc one would have to try to compile a program referencing + # all used intrinsics. However I do know for sure that MSVC + # supports SSSE3 since MSVC 14 / VS2008... + if (MSVC_VERSION GREATER 1300) + set(DTCTN_VALUE 1) + else() + set(DTCTN_VALUE 0) + endif() + endif() + + if (DTCTN_VALUE) + set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} SSSE3-FOUND PARENT_SCOPE) + else() + set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} SSSE3-NOTFOUND PARENT_SCOPE) + endif() +endfunction(detect_target_SIMD_instruction_set_SSSE3) + +function(detect_target_SIMD_instruction_set_AVX2 OUTPUT_VARIABLE) + define_SIMD_compile_flags() + + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILE_FLAGS_AVX2}") + check_symbol_exists(__AVX2__ "immintrin.h" DTCTN_VALUE) + + if (DTCTN_VALUE) + set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} AVX2-FOUND PARENT_SCOPE) + else() + set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} AVX2-NOTFOUND PARENT_SCOPE) + endif() +endfunction(detect_target_SIMD_instruction_set_AVX2) + +function(detect_target_SIMD_instruction_set_NEON OUTPUT_VARIABLE) + +endfunction(detect_target_SIMD_instruction_set_NEON) + +function(detect_target_SIMD_instruction_set OUTPUT_VARIABLE) + target_architecture(_TARGET_ARCH) + + if (APPLE AND CMAKE_OSX_ARCHITECTURES + OR _TARGET_ARCH STREQUAL "i386" + OR _TARGET_ARCH STREQUAL "x86_64") + detect_target_SIMD_instruction_set_SSSE3(_TEMP_OUTPUT) + detect_target_SIMD_instruction_set_AVX2(_TEMP_OUTPUT) + elseif(_TARGET_ARCH MATCHES arm) + # add neon detection + endif() + set(${OUTPUT_VARIABLE} ${_TEMP_OUTPUT} PARENT_SCOPE) +endfunction(detect_target_SIMD_instruction_set) diff --git a/cmake/base64-config.cmake b/cmake/base64-config.cmake new file mode 100644 index 00000000..75a40a04 --- /dev/null +++ b/cmake/base64-config.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake") \ No newline at end of file diff --git a/lib/codec_choose.c b/lib/codec_choose.c index fada59b9..847f7579 100644 --- a/lib/codec_choose.c +++ b/lib/codec_choose.c @@ -5,7 +5,9 @@ #include "../include/libbase64.h" #include "codecs.h" +#ifndef CMD_DEFINED_CONFIG #include "config.h" +#endif #if __x86_64__ || __i386__ || _M_X86 || _M_X64 #ifdef _MSC_VER diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 00000000..3dba06e6 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,37 @@ +# 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/ +# +######################################################################## + +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 +) From 796a5a88b3406a361902a2ab913802cd63a6575f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Sat, 2 Jul 2016 13:59:00 +0200 Subject: [PATCH 02/26] ADD OpenMP SUPPORT TO CMAKE BUILD FILES --- CMakeLists.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5eed4121..a19c6455 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Written in 2016 by Henrik Steffen Gaßmann henrik@gassmann.onl +# 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 @@ -25,6 +25,9 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" set(BASE64_GNU_CXX_COMPATIBLE 1) endif() +######################################################################## +# Compilation options +# # set BASE64_INCLUDED to 1 if you include this project from another # cmake project (this is handy in combination with git submodules :) if (NOT BASE64_INCLUDED) @@ -45,6 +48,13 @@ if (NOT BASE64_INCLUDED) # if (NOT ";${BASE64_WITH_NEON};" MATCHES ";${BASE64_NEON_OPTIONS};") # message(FATAL_ERROR "invalid neon option selected ${BASE64_WITH_NEON}") #endif() + + ################################################################### + # OpenMP + find_package(OpenMP) + if (OPENMP_FOUND) + option(BASE64_USE_OpenMP "Utilize OpenMP to parallelize encoding and decoding.") + endif() #################################################################### # platform/compiler specific configuration @@ -62,6 +72,8 @@ if (NOT BASE64_INCLUDED) endif() endif() +######################################################################## +# library project add_library(base64 STATIC lib/lib.c lib/codec_avx2.c @@ -127,6 +139,12 @@ target_compile_definitions(base64 HAVE_NEON64=${HAVE_NEON64} ) +######################################################################## +# OpenMP Settings +if (BASE64_USE_OpenMP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") +endif() + ######################################################################## if (BASE64_BUILD_TESTS) enable_testing() From 8a11f9275db2d24f1db6c8ea6b2774b1040cef82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 16 Feb 2017 15:36:33 +0100 Subject: [PATCH 03/26] CMAKE BUILDSYSTEM OVERHAUL Adapt the build system to the recent source code changes. Add platform detection code for arm, arm64, x86 and x64. Offer SIMD compile options depending on platform. Add preliminary support for NEON codecs. Enable the SIMD compile options by default. - Clean cmake scripts. - Bump version to 0.3.0. - Fix UTF-8 issues. --- CMakeLists.txt | 195 ++++++++++--------- cmake/Modules/TargetArch.cmake | 28 ++- cmake/Modules/TargetSIMDInstructionSet.cmake | 74 ++----- cmake/test-arch.c | 35 ++++ 4 files changed, 175 insertions(+), 157 deletions(-) create mode 100644 cmake/test-arch.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a19c6455..1fdfe787 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Written in 2016 by Henrik Steffen Ga�mann henrik@gassmann.onl +# 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 @@ -12,7 +12,7 @@ ######################################################################## cmake_minimum_required(VERSION 2.8.12) project(base64) -set(BASE64_VERSION 0.2.1) +set(BASE64_VERSION 0.3.0) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") @@ -25,118 +25,131 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" set(BASE64_GNU_CXX_COMPATIBLE 1) endif() + +####################################################################### +# platform detection +include(TargetArch) +detect_target_architecture(_TARGET_ARCH) + + ######################################################################## # Compilation options -# -# set BASE64_INCLUDED to 1 if you include this project from another -# cmake project (this is handy in combination with git submodules :) -if (NOT BASE64_INCLUDED) - option(BASE64_INSTALL_TARGET "add an install target" ON) - option(BASE64_BUILD_TESTS "add test projects" OFF) - - include(TargetSIMDInstructionSet) - option(BASE64_WITH_SSSE3 "add SSSE3 codepath" OFF) - option(BASE64_WITH_AVX2 "add AVX2 codepath" OFF) - - #list(APPEND BASE64_NEON_OPTIONS NEON32) - #list(APPEND BASE64_NEON_OPTIONS NEON32-DEFAULTED) - #list(APPEND BASE64_NEON_OPTIONS NEON64) - #if (BASE64_NEON_OPTIONS) - #set(BASE64_WITH_NEON "none" CACHE STRING "which NEON codepath should be choosen") - # list(APPEND BASE64_NEON_OPTIONS none) - # set_property(CACHE BASE64_WITH_NEON PROPERTY STRINGS ${BASE64_NEON_OPTIONS}) - # if (NOT ";${BASE64_WITH_NEON};" MATCHES ";${BASE64_NEON_OPTIONS};") - # message(FATAL_ERROR "invalid neon option selected ${BASE64_WITH_NEON}") - #endif() - - ################################################################### - # OpenMP - find_package(OpenMP) - if (OPENMP_FOUND) - option(BASE64_USE_OpenMP "Utilize OpenMP to parallelize encoding and decoding.") - endif() - - #################################################################### - # platform/compiler specific configuration - if(MSVC) - # Force to always compile with W4 - add_definitions(-D_CRT_SECURE_NO_WARNINGS) - if(${CMAKE_C_FLAGS} MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") - endif() - endif() - if (BASE64_GNU_C_COMPATIBLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Wpedantic") +option(BASE64_INSTALL_TARGET "add an install target" ON) +option(BASE64_BUILD_TESTS "add test projects" OFF) + +if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") + 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 +find_package(OpenMP) +if (OPENMP_FOUND) + option(BASE64_USE_OpenMP "Utilize OpenMP to parallelize encoding and decoding." ON) +endif() + + +#################################################################### +# platform/compiler specific configuration +if(MSVC) + # Force to always compile with W4 + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + if(${CMAKE_C_FLAGS} MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") endif() endif() +if (BASE64_GNU_C_COMPATIBLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Wpedantic") + set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -r") +endif() + ######################################################################## # library project add_library(base64 STATIC + # library files lib/lib.c - lib/codec_avx2.c lib/codec_choose.c - lib/codec_neon32.c - lib/codec_neon64.c - lib/codec_plain.c - lib/codec_ssse3.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 ) ######################################################################## # SIMD settings +include(TargetSIMDInstructionSet) define_SIMD_compile_flags() -if (BASE64_WITH_SSSE3) - set_source_files_properties(lib/codec_ssse3.c PROPERTIES - COMPILE_FLAGS ${COMPILE_FLAGS_SSSE3} - ) - if (MSVC) - # if SSSE3 is available it is always enabled by default, - # but MSVC _never_ defines __SSSE3__ - set_source_files_properties(lib/codec_ssse3.c PROPERTIES - COMPILE_DEFINITIONS __SSSE3__ - ) - endif() - set(HAVE_SSSE3 1) -else() - set(HAVE_SSSE3 0) -endif() -if (BASE64_WITH_AVX2) - set_source_files_properties(lib/codec_avx2.c PROPERTIES - COMPILE_FLAGS ${COMPILE_FLAGS_AVX2} - ) - set(HAVE_AVX2 1) -else() - set(HAVE_AVX2 0) -endif() -# this needs much more love... -set(HAVE_NEON32 0) -set(HAVE_NEON64 0) -if (BASE64_WITH_NEON MATCHES NEON32) - if(BASE64_WITH_NEON MATCHES NEON32-DEFAULTED) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS_NEON32}") - else() - set_source_files_properties(lib/codec_neon32.c PROPERTIES - COMPILE_FLAGS ${COMPILE_FLAGS_NEON32} + +if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") + macro(configure_codec _TYPE) + if (BASE64_WITH_${_TYPE}) + 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() - set(HAVE_NEON32 1) -elseif (BASE64_WITH_NEON STREQUAL NEON64) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS_NEON64}") - set(HAVE_NEON64 1) -endif() +#elseif (_TARGET_ARCH STREQUAL "arm64" AND BASE64_WITH_NEON64) + +endif() target_compile_definitions(base64 PRIVATE CMD_DEFINED_CONFIG - HAVE_SSSE3=${HAVE_SSSE3} - HAVE_AVX2=${HAVE_AVX2} - HAVE_NEON32=${HAVE_NEON32} - HAVE_NEON64=${HAVE_NEON64} + HAVE_SSSE3=$ + HAVE_SSE41=$ + HAVE_SSE42=$ + HAVE_AVX=$ + HAVE_AVX2=$ + HAVE_NEON32=$ + HAVE_NEON64=$ ) ######################################################################## diff --git a/cmake/Modules/TargetArch.cmake b/cmake/Modules/TargetArch.cmake index 215e4662..ab04da0d 100644 --- a/cmake/Modules/TargetArch.cmake +++ b/cmake/Modules/TargetArch.cmake @@ -1,4 +1,26 @@ +# 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/ +# +######################################################################## -macro(target_architecture OUTPUT_VARIABLE) - message(FATAL_ERROR "the target_architecture macro has not been implemented") -endmacro() +function(detect_target_architecture OUTPUT_VARIABLE) + try_compile(_IGNORED "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_SOURCE_DIR}/cmake/test-arch.c" + 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() diff --git a/cmake/Modules/TargetSIMDInstructionSet.cmake b/cmake/Modules/TargetSIMDInstructionSet.cmake index d4a1fed9..cd2806ba 100644 --- a/cmake/Modules/TargetSIMDInstructionSet.cmake +++ b/cmake/Modules/TargetSIMDInstructionSet.cmake @@ -1,4 +1,4 @@ -# Written in 2016 by Henrik Steffen Gaßmann henrik@gassmann.onl +# 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 @@ -11,76 +11,24 @@ # ######################################################################## -include(TargetArch) -include(CheckSymbolExists) - ######################################################################## # 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") - #elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") <- sorry about that, but old cmake versions think "MSVC" is a variable and must be dereferenced :( + + #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) - -######################################################################## -# compiler feature detection (incomplete & currently unused) -function(detect_target_SIMD_instruction_set_SSSE3 OUTPUT_VARIABLE) - define_SIMD_compile_flags() - - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILE_FLAGS_SSSE3}") - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - check_symbol_exists(__SSSE3__ "tmmintrin.h" DTCTN_VALUE) - #elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") - elseif(MSVC) - # with msvc one would have to try to compile a program referencing - # all used intrinsics. However I do know for sure that MSVC - # supports SSSE3 since MSVC 14 / VS2008... - if (MSVC_VERSION GREATER 1300) - set(DTCTN_VALUE 1) - else() - set(DTCTN_VALUE 0) - endif() - endif() - - if (DTCTN_VALUE) - set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} SSSE3-FOUND PARENT_SCOPE) - else() - set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} SSSE3-NOTFOUND PARENT_SCOPE) - endif() -endfunction(detect_target_SIMD_instruction_set_SSSE3) - -function(detect_target_SIMD_instruction_set_AVX2 OUTPUT_VARIABLE) - define_SIMD_compile_flags() - - set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILE_FLAGS_AVX2}") - check_symbol_exists(__AVX2__ "immintrin.h" DTCTN_VALUE) - - if (DTCTN_VALUE) - set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} AVX2-FOUND PARENT_SCOPE) - else() - set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} AVX2-NOTFOUND PARENT_SCOPE) - endif() -endfunction(detect_target_SIMD_instruction_set_AVX2) - -function(detect_target_SIMD_instruction_set_NEON OUTPUT_VARIABLE) - -endfunction(detect_target_SIMD_instruction_set_NEON) - -function(detect_target_SIMD_instruction_set OUTPUT_VARIABLE) - target_architecture(_TARGET_ARCH) - - if (APPLE AND CMAKE_OSX_ARCHITECTURES - OR _TARGET_ARCH STREQUAL "i386" - OR _TARGET_ARCH STREQUAL "x86_64") - detect_target_SIMD_instruction_set_SSSE3(_TEMP_OUTPUT) - detect_target_SIMD_instruction_set_AVX2(_TEMP_OUTPUT) - elseif(_TARGET_ARCH MATCHES arm) - # add neon detection - endif() - set(${OUTPUT_VARIABLE} ${_TEMP_OUTPUT} PARENT_SCOPE) -endfunction(detect_target_SIMD_instruction_set) diff --git a/cmake/test-arch.c b/cmake/test-arch.c new file mode 100644 index 00000000..85dc76ba --- /dev/null +++ b/cmake/test-arch.c @@ -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_X86) +#error ##arch=x86## + +#else +#error ##arch=unknown## +#endif From f9dd976ae5201236767f86787cd61bfd14711f8b Mon Sep 17 00:00:00 2001 From: vglavnyy Date: Thu, 22 Mar 2018 13:18:42 +0700 Subject: [PATCH 04/26] CMake build rebased to the latest version of aklomp/base64 library. The OpenMp by default disabled for the plain-codec. --- CMakeLists.txt | 89 ++++++++++++++++++++-------------- cmake/Modules/TargetArch.cmake | 2 +- config.h.in | 14 ++++++ 3 files changed, 68 insertions(+), 37 deletions(-) create mode 100644 config.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fdfe787..eb9c6bf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,21 +10,11 @@ # http://creativecommons.org/publicdomain/zero/1.0/ # ######################################################################## -cmake_minimum_required(VERSION 2.8.12) -project(base64) -set(BASE64_VERSION 0.3.0) +cmake_minimum_required(VERSION 3.1) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules") - -if (CMAKE_C_COMPILER_ID STREQUAL "GNU" - OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - set(BASE64_GNU_C_COMPATIBLE 1) -endif() -if (CMAKE_C_COMPILER_ID STREQUAL "GNU" - OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - set(BASE64_GNU_CXX_COMPATIBLE 1) -endif() +project(base64 LANGUAGES C VERSION 0.3.0) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") ####################################################################### # platform detection @@ -35,9 +25,11 @@ detect_target_architecture(_TARGET_ARCH) ######################################################################## # Compilation options option(BASE64_INSTALL_TARGET "add an install target" ON) -option(BASE64_BUILD_TESTS "add test projects" OFF) +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) @@ -52,31 +44,14 @@ elseif (_TARGET_ARCH STREQUAL "arm64") endif() - ################################################################### # OpenMP -find_package(OpenMP) -if (OPENMP_FOUND) - option(BASE64_USE_OpenMP "Utilize OpenMP to parallelize encoding and decoding." ON) -endif() - - -#################################################################### -# platform/compiler specific configuration -if(MSVC) - # Force to always compile with W4 - add_definitions(-D_CRT_SECURE_NO_WARNINGS) - if(${CMAKE_C_FLAGS} MATCHES "/W[0-4]") - string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") - else() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4") +if(BASE64_WITH_OPENMP) + find_package(OpenMP) + if (OPENMP_FOUND) + option(BASE64_USE_OpenMP "Utilize OpenMP to parallelize encoding and decoding." ON) endif() endif() -if (BASE64_GNU_C_COMPATIBLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Wpedantic") - set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -r") -endif() - ######################################################################## # library project @@ -99,6 +74,44 @@ add_library(base64 STATIC 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 + > + $<$>: + -Wall + -Wextra + -Wpedantic + > +) + +target_compile_definitions(base64 PRIVATE + $<$: + # remove unnecessary warnings about unchecked iterators + _SCL_SECURE_NO_WARNINGS + > +) + ######################################################################## # SIMD settings include(TargetSIMDInstructionSet) @@ -107,6 +120,7 @@ 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}}" @@ -140,9 +154,12 @@ elseif (_TARGET_ARCH STREQUAL "arm") endif() +configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libbase64_config.h @ONLY) + target_compile_definitions(base64 PRIVATE - CMD_DEFINED_CONFIG + BASE64_DIRECT_CONFIG=$ + HAVE_FAST_UNALIGNED_ACCESS=$ HAVE_SSSE3=$ HAVE_SSE41=$ HAVE_SSE42=$ diff --git a/cmake/Modules/TargetArch.cmake b/cmake/Modules/TargetArch.cmake index ab04da0d..5e889df1 100644 --- a/cmake/Modules/TargetArch.cmake +++ b/cmake/Modules/TargetArch.cmake @@ -13,7 +13,7 @@ function(detect_target_architecture OUTPUT_VARIABLE) try_compile(_IGNORED "${CMAKE_CURRENT_BINARY_DIR}" - "${CMAKE_SOURCE_DIR}/cmake/test-arch.c" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-arch.c" OUTPUT_VARIABLE _LOG ) diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..7dafa1b6 --- /dev/null +++ b/config.h.in @@ -0,0 +1,14 @@ +#ifndef BASE64_CONFIG_H +#define BASE64_CONFIG_H + +#cmakedefine BASE64_USE_OpenMP +#cmakedefine BASE64_WITH_SSSE3 +#cmakedefine BASE64_WITH_SSE41 +#cmakedefine BASE64_WITH_SSE42 +#cmakedefine BASE64_WITH_AVX +#cmakedefine BASE64_WITH_AVX2 +#cmakedefine BASE64_WITH_NEON32 +#cmakedefine BASE64_WITH_NEON64 +#cmakedefine BASE64_WITH_FAST_UNALIGNED_ACCESS + +#endif // BASE64_CONFIG_H From 8a3c23b4ed5c5b3899160d6c70741ddf8b33f2d8 Mon Sep 17 00:00:00 2001 From: vglavnyy Date: Fri, 30 Mar 2018 22:20:31 +0700 Subject: [PATCH 05/26] MSVC x86 32-bit architecture detection fix. --- cmake/test-arch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/test-arch.c b/cmake/test-arch.c index 85dc76ba..b438405e 100644 --- a/cmake/test-arch.c +++ b/cmake/test-arch.c @@ -27,7 +27,7 @@ // x86 32-Bit #elif defined(__i386__) \ - || defined(_M_X86) + || defined(_M_IX86) #error ##arch=x86## #else From d20517370228473c72cdf3fe51f299e628f1d538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Wed, 11 Apr 2018 14:19:34 +0200 Subject: [PATCH 06/26] Switch from commandline defines to config.h - Move config.h.in into the cmake folder - Fix some cmake path issues --- CMakeLists.txt | 22 +++++++--------------- cmake/Modules/TargetArch.cmake | 5 ++++- cmake/config.h.in | 28 ++++++++++++++++++++++++++++ config.h.in | 14 -------------- 4 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 cmake/config.h.in delete mode 100644 config.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index eb9c6bf6..58ec55e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ target_compile_options(base64 PRIVATE /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 @@ -154,25 +155,16 @@ elseif (_TARGET_ARCH STREQUAL "arm") endif() -configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/libbase64_config.h @ONLY) - -target_compile_definitions(base64 - PRIVATE - BASE64_DIRECT_CONFIG=$ - HAVE_FAST_UNALIGNED_ACCESS=$ - HAVE_SSSE3=$ - HAVE_SSE41=$ - HAVE_SSE42=$ - HAVE_AVX=$ - HAVE_AVX2=$ - HAVE_NEON32=$ - HAVE_NEON64=$ -) +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) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + target_compile_options(base64 + PRIVATE + ${OpenMP_C_FLAGS} + ) endif() ######################################################################## diff --git a/cmake/Modules/TargetArch.cmake b/cmake/Modules/TargetArch.cmake index 5e889df1..f20c6efc 100644 --- a/cmake/Modules/TargetArch.cmake +++ b/cmake/Modules/TargetArch.cmake @@ -11,9 +11,12 @@ # ######################################################################## +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}" - "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-arch.c" + "${TARGET_ARCHITECTURE_TEST_FILE}" OUTPUT_VARIABLE _LOG ) diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 00000000..4a86bebf --- /dev/null +++ b/cmake/config.h.in @@ -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 diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 7dafa1b6..00000000 --- a/config.h.in +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef BASE64_CONFIG_H -#define BASE64_CONFIG_H - -#cmakedefine BASE64_USE_OpenMP -#cmakedefine BASE64_WITH_SSSE3 -#cmakedefine BASE64_WITH_SSE41 -#cmakedefine BASE64_WITH_SSE42 -#cmakedefine BASE64_WITH_AVX -#cmakedefine BASE64_WITH_AVX2 -#cmakedefine BASE64_WITH_NEON32 -#cmakedefine BASE64_WITH_NEON64 -#cmakedefine BASE64_WITH_FAST_UNALIGNED_ACCESS - -#endif // BASE64_CONFIG_H From bfcb66ec6b738e442543fa5f5094da02b614fb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 09:38:34 +0200 Subject: [PATCH 07/26] Ignore CMake & VS artifacts --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index c0512f5f..837a2306 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,10 @@ bin/base64 lib/config.h test/benchmark test/test_base64 + +# visual studio symbol db, etc. +.vs/ +# build directory used by CMakePresets +out/ +# private cmake presets +CMakeUserPresets.json From ef719a04ac764ff97703daf9af1e5f4c6122f49a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 8 Dec 2020 03:15:41 +0100 Subject: [PATCH 08/26] Include config.h without relative path to allow out-of-tree build --- Makefile | 1 + lib/arch/avx/codec.c | 2 +- lib/arch/avx2/codec.c | 2 +- lib/arch/generic/codec.c | 2 +- lib/arch/neon32/codec.c | 2 +- lib/arch/neon64/codec.c | 2 +- lib/arch/sse41/codec.c | 2 +- lib/arch/sse42/codec.c | 2 +- lib/arch/ssse3/codec.c | 2 +- 9 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index c9b42326..2bb01e20 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,7 @@ lib/config.h: @echo "#define HAVE_AVX $(HAVE_AVX)" >> $@ $(OBJS): lib/config.h +$(OBJS): CFLAGS += -Ilib lib/arch/avx2/codec.o: CFLAGS += $(AVX2_CFLAGS) lib/arch/neon32/codec.o: CFLAGS += $(NEON32_CFLAGS) diff --git a/lib/arch/avx/codec.c b/lib/arch/avx/codec.c index 0581a6b7..a7a963d8 100644 --- a/lib/arch/avx/codec.c +++ b/lib/arch/avx/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #if HAVE_AVX diff --git a/lib/arch/avx2/codec.c b/lib/arch/avx2/codec.c index d3c6818e..0498548b 100644 --- a/lib/arch/avx2/codec.c +++ b/lib/arch/avx2/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #if HAVE_AVX2 diff --git a/lib/arch/generic/codec.c b/lib/arch/generic/codec.c index bd6e0b34..8dd5af23 100644 --- a/lib/arch/generic/codec.c +++ b/lib/arch/generic/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #if BASE64_WORDSIZE == 32 diff --git a/lib/arch/neon32/codec.c b/lib/arch/neon32/codec.c index e2e3ed2f..7ef46109 100644 --- a/lib/arch/neon32/codec.c +++ b/lib/arch/neon32/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #ifdef __arm__ diff --git a/lib/arch/neon64/codec.c b/lib/arch/neon64/codec.c index 65767d51..6aba53c5 100644 --- a/lib/arch/neon64/codec.c +++ b/lib/arch/neon64/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #ifdef __aarch64__ diff --git a/lib/arch/sse41/codec.c b/lib/arch/sse41/codec.c index b1421943..00645fed 100644 --- a/lib/arch/sse41/codec.c +++ b/lib/arch/sse41/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #if HAVE_SSE41 diff --git a/lib/arch/sse42/codec.c b/lib/arch/sse42/codec.c index 6dd813ae..cf5d97cf 100644 --- a/lib/arch/sse42/codec.c +++ b/lib/arch/sse42/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #if HAVE_SSE42 diff --git a/lib/arch/ssse3/codec.c b/lib/arch/ssse3/codec.c index 01ced0e0..ad14a458 100644 --- a/lib/arch/ssse3/codec.c +++ b/lib/arch/ssse3/codec.c @@ -5,7 +5,7 @@ #include "../../../include/libbase64.h" #include "../../tables/tables.h" #include "../../codecs.h" -#include "../../config.h" +#include "config.h" #include "../../env.h" #if HAVE_SSSE3 From 1e0f1bcfc9338724ceefcda7530dc8c8d78e593a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 8 Dec 2020 03:21:13 +0100 Subject: [PATCH 09/26] cmake: Remove unused HAVE_FAST_UNALIGNED_ACCESS related options --- CMakeLists.txt | 1 - cmake/config.h.in | 3 --- 2 files changed, 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58ec55e8..035b98fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,6 @@ 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) diff --git a/cmake/config.h.in b/cmake/config.h.in index 4a86bebf..8530d1e1 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -22,7 +22,4 @@ #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 From 3c7bd1ec6273c407960eabbce0f8fb4203154cf1 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 8 Dec 2020 03:32:02 +0100 Subject: [PATCH 10/26] cmake: add missing source --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 035b98fb..f092ecfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ add_library(base64 STATIC # library files lib/lib.c lib/codec_choose.c + lib/tables/tables.c include/libbase64.h # codec implementations From 5a65bb034aed4684fbb55ef5c03796bb8e85cd02 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 8 Dec 2020 03:33:25 +0100 Subject: [PATCH 11/26] cmake: on Linux, benchmark executable links to rt --- test/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3dba06e6..c53fc690 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Written in 2016 by Henrik Steffen Gaßmann henrik@gassmann.onl +# 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 @@ -18,7 +18,7 @@ function(add_base64_test TEST_NAME) endforeach() add_executable(${TEST_NAME} ${SRC_FILES}) - target_link_libraries(${TEST_NAME} base64) + target_link_libraries(${TEST_NAME} PRIVATE base64) add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} @@ -35,3 +35,6 @@ add_base64_test(benchmark codec_supported.c benchmark.c ) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + target_link_libraries(benchmark PRIVATE rt) +endif() From efd30f86d98f7df93dad9b99941a277edc714e30 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 8 Dec 2020 03:54:25 +0100 Subject: [PATCH 12/26] cmake: regenerate tables (when not cross building) --- CMakeLists.txt | 27 ++++++++++++++++++++++++++- lib/tables/CMakeLists.txt | 3 +++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 lib/tables/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index f092ecfa..2685fef9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,15 +52,40 @@ if(BASE64_WITH_OPENMP) endif() endif() +######################################################################## +# Regenerate headers + +if(NOT CMAKE_CROSSCOMPILING) + # Generate tables in build folder and copy to source tree. + # Don't add the tables in the source tree to the outputs, to avoid `make clean` removing them. + add_subdirectory(lib/tables) + add_custom_command(OUTPUT table_dec_32bit.h + COMMAND table_generator > table_dec_32bit.h + COMMAND "${CMAKE_COMMAND}" -E copy table_dec_32bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_dec_32bit.h" + DEPENDS table_generator + ) + set(Python_ADDITIONAL_VERSIONS 3) + find_package(PythonInterp REQUIRED) + add_custom_command(OUTPUT table_enc_12bit.h + COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.py" > table_enc_12bit.h + COMMAND "${CMAKE_COMMAND}" -E copy table_enc_12bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.h" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.py" + ) +endif() + + ######################################################################## # library project add_library(base64 STATIC # library files lib/lib.c lib/codec_choose.c - lib/tables/tables.c include/libbase64.h + lib/tables/tables.c + table_enc_12bit.h + table_dec_32bit.h + # codec implementations lib/arch/generic/codec.c diff --git a/lib/tables/CMakeLists.txt b/lib/tables/CMakeLists.txt new file mode 100644 index 00000000..15cfa9a1 --- /dev/null +++ b/lib/tables/CMakeLists.txt @@ -0,0 +1,3 @@ +add_executable(table_generator + table_generator.c +) From 8b80a5d7de78c790990d812fa1abff4a75456641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 10:02:34 +0200 Subject: [PATCH 13/26] cmake: Only regenerate tables if requested --- CMakeLists.txt | 11 +++++++---- lib/tables/CMakeLists.txt | 3 --- 2 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 lib/tables/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 2685fef9..9a0c0da9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ cmake_minimum_required(VERSION 3.1) project(base64 LANGUAGES C VERSION 0.3.0) +include(CMakeDependentOption) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") ####################################################################### @@ -27,6 +28,7 @@ detect_target_architecture(_TARGET_ARCH) option(BASE64_INSTALL_TARGET "add an install target" ON) option(BASE64_BUILD_TESTS "add test projects" ON) option(BASE64_WITH_OPENMP "use openmp" OFF) +cmake_dependent_option(BASE64_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF) if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") option(BASE64_WITH_SSSE3 "add SSSE 3 codepath" ON) @@ -55,10 +57,13 @@ endif() ######################################################################## # Regenerate headers -if(NOT CMAKE_CROSSCOMPILING) +if (BASE64_REGENERATE_TABLES) # Generate tables in build folder and copy to source tree. # Don't add the tables in the source tree to the outputs, to avoid `make clean` removing them. - add_subdirectory(lib/tables) + add_executable(table_generator + lib/tables/table_generator.c + ) + add_custom_command(OUTPUT table_dec_32bit.h COMMAND table_generator > table_dec_32bit.h COMMAND "${CMAKE_COMMAND}" -E copy table_dec_32bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_dec_32bit.h" @@ -83,8 +88,6 @@ add_library(base64 STATIC include/libbase64.h lib/tables/tables.c - table_enc_12bit.h - table_dec_32bit.h # codec implementations lib/arch/generic/codec.c diff --git a/lib/tables/CMakeLists.txt b/lib/tables/CMakeLists.txt deleted file mode 100644 index 15cfa9a1..00000000 --- a/lib/tables/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_executable(table_generator - table_generator.c -) From 368abcffacc75bc4843fab590519df141df4a560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 10:14:05 +0200 Subject: [PATCH 14/26] cmake: Make OpenMP option dependent on OpenMP availability --- CMakeLists.txt | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a0c0da9..765d3075 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,11 +23,16 @@ include(TargetArch) detect_target_architecture(_TARGET_ARCH) +################################################################### +# optional/conditional dependencies +find_package(OpenMP) + + ######################################################################## # 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) +cmake_dependent_option(BASE64_WITH_OPENMP "use openmp" OFF "OPENMP_FOUND" OFF) cmake_dependent_option(BASE64_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF) if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") @@ -45,14 +50,6 @@ elseif (_TARGET_ARCH STREQUAL "arm64") 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() ######################################################################## # Regenerate headers @@ -188,7 +185,7 @@ target_include_directories(base64 PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") ######################################################################## # OpenMP Settings -if (BASE64_USE_OpenMP) +if (BASE64_WITH_OpenMP) target_compile_options(base64 PRIVATE ${OpenMP_C_FLAGS} From 2d3808167459dcad165d4978a28c74d4cad2ca5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 11:56:51 +0200 Subject: [PATCH 15/26] cmake: Adopt best practices wrt target installs --- CMakeLists.txt | 58 ++++++++++++++++++------------------ cmake/base64-config.cmake | 1 - cmake/base64-config.cmake.in | 5 ++++ test/CMakeLists.txt | 11 ++++--- 4 files changed, 41 insertions(+), 34 deletions(-) delete mode 100644 cmake/base64-config.cmake create mode 100644 cmake/base64-config.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 765d3075..738d147c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ cmake_minimum_required(VERSION 3.1) project(base64 LANGUAGES C VERSION 0.3.0) +include(GNUInstallDirs) include(CMakeDependentOption) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") @@ -30,7 +31,6 @@ find_package(OpenMP) ######################################################################## # Compilation options -option(BASE64_INSTALL_TARGET "add an install target" ON) option(BASE64_BUILD_TESTS "add test projects" ON) cmake_dependent_option(BASE64_WITH_OPENMP "use openmp" OFF "OPENMP_FOUND" OFF) cmake_dependent_option(BASE64_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF) @@ -99,12 +99,13 @@ add_library(base64 STATIC lib/arch/neon64/codec.c ) -if (NOT BASE64_STANDALONE_PROJECT) - # export inlucde path if base64 added as subdirectory - target_include_directories(base64 INTERFACE +target_include_directories(base64 + PUBLIC $ - ) -endif() + $ + PRIVATE + "${CMAKE_CURRENT_BINARY_DIR}" +) #################################################################### # platform/compiler specific configuration @@ -181,7 +182,6 @@ elseif (_TARGET_ARCH STREQUAL "arm") 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 @@ -199,29 +199,29 @@ if (BASE64_BUILD_TESTS) 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) +# cmake install +install(DIRECTORY include/ TYPE INCLUDE) +install(TARGETS base64 EXPORT base64-targets) - 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) +include(CMakePackageConfigHelpers) +configure_package_config_file(cmake/base64-config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" + + INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" +) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" + VERSION ${BASE64_VERSION} + COMPATIBILITY ExactVersion +) - configure_file(cmake/base64-config.cmake +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" - COPYONLY - ) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" DESTINATION cmake) + "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" + DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" +) - install(EXPORT base64-targets DESTINATION cmake) -endif() +install(EXPORT base64-targets + NAMESPACE aklomp:: + DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" +) diff --git a/cmake/base64-config.cmake b/cmake/base64-config.cmake deleted file mode 100644 index 75a40a04..00000000 --- a/cmake/base64-config.cmake +++ /dev/null @@ -1 +0,0 @@ -include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake") \ No newline at end of file diff --git a/cmake/base64-config.cmake.in b/cmake/base64-config.cmake.in new file mode 100644 index 00000000..d009bf73 --- /dev/null +++ b/cmake/base64-config.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake") + +check_required_components(base64) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c53fc690..fc67a722 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -31,10 +31,13 @@ add_base64_test(test_base64 test_base64.c ) -add_base64_test(benchmark - codec_supported.c - benchmark.c -) +if (NOT WIN32) + add_base64_test(benchmark + codec_supported.c + benchmark.c + ) +endif() + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") target_link_libraries(benchmark PRIVATE rt) endif() From 209ec0891dda73628a344e6d59292036d9373afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 12:45:20 +0200 Subject: [PATCH 16/26] cmake: Use dependent option and feature summary where applicable --- CMakeLists.txt | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 738d147c..368e6c33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ project(base64 LANGUAGES C VERSION 0.3.0) include(GNUInstallDirs) include(CMakeDependentOption) +include(FeatureSummary) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules") ####################################################################### @@ -27,28 +28,38 @@ detect_target_architecture(_TARGET_ARCH) ################################################################### # optional/conditional dependencies find_package(OpenMP) +set_package_properties(OpenMP PROPERTIES + TYPE OPTIONAL + PURPOSE "Allows to utilize openmp" +) ######################################################################## # Compilation options option(BASE64_BUILD_TESTS "add test projects" ON) cmake_dependent_option(BASE64_WITH_OPENMP "use openmp" OFF "OPENMP_FOUND" OFF) +add_feature_info("OpenMP codec" BASE64_WITH_OPENMP "spreads codec work accross multiple threads") cmake_dependent_option(BASE64_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF) -if (_TARGET_ARCH STREQUAL "x86" OR _TARGET_ARCH STREQUAL "x64") - 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) +set(_IS_X86 "\"${_TARGET_ARCH}\" STREQUAL \"x86\" OR \"${_TARGET_ARCH}\" STREQUAL \"x64\"") +cmake_dependent_option(BASE64_WITH_SSSE3 "add SSSE 3 codepath" ON ${_IS_X86} OFF) +add_feature_info(SSSE3 BASE64_WITH_SSSE3 "add SSSE 3 codepath") +cmake_dependent_option(BASE64_WITH_SSE41 "add SSE 4.1 codepath" ON ${_IS_X86} OFF) +add_feature_info(SSE4.1 BASE64_WITH_SSE41 "add SSE 4.1 codepath") +cmake_dependent_option(BASE64_WITH_SSE42 "add SSE 4.2 codepath" ON ${_IS_X86} OFF) +add_feature_info(SSE4.2 BASE64_WITH_SSE42 "add SSE 4.2 codepath") +cmake_dependent_option(BASE64_WITH_AVX "add AVX codepath" ON ${_IS_X86} OFF) +add_feature_info(AVX BASE64_WITH_AVX "add AVX codepath") +cmake_dependent_option(BASE64_WITH_AVX2 "add AVX 2 codepath" ON ${_IS_X86} OFF) +add_feature_info(AVX2 BASE64_WITH_AVX2 "add AVX2 codepath") -elseif (_TARGET_ARCH STREQUAL "arm") - option(BASE64_WITH_NEON32 "add NEON32 codepath" OFF) +set(_IS_ARM "\"${_TARGET_ARCH}\" STREQUAL \"arm\"") +cmake_dependent_option(BASE64_WITH_NEON32 "add NEON32 codepath" OFF ${_IS_ARM} OFF) +add_feature_info(NEON32 BASE64_WITH_NEON32 "add NEON32 codepath") -elseif (_TARGET_ARCH STREQUAL "arm64") - option(BASE64_WITH_NEON64 "add NEON64 codepath" ON) - -endif() +set(_IS_ARM64 "\"${_TARGET_ARCH}\" STREQUAL \"arm64\"") +cmake_dependent_option(BASE64_WITH_NEON64 "add NEON64 codepath" ON ${_IS_ARM64} OFF) +add_feature_info(NEON64 BASE64_WITH_NEON64 "add NEON64 codepath") ######################################################################## @@ -225,3 +236,6 @@ install(EXPORT base64-targets NAMESPACE aklomp:: DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" ) + +######################################################################## +feature_summary(WHAT PACKAGES_FOUND PACKAGES_NOT_FOUND ENABLED_FEATURES DISABLED_FEATURES) From 1d50831a0ed13d51f04834fa07f6069f37689c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 14:25:56 +0200 Subject: [PATCH 17/26] cmake: Respect `BUILD_SHARED_LIBS` configuration Create a shared library if requested by the user. The symbol export machinery has been kept forward compatible to `generate_export_header`. --- CMakeLists.txt | 26 +++++++++++++++++++++++-- include/libbase64.h | 47 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 368e6c33..ac948f96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Written in 2016-2017 by Henrik Steffen Gaßmann henrik@gassmann.onl +# Written in 2016-2017, 2021 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 @@ -61,6 +61,8 @@ set(_IS_ARM64 "\"${_TARGET_ARCH}\" STREQUAL \"arm64\"") cmake_dependent_option(BASE64_WITH_NEON64 "add NEON64 codepath" ON ${_IS_ARM64} OFF) add_feature_info(NEON64 BASE64_WITH_NEON64 "add NEON64 codepath") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") ######################################################################## # Regenerate headers @@ -89,7 +91,7 @@ endif() ######################################################################## # library project -add_library(base64 STATIC +add_library(base64 # library files lib/lib.c lib/codec_choose.c @@ -124,8 +126,28 @@ set_target_properties(base64 PROPERTIES C_STANDARD 99 C_STANDARD_REQUIRED YES C_EXTENSIONS OFF + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} ) +#generate_export_header(base64) +# the following definitions and those in libbase64.h have been +# kept forward compatible in case we ever switch to generate_export_header +if (BUILD_SHARED_LIBS) + set_target_properties(base64 PROPERTIES + C_VISIBILITY_PRESET hidden + ) + target_compile_definitions(base64 + PRIVATE + BASE64_EXPORTS + ) +else() + target_compile_definitions(base64 + PUBLIC + BASE64_STATIC_DEFINE + ) +endif() + target_compile_options(base64 PRIVATE $<$: /W4 diff --git a/include/libbase64.h b/include/libbase64.h index 51e56746..bc63d0a1 100644 --- a/include/libbase64.h +++ b/include/libbase64.h @@ -3,6 +3,39 @@ #include /* size_t */ + +#if defined(_WIN32) || defined(__CYGWIN__) +#define BASE64_SYMBOL_IMPORT __declspec(dllimport) +#define BASE64_SYMBOL_EXPORT __declspec(dllexport) +#define BASE64_SYMBOL_PRIVATE + +#elif __GNUC__ >= 4 +#define BASE64_SYMBOL_IMPORT __attribute__ ((visibility ("default"))) +#define BASE64_SYMBOL_EXPORT __attribute__ ((visibility ("default"))) +#define BASE64_SYMBOL_PRIVATE __attribute__ ((visibility ("hidden"))) + +#else +#define BASE64_SYMBOL_IMPORT +#define BASE64_SYMBOL_EXPORT +#define BASE64_SYMBOL_PRIVATE +#endif + +#if defined(BASE64_STATIC_DEFINE) +#define BASE64_EXPORT +#define BASE64_NO_EXPORT + +#else +#if defined(BASE64_EXPORTS) // defined if we are building the shared library +#define BASE64_EXPORT BASE64_SYMBOL_EXPORT + +#else +#define BASE64_EXPORT BASE64_SYMBOL_IMPORT +#endif + +#define BASE64_NO_EXPORT BASE64_SYMBOL_PRIVATE +#endif + + #ifdef __cplusplus extern "C" { #endif @@ -32,7 +65,7 @@ struct base64_state { * to *out without trailing zero. Output length in bytes is written to *outlen. * The buffer in `out` has been allocated by the caller and is at least 4/3 the * size of the input. See above for `flags`; set to 0 for default operation: */ -void base64_encode +void BASE64_EXPORT base64_encode ( const char *src , size_t srclen , char *out @@ -42,7 +75,7 @@ void base64_encode /* Call this before calling base64_stream_encode() to init the state. See above * for `flags`; set to 0 for default operation: */ -void base64_stream_encode_init +void BASE64_EXPORT base64_stream_encode_init ( struct base64_state *state , int flags ) ; @@ -52,7 +85,7 @@ void base64_stream_encode_init * must be at least 4/3 the size of the in-buffer, but take some margin. Places * the number of new bytes written into `outlen` (which is set to zero when the * function starts). Does not zero-terminate or finalize the output. */ -void base64_stream_encode +void BASE64_EXPORT base64_stream_encode ( struct base64_state *state , const char *src , size_t srclen @@ -64,7 +97,7 @@ void base64_stream_encode * Adds the required end-of-stream markers if appropriate. `outlen` is modified * and will contain the number of new bytes written at `out` (which will quite * often be zero). */ -void base64_stream_encode_final +void BASE64_EXPORT base64_stream_encode_final ( struct base64_state *state , char *out , size_t *outlen @@ -74,7 +107,7 @@ void base64_stream_encode_final * to *out without trailing zero. Output length in bytes is written to *outlen. * The buffer in `out` has been allocated by the caller and is at least 3/4 the * size of the input. See above for `flags`, set to 0 for default operation: */ -int base64_decode +int BASE64_EXPORT base64_decode ( const char *src , size_t srclen , char *out @@ -84,7 +117,7 @@ int base64_decode /* Call this before calling base64_stream_decode() to init the state. See above * for `flags`; set to 0 for default operation: */ -void base64_stream_decode_init +void BASE64_EXPORT base64_stream_decode_init ( struct base64_state *state , int flags ) ; @@ -97,7 +130,7 @@ void base64_stream_decode_init * well, and 0 if a decoding error was found, such as an invalid character. * Returns -1 if the chosen codec is not included in the current build. Used by * the test harness to check whether a codec is available for testing. */ -int base64_stream_decode +int BASE64_EXPORT base64_stream_decode ( struct base64_state *state , const char *src , size_t srclen From 7170a90fe2065b3aed042ebe3f51fff7da73dfec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Thu, 22 Jul 2021 14:37:48 +0200 Subject: [PATCH 18/26] cmake: Update version specifier --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac948f96..e533200f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ ######################################################################## cmake_minimum_required(VERSION 3.1) -project(base64 LANGUAGES C VERSION 0.3.0) +project(base64 LANGUAGES C VERSION 0.4.0) include(GNUInstallDirs) include(CMakeDependentOption) From e2c75a4f24c8a6c1516053852dd2883faf2e0f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Fri, 23 Jul 2021 08:25:03 +0200 Subject: [PATCH 19/26] cmake: Fix table regen dependency tree --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e533200f..a469698e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,14 +74,14 @@ if (BASE64_REGENERATE_TABLES) lib/tables/table_generator.c ) - add_custom_command(OUTPUT table_dec_32bit.h + add_custom_command(OUTPUT table_dec_32bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_dec_32bit.h" COMMAND table_generator > table_dec_32bit.h COMMAND "${CMAKE_COMMAND}" -E copy table_dec_32bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_dec_32bit.h" DEPENDS table_generator ) set(Python_ADDITIONAL_VERSIONS 3) find_package(PythonInterp REQUIRED) - add_custom_command(OUTPUT table_enc_12bit.h + add_custom_command(OUTPUT table_enc_12bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.h" COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.py" > table_enc_12bit.h COMMAND "${CMAKE_COMMAND}" -E copy table_enc_12bit.h "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.h" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/lib/tables/table_enc_12bit.py" @@ -98,6 +98,9 @@ add_library(base64 include/libbase64.h lib/tables/tables.c + # Add generated headers explicitly to target, to insert them in the dependency tree + lib/tables/table_dec_32bit.h + lib/tables/table_enc_12bit.h # codec implementations lib/arch/generic/codec.c From a70fa51ed418a6450405d82e76d22ce60f37db5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Fri, 23 Jul 2021 08:31:52 +0200 Subject: [PATCH 20/26] cmake: Use DEFINE_SYMBOL target property --- CMakeLists.txt | 5 +---- include/libbase64.h | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a469698e..02867594 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -129,6 +129,7 @@ set_target_properties(base64 PROPERTIES C_STANDARD 99 C_STANDARD_REQUIRED YES C_EXTENSIONS OFF + DEFINE_SYMBOL BASE64_EXPORTS VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) @@ -140,10 +141,6 @@ if (BUILD_SHARED_LIBS) set_target_properties(base64 PROPERTIES C_VISIBILITY_PRESET hidden ) - target_compile_definitions(base64 - PRIVATE - BASE64_EXPORTS - ) else() target_compile_definitions(base64 PUBLIC diff --git a/include/libbase64.h b/include/libbase64.h index bc63d0a1..d470a82f 100644 --- a/include/libbase64.h +++ b/include/libbase64.h @@ -20,11 +20,11 @@ #define BASE64_SYMBOL_PRIVATE #endif -#if defined(BASE64_STATIC_DEFINE) +#if defined(BASE64_STATIC_DEFINE) #define BASE64_EXPORT #define BASE64_NO_EXPORT -#else +#else #if defined(BASE64_EXPORTS) // defined if we are building the shared library #define BASE64_EXPORT BASE64_SYMBOL_EXPORT From e3ab782d7110d335bce5ae2ced6d9eb7ae8b2fb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Fri, 23 Jul 2021 12:07:27 +0200 Subject: [PATCH 21/26] cmake: Use a more common cmake config install path --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02867594..7829e73c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,7 +240,7 @@ include(CMakePackageConfigHelpers) configure_package_config_file(cmake/base64-config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" @@ -251,12 +251,12 @@ write_basic_package_version_file( install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" - DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) install(EXPORT base64-targets NAMESPACE aklomp:: - DESTINATION "${CMAKE_INSTALL_DATADIR}/base64" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" ) ######################################################################## From 19917450bbf102f7804365a5c91a32e2457f7522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Ga=C3=9Fmann?= Date: Fri, 23 Jul 2021 12:46:44 +0200 Subject: [PATCH 22/26] cmake: Use GNUInstallDirs provided include path Co-authored-by: Anonymous Maarten --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7829e73c..a2f603fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ add_library(base64 target_include_directories(base64 PUBLIC $ - $ + $ PRIVATE "${CMAKE_CURRENT_BINARY_DIR}" ) From 1eb01fff6853400915557c87fc676d4f388f42cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Wed, 3 Nov 2021 07:28:19 +0100 Subject: [PATCH 23/26] Specify SameMajorVersion as compatibility policy --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a2f603fd..95f28953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,7 +245,7 @@ configure_package_config_file(cmake/base64-config.cmake.in write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" VERSION ${BASE64_VERSION} - COMPATIBILITY ExactVersion + COMPATIBILITY SameMajorVersion ) install(FILES From b3dac064818c058bf967902e97edab9c9ece95d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Wed, 3 Nov 2021 07:52:48 +0100 Subject: [PATCH 24/26] Add an option to disable strict warning treatment --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 95f28953..68d2ef20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ set_package_properties(OpenMP PROPERTIES ######################################################################## # Compilation options +option(BASE64_WERROR "Treat warnings as error" ON) option(BASE64_BUILD_TESTS "add test projects" ON) cmake_dependent_option(BASE64_WITH_OPENMP "use openmp" OFF "OPENMP_FOUND" OFF) add_feature_info("OpenMP codec" BASE64_WITH_OPENMP "spreads codec work accross multiple threads") @@ -151,7 +152,6 @@ endif() 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 @@ -163,6 +163,7 @@ target_compile_options(base64 PRIVATE -Wextra -Wpedantic > + $<$:$,/WX,-Werror>> ) target_compile_definitions(base64 PRIVATE From 28507e6ebaa1c7713e684e7bc2e1ecf261ed86e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Wed, 3 Nov 2021 08:21:42 +0100 Subject: [PATCH 25/26] Fix MSVC AVX codec compiler switch --- cmake/Modules/TargetSIMDInstructionSet.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/TargetSIMDInstructionSet.cmake b/cmake/Modules/TargetSIMDInstructionSet.cmake index cd2806ba..0490121c 100644 --- a/cmake/Modules/TargetSIMDInstructionSet.cmake +++ b/cmake/Modules/TargetSIMDInstructionSet.cmake @@ -28,7 +28,7 @@ macro(define_SIMD_compile_flags) set(COMPILE_FLAGS_SSSE3 " ") set(COMPILE_FLAGS_SSE41 " ") set(COMPILE_FLAGS_SSE42 " ") - set(COMPILE_FLAGS_AVX "/arch:AVX2") + set(COMPILE_FLAGS_AVX "/arch:AVX") set(COMPILE_FLAGS_AVX2 "/arch:AVX2") endif() endmacro(define_SIMD_compile_flags) From 61a8beea85af2f8c06f9241452aec5fe9dfb41c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20S=2E=20Ga=C3=9Fmann?= Date: Tue, 10 May 2022 18:29:24 +0200 Subject: [PATCH 26/26] Fix cmake OpenMP option casing Resolves BurningEnlightenment/base64-cmake#4 --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68d2ef20..4aaf21d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ detect_target_architecture(_TARGET_ARCH) find_package(OpenMP) set_package_properties(OpenMP PROPERTIES TYPE OPTIONAL - PURPOSE "Allows to utilize openmp" + PURPOSE "Allows to utilize OpenMP" ) @@ -38,8 +38,8 @@ set_package_properties(OpenMP PROPERTIES # Compilation options option(BASE64_WERROR "Treat warnings as error" ON) option(BASE64_BUILD_TESTS "add test projects" ON) -cmake_dependent_option(BASE64_WITH_OPENMP "use openmp" OFF "OPENMP_FOUND" OFF) -add_feature_info("OpenMP codec" BASE64_WITH_OPENMP "spreads codec work accross multiple threads") +cmake_dependent_option(BASE64_WITH_OpenMP "use OpenMP" OFF "OpenMP_FOUND" OFF) +add_feature_info("OpenMP codec" BASE64_WITH_OpenMP "spreads codec work accross multiple threads") cmake_dependent_option(BASE64_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF) set(_IS_X86 "\"${_TARGET_ARCH}\" STREQUAL \"x86\" OR \"${_TARGET_ARCH}\" STREQUAL \"x64\"")