Skip to content

Commit ee4ca95

Browse files
committed
Add cmakelists
1 parent 85958a3 commit ee4ca95

4 files changed

Lines changed: 377 additions & 0 deletions

File tree

.github/workflows/cmake.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: CMake Build
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
build:
11+
strategy:
12+
fail-fast: false
13+
matrix:
14+
runs-on: [ubuntu-latest, macos-latest]
15+
runs-on: ${{ matrix.runs-on }}
16+
steps:
17+
- uses: actions/checkout@v3
18+
with:
19+
submodules: recursive
20+
fetch-depth: 0
21+
- uses: lukka/get-cmake@latest
22+
with:
23+
cmakeVersion: latest
24+
ninjaVersion: latest
25+
26+
- name: Build Summary ${{ matrix.targets }}
27+
run: cmake -B build -DCMAKE_BUILD_TYPE=Release; cmake --build build --parallel

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
tmp/*
33
.DS_Store
44
*.pem
5+
6+
build/

CMakeLists.txt

Lines changed: 338 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
cmake_minimum_required(VERSION 3.12)
2+
3+
project(facil.io VERSION 0.8.0)
4+
5+
# Set the source directories
6+
set(LIB_ROOT lib)
7+
set(LIB_CONCAT_FOLDER fio-stl)
8+
9+
include_directories(".")
10+
11+
option(ENABLE_SHARED "Build facil.io as shared library" OFF)
12+
option(EXAMPLES_BUILD "Build Examples" ON)
13+
option(TESTS_BUILD "Build Tests" ON)
14+
15+
# Detect endianess
16+
include(CheckTypeSize)
17+
check_type_size("void*" SIZE_OF_POINTER)
18+
if(${SIZE_OF_POINTER} EQUAL 8)
19+
set(FLAGS "__BIG_ENDIAN__")
20+
else()
21+
set(FLAGS "__BIG_ENDIAN__=0")
22+
endif()
23+
24+
find_package(Threads REQUIRED)
25+
# Detect SSL/TLS Libraries
26+
find_package(OpenSSL 3.0)
27+
28+
if(OpenSSL_FOUND)
29+
message(STATUS "OpenSSL found.")
30+
else()
31+
message(WARNING "OpenSSL not found. SSL/TLS support will be disabled.")
32+
endif()
33+
34+
# Detect Sodium Library
35+
find_package(Sodium)
36+
37+
if(Sodium_FOUND)
38+
message(STATUS "Sodium found.")
39+
else()
40+
message(WARNING "Sodium not found. Sodium support will be disabled.")
41+
endif()
42+
43+
# Detect 'struct tm' fields
44+
include(CheckStructHasMember)
45+
check_struct_has_member("struct tm" tm_zone time.h HAVE_TM_TM_ZONE)
46+
47+
# Detect SystemV socket libraries
48+
include(CheckLibraryExists)
49+
check_library_exists(socket connect "" HAVE_SOCKET)
50+
check_library_exists(nsl gethostname "" HAVE_NSL)
51+
52+
if(HAVE_SOCKET AND HAVE_NSL)
53+
link_libraries(socket nsl)
54+
endif()
55+
if(WIN32)
56+
link_libraries(ws2_32)
57+
endif()
58+
59+
# Variable to track whether any of the checks have succeeded
60+
set(HAVE_SENDFILE FALSE)
61+
62+
# Detect the `sendfile` system call for Linux
63+
if(NOT HAVE_SENDFILE)
64+
include(CheckCSourceCompiles)
65+
check_c_source_compiles("
66+
#define _GNU_SOURCE
67+
#include <stdlib.h>
68+
#include <stdio.h>
69+
#include <sys/sendfile.h>
70+
int main(void) {
71+
off_t offset = 0;
72+
ssize_t result = sendfile(2, 1, (off_t *)&offset, 300);
73+
}
74+
" HAVE_SENDFILE_LINUX)
75+
76+
if(HAVE_SENDFILE_LINUX)
77+
set(FLAGS "${FLAGS} USE_SENDFILE_LINUX HAVE_SENDFILE")
78+
set(HAVE_SENDFILE TRUE)
79+
endif()
80+
endif()
81+
82+
# Detect the `sendfile` system call for BSD
83+
if(NOT HAVE_SENDFILE)
84+
check_c_source_compiles("
85+
#define _GNU_SOURCE
86+
#include <stdlib.h>
87+
#include <stdio.h>
88+
#include <sys/types.h>
89+
#include <sys/socket.h>
90+
#include <sys/uio.h>
91+
int main(void) {
92+
off_t sent = 0;
93+
off_t offset = 0;
94+
ssize_t result = sendfile(2, 1, offset, (size_t)sent, NULL, &sent, 0);
95+
}
96+
" HAVE_SENDFILE_BSD)
97+
98+
if(HAVE_SENDFILE_BSD)
99+
set(FLAGS "${FLAGS} USE_SENDFILE_BSD HAVE_SENDFILE")
100+
set(HAVE_SENDFILE TRUE)
101+
endif()
102+
endif()
103+
104+
# Detect the `sendfile` system call for Apple
105+
if(NOT HAVE_SENDFILE)
106+
check_c_source_compiles("
107+
#define _GNU_SOURCE
108+
#include <stdlib.h>
109+
#include <stdio.h>
110+
#include <sys/types.h>
111+
#include <sys/socket.h>
112+
#include <sys/uio.h>
113+
int main(void) {
114+
off_t sent = 0;
115+
off_t offset = 0;
116+
ssize_t result = sendfile(2, 1, offset, &sent, NULL, 0);
117+
}
118+
" HAVE_SENDFILE_APPLE)
119+
120+
if(HAVE_SENDFILE_APPLE)
121+
set(FLAGS "${FLAGS} USE_SENDFILE_APPLE HAVE_SENDFILE")
122+
set(HAVE_SENDFILE TRUE)
123+
endif()
124+
endif()
125+
126+
# Detect IOCP support for Windows
127+
if(WIN32)
128+
if(NOT HAVE_IOCP)
129+
check_c_source_compiles("
130+
#include <winsock2.h>
131+
#include <windows.h>
132+
int main(void) {
133+
HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
134+
if (iocp == NULL) {
135+
return 1;
136+
}
137+
CloseHandle(iocp);
138+
return 0;
139+
}
140+
" HAVE_IOCP)
141+
142+
if(HAVE_IOCP)
143+
set(FLAGS "${FLAGS} FIO_ENGINE_IOCP HAVE_IOCP")
144+
else()
145+
message(FATAL_ERROR "No supported polling engine detected. Unable to compile facil.io.")
146+
endif()
147+
endif()
148+
else()
149+
# Detect polling mechanisms (kqueue / epoll / poll)
150+
if(NOT HAVE_KQUEUE AND NOT HAVE_EPOLL AND NOT HAVE_POLL)
151+
check_c_source_compiles("
152+
#define _GNU_SOURCE
153+
#include <stdlib.h>
154+
#include <sys/event.h>
155+
int main(void) {
156+
int fd = kqueue();
157+
}
158+
" HAVE_KQUEUE)
159+
160+
if(HAVE_KQUEUE)
161+
set(FLAGS "${FLAGS} FIO_ENGINE_KQUEUE HAVE_KQUEUE")
162+
else()
163+
check_c_source_compiles("
164+
#define _GNU_SOURCE
165+
#include <stdlib.h>
166+
#include <stdio.h>
167+
#include <sys/types.h>
168+
#include <sys/stat.h>
169+
#include <fcntl.h>
170+
#include <sys/epoll.h>
171+
int main(void) {
172+
int fd = epoll_create1(EPOLL_CLOEXEC);
173+
}
174+
" HAVE_EPOLL)
175+
176+
if(HAVE_EPOLL)
177+
set(FLAGS "${FLAGS} FIO_ENGINE_EPOLL HAVE_EPOLL")
178+
else()
179+
check_c_source_compiles("
180+
#define _GNU_SOURCE
181+
#include <stdlib.h>
182+
#include <poll.h>
183+
int main(void) {
184+
struct pollfd plist[18];
185+
memset(plist, 0, sizeof(plist[0]) * 18);
186+
poll(plist, 1, 1);
187+
}
188+
" HAVE_POLL)
189+
190+
if(HAVE_POLL)
191+
set(FLAGS "${FLAGS} FIO_ENGINE_POLL HAVE_POLL")
192+
else()
193+
message(FATAL_ERROR "No supported polling engine detected. Unable to compile facil.io.")
194+
endif()
195+
endif()
196+
endif()
197+
endif()
198+
endif()
199+
200+
201+
# Define the source files for the library
202+
file(GLOB_RECURSE LIB_SOURCES ${LIB_ROOT}/*.c ${LIB_ROOT}/*.cpp ${LIB_ROOT}/*.cxx ${LIB_ROOT}/*.c++)
203+
set(SOURCES ${LIB_SOURCES})
204+
205+
# Optimization level
206+
set(OPTIMIZATION "-O3")
207+
# Optimization level in debug mode
208+
set(OPTIMIZATION_DEBUG "-O0 -g -coverage -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer -fno-builtin")
209+
# Warning flags
210+
set(WARNINGS "-Wno-missing-field-initializers -Wformat-security")
211+
# Preprocessor definitions
212+
set(FLAGS "-DFIO_LEAK_COUNTER -DFIO_FIOBJ -DFIOBJ_MALLOC")
213+
if(WIN32 AND NOT MSVC)
214+
set(FLAGS "${FLAGS} -D_GNU_SOURCE -D__MINGW32__")
215+
endif()
216+
# C specific compiler options
217+
set(C_EXTRA_OPT "")
218+
# C++ specific compiler options
219+
set(CXX_EXTRA_OPT "-Wno-keyword-macro -Wno-vla-extension -Wno-c99-extensions -Wno-zero-length-array -Wno-variadic-macros -Wno-missing-braces")
220+
221+
# Create the library target
222+
if(ENABLE_SHARED)
223+
add_library(${PROJECT_NAME} SHARED ${SOURCES})
224+
if(HAVE_SSL EQUAL 1)
225+
target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads OpenSSL::SSL OpenSSL::Crypto)
226+
elseif(HAVE_SODIUM EQUAL 1)
227+
target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads Sodium::Sodium)
228+
else()
229+
target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads)
230+
endif()
231+
else()
232+
add_library(${PROJECT_NAME} STATIC ${SOURCES})
233+
endif()
234+
# Add the definitions to the target
235+
target_compile_options(${PROJECT_NAME} PRIVATE
236+
$<$<CONFIG:Debug>:${OPTIMIZATION_DEBUG} ${WARNINGS} ${CXX_EXTRA_OPT}> "-DDEBUG=1"
237+
$<$<NOT:$<CONFIG:Debug>>:${OPTIMIZATION} ${WARNINGS}>
238+
)
239+
target_compile_definitions(${PROJECT_NAME} PRIVATE ${FLAGS})
240+
241+
set(PKG_CONFIG_FILE "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc")
242+
configure_file(${CMAKE_SOURCE_DIR}/${PROJECT_NAME}.pc.in ${PKG_CONFIG_FILE} @ONLY)
243+
244+
# Install the generated .pc file
245+
install(FILES ${PKG_CONFIG_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig)
246+
247+
if(EXAMPLES_BUILD)
248+
# Define a function to build and run an example
249+
function(build_and_run_example EXAMPLE_NAME)
250+
add_executable(${EXAMPLE_NAME} examples/${EXAMPLE_NAME}.c)
251+
if(${EXAMPLE_NAME} STREQUAL server OR ${EXAMPLE_NAME} STREQUAL client)
252+
if(Sodium_FOUND)
253+
target_link_libraries(${EXAMPLE_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads Sodium::Sodium)
254+
elseif(OpenSSL_FOUND)
255+
target_link_libraries(${EXAMPLE_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads OpenSSL::SSL OpenSSL::Crypto)
256+
else()
257+
target_link_libraries(${EXAMPLE_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads)
258+
endif()
259+
else()
260+
target_link_libraries(${EXAMPLE_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads)
261+
endif()
262+
target_compile_definitions(${EXAMPLE_NAME} PRIVATE ${FLAGS})
263+
add_custom_target(run_${EXAMPLE_NAME}
264+
COMMAND ${EXAMPLE_NAME}
265+
DEPENDS ${EXAMPLE_NAME}
266+
)
267+
endfunction()
268+
269+
# List of example files to build and run
270+
# comment all examples w/ issue build
271+
set(EXAMPLES
272+
array
273+
bstr
274+
chat
275+
client
276+
# fiobj
277+
map
278+
server
279+
string
280+
)
281+
282+
# Build and run each example
283+
foreach(EXAMPLE ${EXAMPLES})
284+
build_and_run_example(${EXAMPLE})
285+
endforeach()
286+
endif()
287+
288+
if(TESTS_BUILD)
289+
# Define a function to build and run a test
290+
function(build_and_run_test TEST_NAME)
291+
if(${TEST_NAME} STREQUAL cpp)
292+
add_executable(${TEST_NAME} tests/${TEST_NAME}.cpp)
293+
else()
294+
add_executable(${TEST_NAME} tests/${TEST_NAME}.c)
295+
endif()
296+
if(${TEST_NAME} STREQUAL base64 OR ${TEST_NAME} STREQUAL stl-mutex)
297+
if(Sodium_FOUND)
298+
target_link_libraries(${TEST_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads Sodium::Sodium)
299+
elseif(OpenSSL_FOUND)
300+
target_link_libraries(${TEST_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads OpenSSL::SSL OpenSSL::Crypto)
301+
endif()
302+
else()
303+
target_link_libraries(${TEST_NAME} PUBLIC ${PROJECT_NAME} PRIVATE Threads::Threads)
304+
endif()
305+
target_compile_definitions(${TEST_NAME} PRIVATE ${FLAGS} "-DTESTS=1")
306+
add_custom_target(run_${TEST_NAME}
307+
COMMAND ${TEST_NAME}
308+
DEPENDS ${TEST_NAME}
309+
)
310+
endfunction()
311+
312+
# List of test files to build and run
313+
# comment all tests w/ issue build
314+
set(TESTS
315+
# array
316+
base64
317+
# cpp
318+
http1-parser-old
319+
http1-parser
320+
# json
321+
# json_find
322+
# json_minify
323+
malloc
324+
mempool
325+
# mustache
326+
noop
327+
# random
328+
slowloris
329+
# stl-mutex
330+
# stl
331+
url
332+
)
333+
334+
# Build and run each test
335+
foreach(TEST ${TESTS})
336+
build_and_run_test(${TEST})
337+
endforeach()
338+
endif()

facil.io.pc.in

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
prefix=@CMAKE_INSTALL_PREFIX@
2+
exec_prefix=@CMAKE_INSTALL_PREFIX@
3+
libdir=${prefix}/lib
4+
includedir=${prefix}/include
5+
6+
Name: facil.io
7+
Description: The Web microFramework and Server Toolbox library for C
8+
Version: @PROJECT_VERSION@
9+
Cflags: -I${includedir}
10+
Libs: -L${libdir} -l@CMAKE_SHARED_LIBRARY_PREFIX@facil.io

0 commit comments

Comments
 (0)