Skip to content

Commit e12e3cd

Browse files
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.
1 parent 42aca68 commit e12e3cd

File tree

6 files changed

+292
-0
lines changed

6 files changed

+292
-0
lines changed

CMakeLists.txt

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Written in 2016 by Henrik Steffen Gaßmann [email protected]
2+
#
3+
# To the extent possible under law, the author(s) have dedicated all
4+
# copyright and related and neighboring rights to this software to the
5+
# public domain worldwide. This software is distributed without any warranty.
6+
#
7+
# You should have received a copy of the CC0 Public Domain Dedication
8+
# along with this software. If not, see
9+
#
10+
# http://creativecommons.org/publicdomain/zero/1.0/
11+
#
12+
########################################################################
13+
cmake_minimum_required(VERSION 2.8.12)
14+
project(base64)
15+
set(BASE64_VERSION 0.2.1)
16+
17+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules")
18+
19+
if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
20+
OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
21+
set(BASE64_GNU_C_COMPATIBLE 1)
22+
endif()
23+
if (CMAKE_C_COMPILER_ID STREQUAL "GNU"
24+
OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
25+
set(BASE64_GNU_CXX_COMPATIBLE 1)
26+
endif()
27+
28+
# set BASE64_INCLUDED to 1 if you include this project from another
29+
# cmake project (this is handy in combination with git submodules :)
30+
if (NOT BASE64_INCLUDED)
31+
option(BASE64_INSTALL_TARGET "add an install target" ON)
32+
option(BASE64_BUILD_TESTS "add test projects" OFF)
33+
34+
include(TargetSIMDInstructionSet)
35+
option(BASE64_WITH_SSSE3 "add SSSE3 codepath" OFF)
36+
option(BASE64_WITH_AVX2 "add AVX2 codepath" OFF)
37+
38+
#list(APPEND BASE64_NEON_OPTIONS NEON32)
39+
#list(APPEND BASE64_NEON_OPTIONS NEON32-DEFAULTED)
40+
#list(APPEND BASE64_NEON_OPTIONS NEON64)
41+
#if (BASE64_NEON_OPTIONS)
42+
#set(BASE64_WITH_NEON "none" CACHE STRING "which NEON codepath should be choosen")
43+
# list(APPEND BASE64_NEON_OPTIONS none)
44+
# set_property(CACHE BASE64_WITH_NEON PROPERTY STRINGS ${BASE64_NEON_OPTIONS})
45+
# if (NOT ";${BASE64_WITH_NEON};" MATCHES ";${BASE64_NEON_OPTIONS};")
46+
# message(FATAL_ERROR "invalid neon option selected ${BASE64_WITH_NEON}")
47+
#endif()
48+
49+
####################################################################
50+
# platform/compiler specific configuration
51+
if(MSVC)
52+
# Force to always compile with W4
53+
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
54+
if(${CMAKE_C_FLAGS} MATCHES "/W[0-4]")
55+
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
56+
else()
57+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
58+
endif()
59+
endif()
60+
if (BASE64_GNU_C_COMPATIBLE)
61+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Wpedantic")
62+
endif()
63+
endif()
64+
65+
add_library(base64 STATIC
66+
lib/lib.c
67+
lib/codec_avx2.c
68+
lib/codec_choose.c
69+
lib/codec_neon32.c
70+
lib/codec_neon64.c
71+
lib/codec_plain.c
72+
lib/codec_ssse3.c
73+
74+
include/libbase64.h
75+
)
76+
77+
########################################################################
78+
# SIMD settings
79+
define_SIMD_compile_flags()
80+
if (BASE64_WITH_SSSE3)
81+
set_source_files_properties(lib/codec_ssse3.c PROPERTIES
82+
COMPILE_FLAGS ${COMPILE_FLAGS_SSSE3}
83+
)
84+
if (MSVC)
85+
# if SSSE3 is available it is always enabled by default,
86+
# but MSVC _never_ defines __SSSE3__
87+
set_source_files_properties(lib/codec_ssse3.c PROPERTIES
88+
COMPILE_DEFINITIONS __SSSE3__
89+
)
90+
endif()
91+
set(HAVE_SSSE3 1)
92+
else()
93+
set(HAVE_SSSE3 0)
94+
endif()
95+
if (BASE64_WITH_AVX2)
96+
set_source_files_properties(lib/codec_avx2.c PROPERTIES
97+
COMPILE_FLAGS ${COMPILE_FLAGS_AVX2}
98+
)
99+
set(HAVE_AVX2 1)
100+
else()
101+
set(HAVE_AVX2 0)
102+
endif()
103+
# this needs much more love...
104+
set(HAVE_NEON32 0)
105+
set(HAVE_NEON64 0)
106+
if (BASE64_WITH_NEON MATCHES NEON32)
107+
if(BASE64_WITH_NEON MATCHES NEON32-DEFAULTED)
108+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS_NEON32}")
109+
else()
110+
set_source_files_properties(lib/codec_neon32.c PROPERTIES
111+
COMPILE_FLAGS ${COMPILE_FLAGS_NEON32}
112+
)
113+
endif()
114+
set(HAVE_NEON32 1)
115+
elseif (BASE64_WITH_NEON STREQUAL NEON64)
116+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMPILE_FLAGS_NEON64}")
117+
set(HAVE_NEON64 1)
118+
endif()
119+
120+
121+
target_compile_definitions(base64
122+
PRIVATE
123+
CMD_DEFINED_CONFIG
124+
HAVE_SSSE3=${HAVE_SSSE3}
125+
HAVE_AVX2=${HAVE_AVX2}
126+
HAVE_NEON32=${HAVE_NEON32}
127+
HAVE_NEON64=${HAVE_NEON64}
128+
)
129+
130+
########################################################################
131+
if (BASE64_BUILD_TESTS)
132+
enable_testing()
133+
add_subdirectory(test)
134+
endif()
135+
136+
########################################################################
137+
# install target
138+
if (BASE64_INSTALL_TARGET)
139+
install(TARGETS base64 EXPORT base64-targets
140+
RUNTIME DESTINATION bin/$<CONFIG>
141+
LIBRARY DESTINATION lib/$<CONFIG>
142+
ARCHIVE DESTINATION lib/$<CONFIG>
143+
INCLUDES DESTINATION include
144+
)
145+
install(FILES include/libbase64.h DESTINATION include)
146+
147+
include(CMakePackageConfigHelpers)
148+
write_basic_package_version_file(
149+
"${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake"
150+
VERSION ${BASE64_VERSION}
151+
COMPATIBILITY ExactVersion
152+
)
153+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config-version.cmake" DESTINATION cmake)
154+
155+
configure_file(cmake/base64-config.cmake
156+
"${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake"
157+
COPYONLY
158+
)
159+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/base64-config.cmake" DESTINATION cmake)
160+
161+
install(EXPORT base64-targets DESTINATION cmake)
162+
endif()

cmake/Modules/TargetArch.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
macro(target_architecture OUTPUT_VARIABLE)
3+
message(FATAL_ERROR "the target_architecture macro has not been implemented")
4+
endmacro()
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Written in 2016 by Henrik Steffen Gaßmann [email protected]
2+
#
3+
# To the extent possible under law, the author(s) have dedicated all
4+
# copyright and related and neighboring rights to this software to the
5+
# public domain worldwide. This software is distributed without any warranty.
6+
#
7+
# You should have received a copy of the CC0 Public Domain Dedication
8+
# along with this software. If not, see
9+
#
10+
# http://creativecommons.org/publicdomain/zero/1.0/
11+
#
12+
########################################################################
13+
14+
include(TargetArch)
15+
include(CheckSymbolExists)
16+
17+
########################################################################
18+
# compiler flags definition
19+
macro(define_SIMD_compile_flags)
20+
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
21+
set(COMPILE_FLAGS_SSSE3 "-mssse3")
22+
set(COMPILE_FLAGS_AVX2 "-mavx2")
23+
#elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") <- sorry about that, but old cmake versions think "MSVC" is a variable and must be dereferenced :(
24+
elseif(MSVC)
25+
set(COMPILE_FLAGS_SSSE3 " ")
26+
set(COMPILE_FLAGS_AVX2 "/arch:AVX2")
27+
endif()
28+
endmacro(define_SIMD_compile_flags)
29+
30+
########################################################################
31+
# compiler feature detection (incomplete & currently unused)
32+
function(detect_target_SIMD_instruction_set_SSSE3 OUTPUT_VARIABLE)
33+
define_SIMD_compile_flags()
34+
35+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILE_FLAGS_SSSE3}")
36+
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
37+
check_symbol_exists(__SSSE3__ "tmmintrin.h" DTCTN_VALUE)
38+
#elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
39+
elseif(MSVC)
40+
# with msvc one would have to try to compile a program referencing
41+
# all used intrinsics. However I do know for sure that MSVC
42+
# supports SSSE3 since MSVC 14 / VS2008...
43+
if (MSVC_VERSION GREATER 1300)
44+
set(DTCTN_VALUE 1)
45+
else()
46+
set(DTCTN_VALUE 0)
47+
endif()
48+
endif()
49+
50+
if (DTCTN_VALUE)
51+
set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} SSSE3-FOUND PARENT_SCOPE)
52+
else()
53+
set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} SSSE3-NOTFOUND PARENT_SCOPE)
54+
endif()
55+
endfunction(detect_target_SIMD_instruction_set_SSSE3)
56+
57+
function(detect_target_SIMD_instruction_set_AVX2 OUTPUT_VARIABLE)
58+
define_SIMD_compile_flags()
59+
60+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${COMPILE_FLAGS_AVX2}")
61+
check_symbol_exists(__AVX2__ "immintrin.h" DTCTN_VALUE)
62+
63+
if (DTCTN_VALUE)
64+
set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} AVX2-FOUND PARENT_SCOPE)
65+
else()
66+
set(${OUTPUT_VARIABLE} ${${OUTPUT_VARIABLE}} AVX2-NOTFOUND PARENT_SCOPE)
67+
endif()
68+
endfunction(detect_target_SIMD_instruction_set_AVX2)
69+
70+
function(detect_target_SIMD_instruction_set_NEON OUTPUT_VARIABLE)
71+
72+
endfunction(detect_target_SIMD_instruction_set_NEON)
73+
74+
function(detect_target_SIMD_instruction_set OUTPUT_VARIABLE)
75+
target_architecture(_TARGET_ARCH)
76+
77+
if (APPLE AND CMAKE_OSX_ARCHITECTURES
78+
OR _TARGET_ARCH STREQUAL "i386"
79+
OR _TARGET_ARCH STREQUAL "x86_64")
80+
detect_target_SIMD_instruction_set_SSSE3(_TEMP_OUTPUT)
81+
detect_target_SIMD_instruction_set_AVX2(_TEMP_OUTPUT)
82+
elseif(_TARGET_ARCH MATCHES arm)
83+
# add neon detection
84+
endif()
85+
set(${OUTPUT_VARIABLE} ${_TEMP_OUTPUT} PARENT_SCOPE)
86+
endfunction(detect_target_SIMD_instruction_set)

cmake/base64-config.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake")

lib/codec_choose.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
#include "../include/libbase64.h"
77
#include "codecs.h"
8+
#ifndef CMD_DEFINED_CONFIG
89
#include "config.h"
10+
#endif
911

1012
#if __x86_64__ || __i386__ || _M_X86 || _M_X64
1113
#ifdef _MSC_VER

test/CMakeLists.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Written in 2016 by Henrik Steffen Gaßmann [email protected]
2+
#
3+
# To the extent possible under law, the author(s) have dedicated all
4+
# copyright and related and neighboring rights to this software to the
5+
# public domain worldwide. This software is distributed without any warranty.
6+
#
7+
# You should have received a copy of the CC0 Public Domain Dedication
8+
# along with this software. If not, see
9+
#
10+
# http://creativecommons.org/publicdomain/zero/1.0/
11+
#
12+
########################################################################
13+
14+
function(add_base64_test TEST_NAME)
15+
unset(SRC_FILE)
16+
foreach(SRC_FILE ${ARGN})
17+
list(APPEND SRC_FILES "${SRC_FILE}")
18+
endforeach()
19+
20+
add_executable(${TEST_NAME} ${SRC_FILES})
21+
target_link_libraries(${TEST_NAME} base64)
22+
23+
add_test(NAME ${TEST_NAME}
24+
COMMAND ${TEST_NAME}
25+
)
26+
endfunction()
27+
28+
29+
add_base64_test(test_base64
30+
codec_supported.c
31+
test_base64.c
32+
)
33+
34+
add_base64_test(benchmark
35+
codec_supported.c
36+
benchmark.c
37+
)

0 commit comments

Comments
 (0)