Skip to content

Commit

Permalink
ADD CMake PROJECT FILES
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
BurningEnlightenment committed Feb 23, 2016
1 parent 42aca68 commit e12e3cd
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 0 deletions.
162 changes: 162 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Written in 2016 by Henrik Steffen Gaßmann [email protected]
#
# 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/$<CONFIG>
LIBRARY DESTINATION lib/$<CONFIG>
ARCHIVE DESTINATION lib/$<CONFIG>
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()
4 changes: 4 additions & 0 deletions cmake/Modules/TargetArch.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

macro(target_architecture OUTPUT_VARIABLE)
message(FATAL_ERROR "the target_architecture macro has not been implemented")
endmacro()
86 changes: 86 additions & 0 deletions cmake/Modules/TargetSIMDInstructionSet.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Written in 2016 by Henrik Steffen Gaßmann [email protected]
#
# 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)
1 change: 1 addition & 0 deletions cmake/base64-config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/base64-targets.cmake")
2 changes: 2 additions & 0 deletions lib/codec_choose.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
37 changes: 37 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Written in 2016 by Henrik Steffen Gaßmann [email protected]
#
# 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
)

0 comments on commit e12e3cd

Please sign in to comment.