-
Notifications
You must be signed in to change notification settings - Fork 2
/
CMakeLists.txt
198 lines (171 loc) · 11.3 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
cmake_minimum_required(VERSION 2.8)
project(endianness C)
option(ENDIANNESS_FORCE_NON_SYSTEM_IMPLEMENTATION OFF)
option(ENDIANNESS_EXPOSE_TEST_APPLICATION OFF)
include_directories("${PROJECT_SOURCE_DIR}")
include_directories("${PROJECT_BINARY_DIR}")
# Import the CHECK_INCLUDE_FILES macros
include(CheckIncludeFiles)
# Test for available headers, etc
CHECK_INCLUDE_FILES("inttypes.h" ENDIANNESS_CONFIG_HAVE_INTTYPES_H)
CHECK_INCLUDE_FILES("features.h" ENDIANNESS_CONFIG_HAVE_FEATURES_H)
CHECK_INCLUDE_FILES("endian.h" ENDIANNESS_CONFIG_HAVE_ENDIAN_H)
CHECK_INCLUDE_FILES("sys/endian.h" ENDIANNESS_CONFIG_HAVE_SYS_ENDIAN_H)
CHECK_INCLUDE_FILES("sys/param.h" ENDIANNESS_CONFIG_HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILES("libkern/OSByteOrder.h" ENDIANNESS_CONFIG_HAVE_LIBKERN_OSBYTEORDER_H)
CHECK_INCLUDE_FILES("arpa/inet.h" ENDIANNESS_CONFIG_HAVE_ARPA_INET_H)
CHECK_INCLUDE_FILES("netinet/in.h" ENDIANNESS_CONFIG_HAVE_NETINET_IN_H)
CHECK_INCLUDE_FILES("winsock2.h" ENDIANNESS_CONFIG_HAVE_WINSOCK2_H)
SET(ENDIANNESS_LINK_LIBRARIES "")
if (ENDIANNESS_FORCE_NON_SYSTEM_IMPLEMENTATION)
SET(ENDIANNESS_CONFIG_FORCE_NON_SYSTEM_IMPLEMENTATION ON)
message(STATUS "Forcing custom non-system implementation of endian conversion methods. Expect bad performance.")
else()
message(STATUS "Trying to use system implementation of endian conversion methods if available.")
# Specify necessary libraries that need to be linked
if (MSVC)
SET(ENDIANNESS_LINK_LIBRARIES "ws2_32")
endif()
endif(ENDIANNESS_FORCE_NON_SYSTEM_IMPLEMENTATION)
# Add ENDIANNESS_CONFIG_TESTCOMPILE_HAVE_INTTYPES_H definition for tests
SET(CONFIG_TEST_DEFINITIONS "")
SET(AATOBBNN_TEST_DEFINITIONS "")
SET(ATOBX_TEST_DEFINITIONS "")
if (ENDIANNESS_CONFIG_HAVE_INTTYPES_H)
add_definitions(-DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_INTTYPES_H)
SET(CONFIG_TEST_DEFINITIONS "${CONFIG_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_INTTYPES_H")
SET(AATOBBNN_TEST_DEFINITIONS "${AATOBBNN_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_INTTYPES_H")
SET(ATOBX_TEST_DEFINITIONS "${ATOBX_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_INTTYPES_H")
endif(ENDIANNESS_CONFIG_HAVE_INTTYPES_H)
# Add ENDIANNESS_CONFIG_TESTCOMPILE_HAVE_* definitions for cmake_aatobbnn_test.c
if (ENDIANNESS_CONFIG_HAVE_ENDIAN_H)
SET(AATOBBNN_TEST_DEFINITIONS "${AATOBBNN_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_ENDIAN_H")
endif(ENDIANNESS_CONFIG_HAVE_ENDIAN_H)
if (ENDIANNESS_CONFIG_HAVE_SYS_ENDIAN_H)
SET(AATOBBNN_TEST_DEFINITIONS "${AATOBBNN_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_SYS_ENDIAN_H")
endif(ENDIANNESS_CONFIG_HAVE_SYS_ENDIAN_H)
# Add ENDIANNESS_CONFIG_TESTCOMPILE_HAVE_* definitions for cmake_aatobbnn_test.c
if (ENDIANNESS_CONFIG_HAVE_WINSOCK2_H)
SET(ATOBX_TEST_DEFINITIONS "${ATOBX_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_WINSOCK2_H")
endif(ENDIANNESS_CONFIG_HAVE_WINSOCK2_H)
if (ENDIANNESS_CONFIG_HAVE_ARPA_INET_H)
SET(ATOBX_TEST_DEFINITIONS "${ATOBX_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_ARPA_INET_H")
endif(ENDIANNESS_CONFIG_HAVE_ARPA_INET_H)
if (ENDIANNESS_CONFIG_HAVE_NETINET_IN_H)
SET(ATOBX_TEST_DEFINITIONS "${ATOBX_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_HAVE_NETINET_IN_H")
endif(ENDIANNESS_CONFIG_HAVE_NETINET_IN_H)
# Check for %zu support
if (NOT DEFINED ENDIANNESS_ZUSUPPORT_TEST_RUN_RESULT)
try_run(ENDIANNESS_ZUSUPPORT_TEST_RUN_RESULT ENDIANNESS_ZUSUPPORT_TEST_COMPILE_RESULT "${PROJECT_BINARY_DIR}/testZuSupport" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_printf_zu_test.c" COMPILE_OUTPUT_VARIABLE ENDIANNESS_ZUSUPPORT_TEST_COMPILE_OUTPUT RUN_OUTPUT_VARIABLE ENDIANNESS_ZUSUPPORT_TEST_RUN_OUTPUT)
if ("${ENDIANNESS_ZUSUPPORT_TEST_RUN_OUTPUT}" EQUAL "1234")
message(STATUS "Compiler has %zu support.")
else()
message(STATUS "Compiler has NO %zu support, result was ${ENDIANNESS_ZUSUPPORT_TEST_RUN_OUTPUT} instead of 1234.")
endif()
endif()
if (NOT "${ENDIANNESS_ZUSUPPORT_TEST_RUN_OUTPUT}" EQUAL "1234")
SET(CONFIG_TEST_DEFINITIONS "${CONFIG_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_NO_ZU_SUPPORT")
endif()
SET(ENDIANNESS_OLD_C_FLAGS "${CMAKE_C_FLAGS}")
if(CMAKE_COMPILER_IS_GNUCC)
message(STATUS "Compiler: GNU CC")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-format -Werror=implicit -pedantic -Wno-unused-but-set-variable -std=gnu99")
elseif(MSVC)
message(STATUS "Compiler: MSVC")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall /we4013 /wd4100 /wd4820")
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
message(STATUS "Compiler: Clang")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -pedantic")
else()
message(STATUS "Compiler: Unknown with COMPILER_ID = ${CMAKE_C_COMPILER_ID}")
endif()
# Function for cached try_compile
macro(cache_try_compile RESULT_VAR)
if (NOT DEFINED "${RESULT_VAR}")
try_compile("${RESULT_VAR}" ${ARGN})
endif()
endmacro(cache_try_compile)
# Test for leNNtoh vs. letohNN
cache_try_compile(ENDIANNESS_AATOBBNN_TEST_RESULT_NON_OPENBSD "${PROJECT_BINARY_DIR}/compileTestNonOpenBsd" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_aatobbnn_test.c" COMPILE_DEFINITIONS "${AATOBBNN_TEST_DEFINITIONS}" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}" OUTPUT_VARIABLE ENDIANNESS_AATOBBNN_TEST_COMPILE_OUTPUT_NON_OPENBSD)
cache_try_compile(ENDIANNESS_AATOBBNN_TEST_RESULT_OPENBSD "${PROJECT_BINARY_DIR}/compileTestOpenBsd" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_aatobbnn_test.c" COMPILE_DEFINITIONS "${AATOBBNN_TEST_DEFINITIONS} -DENDIANNESS_CONFIG_TESTCOMPILE_TRY_OPENBSD_SYNTAX" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}" OUTPUT_VARIABLE ENDIANNESS_AATOBBNN_TEST_COMPILE_OUTPUT_OPENBSD)
if (ENDIANNESS_AATOBBNN_TEST_RESULT_NON_OPENBSD)
message(STATUS "Detected Non-OpenBSD Style Unix leNNtoh functions.")
SET(ENDIANNESS_CONFIG_HAVE_NON_OPENBSD_STYLE_ENDIAN_FUNCTIONS ON)
else()
message(STATUS "Did not detect Non-OpenBSD Style Unix leNNtoh functions.")
endif(ENDIANNESS_AATOBBNN_TEST_RESULT_NON_OPENBSD)
if (ENDIANNESS_AATOBBNN_TEST_RESULT_OPENBSD)
message(STATUS "Detected OpenBSD Style Unix letohNN functions.")
SET(ENDIANNESS_CONFIG_HAVE_OPENBSD_STYLE_ENDIAN_FUNCTIONS ON)
else()
message(STATUS "Did not detect OpenBSD Style Unix letohNN functions.")
endif(ENDIANNESS_AATOBBNN_TEST_RESULT_OPENBSD)
# Test builtin Byteswap
cache_try_compile(ENDIANNESS_BUILTIN_BYTESWAP_TEST_RESULT_NON_MSVC "${PROJECT_BINARY_DIR}/compileTestBuiltinByteswapNonMsvc" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_builtin_bswap_test.c" COMPILE_DEFINITIONS "" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}")
cache_try_compile(ENDIANNESS_BUILTIN_BYTESWAP_TEST_RESULT_MSVC "${PROJECT_BINARY_DIR}/compileTestBuiltinByteswapMsvc" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_builtin_bswap_test.c" COMPILE_DEFINITIONS "-DENDIANNESS_CONFIG_TESTCOMPILE_TRY_MSVC_SYNTAX" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}")
if (ENDIANNESS_BUILTIN_BYTESWAP_TEST_RESULT_NON_MSVC)
message(STATUS "Detected GCC Style __builtin_bswap functions.")
SET(ENDIANNESS_CONFIG_HAVE_GCC_STYLE_BSWAP_FUNCTIONS ON)
endif(ENDIANNESS_BUILTIN_BYTESWAP_TEST_RESULT_NON_MSVC)
if (ENDIANNESS_BUILTIN_BYTESWAP_TEST_RESULT_MSVC)
message(STATUS "Detected MSVC Style _byteswap functions.")
SET(ENDIANNESS_CONFIG_HAVE_MSVC_STYLE_BSWAP_FUNCTIONS ON)
endif(ENDIANNESS_BUILTIN_BYTESWAP_TEST_RESULT_MSVC)
# Test for htons, htonl, htonll, etc
cache_try_compile(ENDIANNESS_HTONS_TEST_RESULT "${PROJECT_BINARY_DIR}/compileTestHtons" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_atobs_test.c" COMPILE_DEFINITIONS "${ATOBX_TEST_DEFINITIONS}" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}")
cache_try_compile(ENDIANNESS_HTONL_TEST_RESULT "${PROJECT_BINARY_DIR}/compileTestHtonl" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_atobl_test.c" COMPILE_DEFINITIONS "${ATOBX_TEST_DEFINITIONS}" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}")
cache_try_compile(ENDIANNESS_HTONLL_TEST_RESULT "${PROJECT_BINARY_DIR}/compileTestHtonll" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_atobll_test.c" COMPILE_DEFINITIONS "${ATOBX_TEST_DEFINITIONS}" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}")
if (ENDIANNESS_HTONS_TEST_RESULT)
message(STATUS "Detected 16bit hton/ntoh functions.")
SET(ENDIANNESS_CONFIG_HAVE_HTONS_FUNCTIONS ON)
endif(ENDIANNESS_HTONS_TEST_RESULT)
if (ENDIANNESS_HTONL_TEST_RESULT)
message(STATUS "Detected 32bit htonl/ntohl functions.")
SET(ENDIANNESS_CONFIG_HAVE_HTONL_FUNCTIONS ON)
endif(ENDIANNESS_HTONL_TEST_RESULT)
if (ENDIANNESS_HTONLL_TEST_RESULT)
message(STATUS "Detected 64bit htonll/ntohll functions.")
SET(ENDIANNESS_CONFIG_HAVE_HTONLL_FUNCTIONS ON)
endif(ENDIANNESS_HTONLL_TEST_RESULT)
# Test local endianness
try_run(ENDIANNESS_CONFIG_TEST_RUN_RESULT ENDIANNESS_CONFIG_TEST_COMPILE_RESULT "${PROJECT_BINARY_DIR}/testConfig" "${CMAKE_CURRENT_SOURCE_DIR}/test/cmake_endian_test.c" COMPILE_DEFINITIONS "${CONFIG_TEST_DEFINITIONS}" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}" COMPILE_OUTPUT_VARIABLE ENDIANNESS_CONFIG_TEST_COMPILE_OUTPUT RUN_OUTPUT_VARIABLE ENDIANNESS_CONFIG_TEST_RUN_OUTPUT)
if (NOT ${ENDIANNESS_CONFIG_TEST_COMPILE_RESULT})
message(FATAL_ERROR "Failed to compile endianness testing program, please contact a developer! Extended Information: ${ENDIANNESS_CONFIG_TEST_COMPILE_OUTPUT}")
elseif(${ENDIANNESS_CONFIG_TEST_RUN_RESULT} GREATER 0)
message(FATAL_ERROR "Failed to run endianness testing program, please contact a developer! Extended Information: ${ENDIANNESS_CONFIG_TEST_RUN_OUTPUT}")
else()
message(STATUS "Collected endianness information...")
endif()
#message(STATUS "Result: ${ENDIANNESS_CONFIG_TEST_RUN_RESULT}")
#message(STATUS " - ")
#message(STATUS "Compile Result: ${ENDIANNESS_CONFIG_TEST_COMPILE_RESULT}")
#message(STATUS " - ")
#message(STATUS "Compile Output: ${ENDIANNESS_CONFIG_TEST_COMPILE_OUTPUT}")
#message(STATUS " - ")
#message(STATUS "Run Output: ${ENDIANNESS_CONFIG_TEST_RUN_OUTPUT}")
# Configure a header file to pass some of the CMake settings to the source code
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/endianness_config.h.in"
"${PROJECT_BINARY_DIR}/endianness_config.h"
)
# Add the binary dir directory
include_directories("${PROJECT_BINARY_DIR}")
try_run(ENDIANNESS_SIMPLE_CONFIG_TEST_RUN_RESULT ENDIANNESS_SIMPLE_CONFIG_TEST_COMPILE_RESULT "${PROJECT_BINARY_DIR}/testSimpleConfigTest" "${CMAKE_CURRENT_SOURCE_DIR}/test/simple_test.c" CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${PROJECT_BINARY_DIR}" LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}" COMPILE_OUTPUT_VARIABLE ENDIANNESS_SIMPLE_CONFIG_TEST_COMPILE_OUTPUT RUN_OUTPUT_VARIABLE ENDIANNESS_SIMPLE_CONFIG_TEST_RUN_OUTPUT)
if (NOT ENDIANNESS_SIMPLE_CONFIG_TEST_RUN_RESULT)
message(FATAL_ERROR "Testing the generated portable endian config file failed: ${ENDIANNESS_SIMPLE_CONFIG_TEST_COMPILE_OUTPUT} ${ENDIANNESS_SIMPLE_CONFIG_TEST_RUN_OUTPUT}")
elseif(NOT "${ENDIANNESS_SIMPLE_CONFIG_TEST_RUN_RESULT}" EQUAL "1")
message(FATAL_ERROR "Testing the generated portable endian config file failed: ${ENDIANNESS_SIMPLE_CONFIG_TEST_RUN_OUTPUT}")
else()
message(STATUS "Success! The generated portable endian config file seems to work!")
endif()
if (ENDIANNESS_EXPOSE_TEST_APPLICATION)
add_executable(endianness-simple-test "${CMAKE_CURRENT_SOURCE_DIR}/test/simple_test.c")
target_link_libraries(endianness-simple-test "${ENDIANNESS_LINK_LIBRARIES}")
endif()
# Restore C flags for other projects
SET(CMAKE_C_FLAGS "${ENDIANNESS_OLD_C_FLAGS}")
# Export necessary Libraries
SET(ENDIANNESS_LINK_LIBRARIES "${ENDIANNESS_LINK_LIBRARIES}" PARENT_SCOPE)
if (NOT ${ENDIANNESS_LINK_LIBRARIES} EQUAL "")
message(STATUS "Programs need to be linked with ${ENDIANNESS_LINK_LIBRARIES}")
endif()