Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CMake project #7

Merged
merged 31 commits into from
May 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e12e3cd
ADD CMake PROJECT FILES
BurningEnlightenment Jan 16, 2016
43d0e4b
Merge branch 'master' into feature/cmake
BurningEnlightenment Jul 2, 2016
796a5a8
ADD OpenMP SUPPORT TO CMAKE BUILD FILES
BurningEnlightenment Jul 2, 2016
3d5300e
Merge branch 'master' into feature/cmake
BurningEnlightenment Jul 9, 2016
9436179
Merge remote-tracking branch 'upstream/master' into feature/cmake
BurningEnlightenment Feb 16, 2017
8a11f92
CMAKE BUILDSYSTEM OVERHAUL
BurningEnlightenment Feb 16, 2017
2784cac
Merge remote-tracking branch 'upstream/master' into feature/cmake
BurningEnlightenment Apr 11, 2018
f9dd976
CMake build rebased to the latest version of aklomp/base64 library.
vglavnyy Mar 22, 2018
8a3c23b
MSVC x86 32-bit architecture detection fix.
vglavnyy Mar 30, 2018
d205173
Switch from commandline defines to config.h
BurningEnlightenment Apr 11, 2018
f1e6ba2
Merge remote-tracking branch 'upstream/master' into feature/cmake
BurningEnlightenment Jul 22, 2021
bfcb66e
Ignore CMake & VS artifacts
BurningEnlightenment Jul 22, 2021
ef719a0
Include config.h without relative path to allow out-of-tree build
madebr Dec 8, 2020
1e0f1bc
cmake: Remove unused HAVE_FAST_UNALIGNED_ACCESS related options
madebr Dec 8, 2020
3c7bd1e
cmake: add missing source
madebr Dec 8, 2020
5a65bb0
cmake: on Linux, benchmark executable links to rt
madebr Dec 8, 2020
efd30f8
cmake: regenerate tables (when not cross building)
madebr Dec 8, 2020
8b80a5d
cmake: Only regenerate tables if requested
BurningEnlightenment Jul 22, 2021
368abcf
cmake: Make OpenMP option dependent on OpenMP availability
BurningEnlightenment Jul 22, 2021
2d38081
cmake: Adopt best practices wrt target installs
BurningEnlightenment Jul 22, 2021
209ec08
cmake: Use dependent option and feature summary where applicable
BurningEnlightenment Jul 22, 2021
1d50831
cmake: Respect `BUILD_SHARED_LIBS` configuration
BurningEnlightenment Jul 22, 2021
7170a90
cmake: Update version specifier
BurningEnlightenment Jul 22, 2021
e2c75a4
cmake: Fix table regen dependency tree
BurningEnlightenment Jul 23, 2021
a70fa51
cmake: Use DEFINE_SYMBOL target property
BurningEnlightenment Jul 23, 2021
e3ab782
cmake: Use a more common cmake config install path
BurningEnlightenment Jul 23, 2021
1991745
cmake: Use GNUInstallDirs provided include path
BurningEnlightenment Jul 23, 2021
1eb01ff
Specify SameMajorVersion as compatibility policy
BurningEnlightenment Nov 3, 2021
b3dac06
Add an option to disable strict warning treatment
BurningEnlightenment Nov 3, 2021
28507e6
Fix MSVC AVX codec compiler switch
BurningEnlightenment Nov 3, 2021
61a8bee
Fix cmake OpenMP option casing
BurningEnlightenment May 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
264 changes: 264 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# 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
# 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.4.0)

include(GNUInstallDirs)
include(CMakeDependentOption)
include(FeatureSummary)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")

#######################################################################
# platform detection
include(TargetArch)
detect_target_architecture(_TARGET_ARCH)
Copy link
Contributor

@madebr madebr Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMake uses cmake toolchains for specifying the host architecture.
See CMAKE_SYSTEM_PROCESSOR.
Perhaps we should first try to parse CMAKE_SYSTEM_PROCESSOR, and then try to run the compiler?
Using that approach, users can override the architecture in the case of a mis-detection.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you could effectively transliterate the makefile into cmake (ie require users to set options). I'm all about making this as feature rich as possible, but it doesn't seem like it makes sense to wait on the perfect cmake build.



###################################################################
# optional/conditional dependencies
find_package(OpenMP)
set_package_properties(OpenMP PROPERTIES
TYPE OPTIONAL
PURPOSE "Allows to utilize OpenMP"
)


########################################################################
# 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_REGENERATE_TABLES "regenerate the codec tables" OFF "NOT CMAKE_CROSSCOMPILING" OFF)

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")

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")

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

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_executable(table_generator
lib/tables/table_generator.c
)

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 "${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"
)
endif()


########################################################################
# library project
add_library(base64
# library files
lib/lib.c
lib/codec_choose.c
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

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
BurningEnlightenment marked this conversation as resolved.
Show resolved Hide resolved
)

target_include_directories(base64
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}"
)

####################################################################
# platform/compiler specific configuration
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}
)

#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
)
else()
target_compile_definitions(base64
PUBLIC
BASE64_STATIC_DEFINE
Copy link
Contributor

@madebr madebr Nov 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the _DEFINE suffix weird: it's a definition anyways.
How about simply using BASE64_STATIC?

)
endif()

target_compile_options(base64 PRIVATE
$<$<C_COMPILER_ID:MSVC>:
/W4
/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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If all of these are legitimate issues with the code, I'd prefer to have them fixed rather than ignore the warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is currently one violation in the windows __cpuid macro definition and its usage in codec_choose_x86(). Sadly one can only disable the warning as a whole and not just it being treated as an error.

>
$<$<NOT:$<C_COMPILER_ID:MSVC>>:
-Wall
-Wextra
-Wpedantic
>
$<$<BOOL:${BASE64_WERROR}>:$<IF:$<C_COMPILER_ID:MSVC>,/WX,-Werror>>
)

target_compile_definitions(base64 PRIVATE
$<$<C_COMPILER_ID:MSVC>:
# 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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add a else() with a warning about an unknown arch?

else()
    message(WARNING "Unknown architecture: ${_TARGET_ARCH}")
endif()

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A warning definitely makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it though? Obviously there won't be SIMD acceleration, because SIMD instruction sets are architecture specific and one chose to compile for an alien one. Or is this more about not providing official support/ not regularly testing the pure C codec on that architecture?

Copy link
Contributor

@madebr madebr Nov 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another comment, shouldn't TARGET_ARCH be HOST_ARCH?
A target architecture only makes sense for a code generator (=compiler).
Here, we're just converting some sources to binaries (on a build machine to some host machine).


configure_file("${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)

########################################################################
# OpenMP Settings
if (BASE64_WITH_OpenMP)
target_compile_options(base64
PRIVATE
${OpenMP_C_FLAGS}
)
endif()

########################################################################
if (BASE64_BUILD_TESTS)
enable_testing()
add_subdirectory(test)
endif()

########################################################################
# cmake install
install(DIRECTORY include/ TYPE INCLUDE)
install(TARGETS base64 EXPORT base64-targets)

include(CMakePackageConfigHelpers)
configure_package_config_file(cmake/base64-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake"

INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake"
VERSION ${BASE64_VERSION}
COMPATIBILITY SameMajorVersion
)

install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

install(EXPORT base64-targets
NAMESPACE aklomp::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just use base64 as namespace.

Suggested change
NAMESPACE aklomp::
NAMESPACE base64::

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take another look at this suggestion?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tough call. On one hand base64 makes sense as a namespace, but on the other hand it seems kind of invasive to claim the generic term like that.

So then use aklomp as the vendor string? Hm, would work, except it's my name and not a brand. I don't publish any other libraries under the aklomp "banner". It would be weird to require people to include it in their CMakeLists or how it's called.

I think libbase64 might be a compromise?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK there are two widely used conventions: Using a vendor/organization string or using the cmake project name (which in our case would be base64). I dislike base64::base64, because it is unlikely to prevent target name collisions.
However, in the end this is just bikeshedding, so I will change this to whatever you choose as soon as you choose.

DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

########################################################################
feature_summary(WHAT PACKAGES_FOUND PACKAGES_NOT_FOUND ENABLED_FEATURES DISABLED_FEATURES)
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
29 changes: 29 additions & 0 deletions cmake/Modules/TargetArch.cmake
Original file line number Diff line number Diff line change
@@ -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()
34 changes: 34 additions & 0 deletions cmake/Modules/TargetSIMDInstructionSet.cmake
Original file line number Diff line number Diff line change
@@ -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 " ")
Copy link
Owner

@aklomp aklomp Nov 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Support for these levels are not selectable in MSVC?

Edit: to answer my own question: no, they are not. It's strange though, because what to do then? We can't really use the next best level, which is AVX. But the default architecture is only SSE2, so presumably these codecs would miscompile. Argh.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the contrary the SIMD intrinsics up to and including SSE42 are always available on the MSVC platform and cannot be disabled. This isn't an issue for MSVC because they don't utilize them for auto vectorization (unlike gcc).

set(COMPILE_FLAGS_AVX "/arch:AVX")
set(COMPILE_FLAGS_AVX2 "/arch:AVX2")
endif()
endmacro(define_SIMD_compile_flags)
5 changes: 5 additions & 0 deletions cmake/base64-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake")

check_required_components(base64)
25 changes: 25 additions & 0 deletions cmake/config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#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

#endif // BASE64_CONFIG_H
Loading