diff CMakeLists.txt @ 23:e26874655738

*: huge refactor, new major release (hahaha) I keep finding things that are broken... The problem NOW was that vec would unintentionally build some functions with extended instruction sets, which is Bad and would mean that for all intents and purposes the CPU detection was completely broken. Now vec is no longer header only either. Boohoo. However this gives a lot more flexibility to vec since we no longer want or need to care about C++ crap. The NEON and Altivec implementations have not been updated which means they won't compile hence why they're commented out in the cmake build file.
author Paper <paper@tflc.us>
date Sun, 24 Nov 2024 02:52:40 -0500
parents 41dd962abdd1
children 92156fe32755
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Nov 23 04:09:44 2024 +0000
+++ b/CMakeLists.txt	Sun Nov 24 02:52:40 2024 -0500
@@ -1,49 +1,114 @@
 cmake_minimum_required(VERSION 3.23)
 
-project(vec VERSION 2.0.0 DESCRIPTION "a tiny C99 SIMD vector library")
-
-add_library(vec SHARED src/vec.c)
+project(vec VERSION 3.0.0 DESCRIPTION "a tiny C99 SIMD vector library")
 
-target_sources(vec PUBLIC
-	$<INSTALL_INTERFACE:vec/vec.h>
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/vec/vec.h>
-	$<INSTALL_INTERFACE:vec/impl/integer.h>
-	$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/vec/impl/integer.h>
-)
+add_library(vec SHARED "src/vec.c;src/cpu.c;src/impl/generic.c;src/impl/fallback.c")
 
 include(CheckCCompilerFlag)
 
 if(MSVC)
-	# TODO ?
+	# Untested!
+
+	if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+		set(COMPILER_HAS_MMX OFF)
+	else()
+		set(COMPILER_HAS_MMX ON)
+		set(COMPILER_MMX_FLAGS "") # none?
+	endif()
+	check_c_compiler_flag("/arch:SSE2" COMPILER_HAS_SSE2)
+	if(COMPILER_HAS_SSE2)
+		set(COMPILER_SSE2_FLAGS "/arch:SSE2")
+	endif()
+	check_c_compiler_flag("/arch:SSE4.2" COMPILER_HAS_SSE41)
+	if(COMPILER_HAS_SSE41)
+		set(COMPILER_SSE41_FLAGS "/arch:SSE4.2")
+	endif()
+	check_c_compiler_flag("/arch:AVX2" COMPILER_HAS_AVX2)
+	if(COMPILER_HAS_AVX2)
+		set(COMPILER_AVX2_FLAGS "/arch:AVX2")
+	endif()
+	check_c_compiler_flag("/arch:AVX512" COMPILER_HAS_AVX512F)
+	if(COMPILER_HAS_AVX512F)
+		set(COMPILER_AVX512F_FLAGS "/arch:AVX512")
+	endif()
+	# TODO we have to try_compile to detect NEON
 else()
-	check_c_compiler_flag("-maltivec" COMPILER_HAS_ALTIVEC)
-	if(COMPILER_HAS_ALTIVEC)
-		target_compile_options(vec PRIVATE "-maltivec")
-	endif()
+	#check_c_compiler_flag("-maltivec" COMPILER_HAS_ALTIVEC)
+	#if(COMPILER_HAS_ALTIVEC)
+	#	set(COMPILER_ALTIVEC_FLAGS "-maltivec")
+	#endif()
+	#check_c_compiler_flag("-mfpu=neon" COMPILER_HAS_NEON)
+	#if(COMPILER_HAS_NEON)
+	#	set(COMPILER_NEON_FLAGS "-mfpu=neon")
+	#endif()
 	check_c_compiler_flag("-mmmx" COMPILER_HAS_MMX)
 	if(COMPILER_HAS_MMX)
-		target_compile_options(vec PRIVATE "-mmmx")
+		set(COMPILER_MMX_FLAGS "-mmmx")
 	endif()
 	check_c_compiler_flag("-msse2" COMPILER_HAS_SSE2)
 	if(COMPILER_HAS_SSE2)
-		target_compile_options(vec PRIVATE "-msse2")
+		set(COMPILER_SSE2_FLAGS "-msse2")
 	endif()
 	check_c_compiler_flag("-msse4.1" COMPILER_HAS_SSE41)
 	if(COMPILER_HAS_SSE41)
-		target_compile_options(vec PRIVATE "-msse4.1")
+		set(COMPILER_SSE41_FLAGS "-msse4.1")
 	endif()
 	check_c_compiler_flag("-mavx2" COMPILER_HAS_AVX2)
 	if(COMPILER_HAS_AVX2)
-		target_compile_options(vec PRIVATE "-mavx2")
+		set(COMPILER_AVX2_FLAGS "-mavx2")
 	endif()
 	check_c_compiler_flag("-mavx512f" COMPILER_HAS_AVX512F)
 	if(COMPILER_HAS_AVX512F)
-		target_compile_options(vec PRIVATE "-mavx512f")
+		set(COMPILER_AVX512F_FLAGS "-mavx512f")
 	endif()
 endif()
 
+if(COMPILER_HAS_ALTIVEC)
+	target_sources(vec PRIVATE "src/impl/ppc/altivec.c")
+	set_source_files_properties("src/impl/ppc/altivec.c" PROPERTIES COMPILE_FLAGS "${COMPILER_ALTIVEC_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_ALTIVEC")
+endif()
+
+if(COMPILER_HAS_NEON)
+	target_sources(vec PRIVATE "src/impl/arm/neon.c")
+	set_source_files_properties("src/impl/arm/neon.c" PROPERTIES COMPILE_FLAGS "${COMPILER_NEON_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_NEON")
+endif()
+
+if(COMPILER_HAS_MMX)
+	target_sources(vec PRIVATE "src/impl/x86/mmx.c")
+	set_source_files_properties("src/impl/x86/mmx.c" PROPERTIES COMPILE_FLAGS "${COMPILER_MMX_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_MMX")
+endif()
+
+if(COMPILER_HAS_SSE2)
+	target_sources(vec PRIVATE "src/impl/x86/sse2.c")
+	set_source_files_properties("src/impl/x86/sse2.c" PROPERTIES COMPILE_FLAGS "${COMPILER_SSE2_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_SSE2")
+endif()
+
+if(COMPILER_HAS_SSE41)
+	target_sources(vec PRIVATE "src/impl/x86/sse41.c")
+	set_source_files_properties("src/impl/x86/sse41.c" PROPERTIES COMPILE_FLAGS "${COMPILER_SSE41_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_SSE41")
+endif()
+
+if(COMPILER_HAS_AVX2)
+	target_sources(vec PRIVATE "src/impl/x86/avx2.c")
+	set_source_files_properties("src/impl/x86/avx2.c" PROPERTIES COMPILE_FLAGS "${COMPILER_AVX2_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_AVX2")
+endif()
+
+if(COMPILER_HAS_AVX512F)
+	target_sources(vec PRIVATE "src/impl/x86/avx512f.c")
+	set_source_files_properties("src/impl/x86/avx512f.c" PROPERTIES COMPILE_FLAGS "${COMPILER_AVX512F_FLAGS}")
+	target_compile_definitions(vec PRIVATE "-DVEC_COMPILER_HAS_AVX512F")
+endif()
+
+
 #########################################################################
-# integer types
+# integer types; it's nice to accommodate for older broken systems that
+# may not have stdint.h.
 
 include(CheckTypeSize)
 
@@ -61,6 +126,7 @@
 check_type_size("long"      LONG_SIZE      LANGUAGE C)
 check_type_size("long long" LONG_LONG_SIZE LANGUAGE C)
 check_type_size("uintptr_t" UINTPTR_T_SIZE LANGUAGE C)
+check_type_size("size_t"    SIZE_T_SIZE LANGUAGE C)
 
 if(INT16_T_SIZE EQUAL 2)
 	set(SIZE16 "int16_t")
@@ -68,6 +134,8 @@
 	set(SIZE16 "short")
 elseif(INT_SIZE EQUAL 2)
 	set(SIZE16 "int")
+else()
+	message(FATAL_ERROR "Failed to find a signed 16-bit integer type.")
 endif()
 
 if(UINT16_T_SIZE EQUAL 2)
@@ -78,6 +146,8 @@
 	set(USIZE16 "unsigned short")
 elseif(INT_SIZE EQUAL 2)
 	set(USIZE16 "unsigned int")
+else()
+	message(FATAL_ERROR "Failed to find an unsigned 16-bit integer type.")
 endif()
 
 if(INT32_T_SIZE EQUAL 4)
@@ -88,6 +158,8 @@
 	set(SIZE32 "int")
 elseif(LONG_SIZE EQUAL 4)
 	set(SIZE32 "long")
+else()
+	message(FATAL_ERROR "Failed to find a signed 32-bit integer type.")
 endif()
 
 if(UINT32_T_SIZE EQUAL 4)
@@ -100,6 +172,8 @@
 	set(USIZE32 "unsigned int")
 elseif(LONG_SIZE EQUAL 4)
 	set(USIZE32 "unsigned long")
+else()
+	message(FATAL_ERROR "Failed to find an unsigned 32-bit integer type.")
 endif()
 
 if(INT64_T_SIZE EQUAL 8)
@@ -112,6 +186,8 @@
 	set(SIZE64 "long")
 elseif(LONG_LONG_SIZE EQUAL 8)
 	set(SIZE64 "long long")
+else()
+	message(FATAL_ERROR "Failed to find a signed 64-bit integer type.")
 endif()
 
 if(UINT64_T_SIZE EQUAL 8)
@@ -126,28 +202,46 @@
 	set(USIZE64 "unsigned long")
 elseif(LONG_LONG_SIZE EQUAL 8)
 	set(USIZE64 "unsigned long long")
+else()
+	message(FATAL_ERROR "Failed to find an unsigned 64-bit integer type.")
 endif()
 
 if(CMAKE_SIZEOF_VOID_P EQUAL UINTPTR_T_SIZE)
 	set(USIZEPTR "uintptr_t")
-elseif(CMAKE_SIZEOF_VOID_P EQUAL 1)
+elseif(CMAKE_SIZEOF_VOID_P LESS_EQUAL 1)
 	set(USIZEPTR "unsigned char")
-elseif(CMAKE_SIZEOF_VOID_P EQUAL 2)
+elseif(CMAKE_SIZEOF_VOID_P LESS_EQUAL 2)
 	set(USIZEPTR "${USIZE16}")
-elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+elseif(CMAKE_SIZEOF_VOID_P LESS_EQUAL 4)
 	set(USIZEPTR "${USIZE32}")
-elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+elseif(CMAKE_SIZEOF_VOID_P LESS_EQUAL 8)
 	set(USIZEPTR "${USIZE64}")
+else()
+	message(FATAL_ERROR "Failed to find an integer type that can fit a pointer.")
 endif()
 
-configure_file(include/vec/impl/integer.h.in include/vec/impl/integer.h @ONLY)
+if(NOT SIZE_T_SIZE EQUAL 0 AND NOT SIZE_T_SIZE EQUAL "")
+	set(USIZESIZE "size_t")
+else()
+	# should be close enough I guess
+	set(USIZESIZE "${USIZEPTR}")
+endif()
 
-target_compile_definitions(vec PRIVATE "VEC_HAVE_IMPL_INTEGER_H")
+configure_file(include/vec/types.h.in include/vec/types.h @ONLY)
 
 #########################################################################
 
+target_sources(vec PUBLIC
+	$<INSTALL_INTERFACE:vec/vec.h>
+	$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/vec/vec.h>
+	$<INSTALL_INTERFACE:vec/types.h>
+	$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include/vec/types.h>
+	$<INSTALL_INTERFACE:vec/cpu.h>
+	$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include/vec/cpu.h>
+)
+
 target_compile_features(vec PRIVATE $<IF:$<COMPILE_FEATURES:c_std_11>,c_std_11,c_std_99>)
-target_include_directories(vec PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_BINARY_DIR}/include/vec")
+target_include_directories(vec PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_CURRENT_BINARY_DIR}/include")
 
 # Installing