summaryrefslogtreecommitdiffstats
path: root/CMakeLists.txt
blob: cc8bfb74f7a3982c34cee7ad5e347afc0015530e (plain) (blame)
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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
################################################################################
# GENERAL                                                                      #
################################################################################

PROJECT(dnbd3 C)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12)
IF (CMAKE_BUILD_TYPE STREQUAL "")
	SET(CMAKE_BUILD_TYPE Debug)
ENDIF()

SET(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Path prefix for system installation")
OPTION(BUILD_FUSE_CLIENT "Build dnbd3 fuse client" ON)
OPTION(BUILD_SERVER "Build dnbd3 server" ON)
OPTION(BUILD_STRESSTEST "Build dnbd3 stress testing tool" OFF)
SET(EXTRA_C_FLAGS "" CACHE STRING "Additional options to pass to compiler")

OPTION(SERVER_FOR_AFL "Build dnbd3-server for usage with afl-fuzz" OFF)

# Is there a non-retarded way to check if build type is debug or release?
# When specifying, it is case insensitive, so DeBuG would also enable debug builds,
# but in cmake, we can only do case sensitive matches... :/
string( TOLOWER "${CMAKE_BUILD_TYPE}" bt_lower )
if (NOT bt_lower MATCHES "^(debug|release)$")
	message( FATAL_ERROR "Build type needs to be either Debug or Release" )
endif()

message( "Build Type selected: ${CMAKE_BUILD_TYPE}" )

IF(CMAKE_SYSTEM_NAME MATCHES "BSD")
	message("Detected *BSD System: disable build of Kernel Module.")
	SET(BUILD_KERNEL_MODULE False)
ELSE()
	OPTION(BUILD_KERNEL_MODULE "Build the dnbd3 Linux kernel module" ON)
ENDIF()

INCLUDE(CheckCCompilerFlag)
macro (TRY_ADD_FLAG _FLAG)
	UNSET(TMP_TEST CACHE)
	CHECK_C_COMPILER_FLAG("${_FLAG}" TMP_TEST)
	if (TMP_TEST)
		message(":-) Compiler supports ${_FLAG}")
		SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_FLAG}")
	else()
		message(":-( Compiler does not support ${_FLAG}")
	endif()

endmacro()

# Common for gcc and clang
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,-z,relro,-z,now,-z,defs -pie")
SET(CMAKE_C_FLAGS "-fPIE -std=c11 -Wno-multichar -fno-strict-aliasing -D_GNU_SOURCE -D_FORTIFY_SOURCE=2 ${EXTRA_C_FLAGS}")
SET(CMAKE_C_FLAGS_RELEASE " -O3 -Wno-unused-result -DNDEBUG")
# Hardening. Try as much as is possible.
TRY_ADD_FLAG("-mmitigate-rop")
TRY_ADD_FLAG("-fstack-protector-strong")
TRY_ADD_FLAG("-fstack-clash-protection")
TRY_ADD_FLAG("-Wformat")
TRY_ADD_FLAG("-Wformat-security")
TRY_ADD_FLAG("-Werror=format-security")
if(CMAKE_C_COMPILER MATCHES "clang")
	message( "Using clang flags." )
	SET(CMAKE_C_FLAGS_DEBUG " -O1 -fno-omit-frame-pointer -g -Wall -Wextra -Wpedantic -Wno-unused-result -D_DEBUG")
elseif (CMAKE_C_COMPILER MATCHES "(cc-)|(cc$)")
	message( "Using (g)cc flags." )
	SET(CMAKE_C_FLAGS_DEBUG " -O0 -g -Wall -Wextra -Wpedantic -Wconversion -Wno-sign-conversion -D_DEBUG")
else()
	message( FATAL_ERROR "Could not determine compiler type." )
endif()

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")

ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
ADD_DEFINITIONS(-DWITH_IPV6)

FIND_PACKAGE(Threads)

SET(DO_ABORT False)

message( " *************************************************" )
if(BUILD_FUSE_CLIENT)
	FIND_PACKAGE(Fuse)
	if(NOT FUSE_FOUND)
		message( " *** No fuse dev libs found, can't build dnbd3-fuse" )
		SET(DO_ABORT True)
	endif()
	if(NOT THREADS_FOUND)
		message( " *** No threads found, can't build dnbd3-fuse" )
		SET(DO_ABORT True)
	endif()
endif()
if(BUILD_SERVER)
	FIND_PACKAGE(Jansson)
	if(NOT THREADS_FOUND)
		message( " *** No threads found, can't build dnbd3-server" )
		SET(DO_ABORT True)
	endif()
	if(NOT JANSSON_FOUND)
		message( " *** No jansson lib found, can't build dnbd3-server" )
		SET(DO_ABORT True)
	endif()
endif()
if(BUILD_STRESSTEST)
	if(NOT THREADS_FOUND)
		message( " *** No threads found, can't build dnbd3-bench" )
		SET(DO_ABORT True)
	endif()
endif()
message( " *************************************************" )
if(DO_ABORT)
	message( FATAL_ERROR "Aborting." )
endif()

#SET(FUSE_INCLUDE_DIR "")
#SET(JANSSON_INCLUDE_DIR "")

################################################################################
# VERSION HEADER                                                               #
################################################################################

FILE(WRITE ${CMAKE_BINARY_DIR}/version.cmake
"EXECUTE_PROCESS(
	COMMAND \${CMD}
	OUTPUT_VARIABLE VERSION
	OUTPUT_STRIP_TRAILING_WHITESPACE
 )
 CONFIGURE_FILE(\${SRC} \${DST} @ONLY)
")
ADD_CUSTOM_TARGET(
	version
	${CMAKE_COMMAND} -D SRC=${CMAKE_SOURCE_DIR}/src/version.c.in
						-D DST=${CMAKE_BINARY_DIR}/generated/version.c
						-D CMD=${CMAKE_SOURCE_DIR}/get-version.sh
						-P ${CMAKE_BINARY_DIR}/version.cmake
)

INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR}/generated )

################################################################################
# CLIENT                                                                       #
################################################################################

if(BUILD_KERNEL_MODULE)
	FILE(GLOB_RECURSE CLIENT_SRCS src/client/*.c)
	ADD_EXECUTABLE(dnbd3-client ${CLIENT_SRCS})
	TARGET_LINK_LIBRARIES(dnbd3-client)
	ADD_DEPENDENCIES(dnbd3-client version)
	INSTALL(TARGETS dnbd3-client RUNTIME DESTINATION sbin)
ENDIF()


################################################################################
# SERVER                                                                       #
################################################################################

if(BUILD_SERVER)
	IF(SERVER_FOR_AFL)
		message(" ######################## Building server for AFL mode - will be useless otherwise!")
		ADD_DEFINITIONS(-DAFL_MODE)
	ENDIF()
	FILE(GLOB SERVER_SRCS src/server/*.c src/shared/*.c src/server/picohttpparser/*.c)
	ADD_EXECUTABLE(dnbd3-server ${SERVER_SRCS})
	TARGET_INCLUDE_DIRECTORIES(dnbd3-server PRIVATE ${JANSSON_INCLUDE_DIR})
	TARGET_LINK_LIBRARIES(dnbd3-server ${CMAKE_THREAD_LIBS_INIT} ${JANSSON_LIBRARIES})
	if(UNIX AND NOT APPLE)
		target_link_libraries(dnbd3-server rt)
	endif()
	ADD_DEPENDENCIES(dnbd3-server version)
	INSTALL(TARGETS dnbd3-server RUNTIME DESTINATION sbin)
endif()



################################################################################
# FUSE                                                                         #
################################################################################

if(BUILD_FUSE_CLIENT)
	FILE(GLOB FUSE_SRCS src/fuse/*.c src/shared/*.c)
	ADD_EXECUTABLE(dnbd3-fuse ${FUSE_SRCS})
	TARGET_INCLUDE_DIRECTORIES(dnbd3-fuse PRIVATE ${FUSE_INCLUDE_DIRS})
	TARGET_LINK_LIBRARIES(dnbd3-fuse ${CMAKE_THREAD_LIBS_INIT} ${FUSE_LIBRARIES})
	ADD_DEPENDENCIES(dnbd3-fuse version)
	INSTALL(TARGETS dnbd3-fuse RUNTIME DESTINATION bin)
endif()

################################################################################
# STRESSTEST                                                                   #
################################################################################

if(BUILD_STRESSTEST)
	FILE(GLOB BENCH_SRCS src/bench/*.c src/shared/*.c)
	ADD_EXECUTABLE(dnbd3-bench ${BENCH_SRCS})
	TARGET_LINK_LIBRARIES(dnbd3-bench ${CMAKE_THREAD_LIBS_INIT})
	ADD_DEPENDENCIES(dnbd3-bench version)
	INSTALL(TARGETS dnbd3-bench RUNTIME DESTINATION bin)
endif()

################################################################################
# MODULE                                                                       #
################################################################################

IF(BUILD_KERNEL_MODULE)
	SET(MODULE_NAME dnbd3)
	SET(MODULE_FILE ${MODULE_NAME}.ko)
	FILE(GLOB MODULE_SOURCE_FILES src/kernel/*.c src/serialize.c)
	FILE(GLOB MODULE_HEADER_FILES src/kernel/*.h)

	SET(KERNEL_DIR "" CACHE PATH "Path to kernel sources to compile against")
	IF(KERNEL_DIR STREQUAL "")
		SET(KERNEL_DIR "/lib/modules/${CMAKE_SYSTEM_VERSION}/build")
	ENDIF()

	SET(KBUILD_COMMAND ${CMAKE_MAKE_PROGRAM} -C ${KERNEL_DIR}
		M=${CMAKE_BINARY_DIR} modules
	)

	CONFIGURE_FILE(Kbuild.in ${CMAKE_BINARY_DIR}/Kbuild)

	FOREACH(MODULE_SOURCE_FILE ${MODULE_SOURCE_FILES})
		CONFIGURE_FILE(${MODULE_SOURCE_FILE} ${CMAKE_BINARY_DIR} COPYONLY)
	ENDFOREACH( MODULE_SOURCE_FILE )

	FOREACH(MODULE_HEADER_FILE ${MODULE_HEADER_FILES})
		CONFIGURE_FILE(${MODULE_HEADER_FILE} ${CMAKE_BINARY_DIR} COPYONLY)
	ENDFOREACH( MODULE_HEADER_FILE )

	ADD_CUSTOM_COMMAND(
		OUTPUT ${CMAKE_BINARY_DIR}/${MODULE_FILE}
		COMMAND ${KBUILD_COMMAND}
		WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
		DEPENDS ${MODULE_SOURCE_FILES} Kbuild.in
		VERBATIM
	)

	ADD_CUSTOM_TARGET(${MODULE_NAME} ALL DEPENDS ${CMAKE_BINARY_DIR}/${MODULE_FILE})

	INSTALL(FILES ${CMAKE_BINARY_DIR}/${MODULE_NAME}.ko
		DESTINATION /lib/modules/${CMAKE_SYSTEM_VERSION}/kernel/drivers/block
		PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
	)

	INSTALL(CODE "EXECUTE_PROCESS(COMMAND depmod -a)")
ENDIF()


#
# Other install files
#

FILE(GLOB conf_files "${CMAKE_CURRENT_SOURCE_DIR}/conf/*")
INSTALL(FILES ${conf_files} DESTINATION /etc/dnbd3-server/sample/)