CMakeLists.txt (view raw)
1cmake_minimum_required(VERSION 3.10)
2
3# project specification
4
5project(nimisewi
6 VERSION 0.3.2
7 DESCRIPTION "small program that generates random toki pona noun phrase"
8 HOMEPAGE_URL "https://fsl.aaoth.xyz/nimisewi.c/home")
9
10# get compiler name and version
11
12execute_process(COMMAND ${CMAKE_C_COMPILER} "--version"
13 OUTPUT_VARIABLE _PROJECT_C_COMPILER_VERSION)
14string(REGEX REPLACE "\n" ";"
15 PROJECT_C_COMPILER_VERSION ${_PROJECT_C_COMPILER_VERSION})
16list(APPEND PROJECT_C_COMPILER_STRING ${PROJECT_C_COMPILER_VERSION})
17list(POP_FRONT PROJECT_C_COMPILER_STRING PROJECT_C_COMPILER_VERSION)
18
19# configuration header
20
21configure_file(config.h.in config.h)
22
23# main executable
24
25add_executable(nimisewi main.c nimisewi.c
26 ${PROJECT_BINARY_DIR}/nimitoki.c)
27target_include_directories(nimisewi PUBLIC "${PROJECT_BINARY_DIR}")
28
29# supplementary executable
30
31add_executable(makenimitoki makenimitoki.c)
32target_include_directories(makenimitoki PUBLIC "${PROJECT_BINARY_DIR}")
33
34add_custom_command(
35 OUTPUT ${PROJECT_BINARY_DIR}/nimitoki.c
36 ${PROJECT_BINARY_DIR}/nimitoki.h
37 COMMAND makenimitoki ${PROJECT_SOURCE_DIR}/nimitoki.txt
38 DEPENDS makenimitoki)
39
40# includes
41
42include(CheckIncludeFile)
43include(CheckSymbolExists)
44include(CheckCSourceCompiles)
45
46# warning message
47
48set(WARNING_STATIC_BUILD "static build won't work here")
49
50# check libraries
51
52cmake_host_system_information(RESULT OS_NAME QUERY OS_NAME)
53message(VERBOSE "OS_NAME is ${OS_NAME}")
54if(OS_NAME MATCHES "Linux")
55 check_include_file("bsd/string.h" HAVE_BSD_STRING_H)
56 check_include_file("bsd/stdlib.h" HAVE_BSD_STDLIB_H)
57 if(HAVE_BSD_STRING_H AND HAVE_BSD_STDLIB_H)
58 set(CMAKE_REQUIRED_LIBRARIES "bsd")
59
60 check_symbol_exists(strlcat "bsd/string.h" HAVE_STRLCAT)
61 if (HAVE_STRLCAT)
62 list(APPEND EXTRA_DEFINITIONS HAVE_BSD_STRING_H HAVE_STRLCAT)
63 endif() # HAVE_STRLCAT
64
65 check_symbol_exists(arc4random_uniform "bsd/stdlib.h"
66 HAVE_ARC4RANDOM_UNIFORM)
67 if (HAVE_ARC4RANDOM_UNIFORM)
68 list(APPEND EXTRA_DEFINITIONS HAVE_BSD_STDLIB_H HAVE_ARC4RANDOM_UNIFORM)
69 endif() # HAVE_ARC4RANDOM_UNIFORM
70
71 # check static libraries
72 set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
73 check_c_source_compiles(
74 "#include<bsd/string.h>\nint main(void){return 0;}"
75 HAVE_LIBBSD_STATIC)
76
77 if(NOT ANDROID)
78 # libpthread and libmd are needed when linking statically on linux.
79 # these test aren't really checking particular functions, but
80 # they are here to make sure that program could be linked statically
81 unset(CMAKE_REQUIRED_LIBRARIES)
82 set(CMAKE_REQUIRED_LIBRARIES "pthread")
83 check_c_source_compiles(
84 "#include<pthread.h>\nint main(void){return 0;}"
85 HAVE_LIBPTHREAD_STATIC)
86
87 unset(CMAKE_REQUIRED_LIBRARIES)
88 set(CMAKE_REQUIRED_LIBRARIES "md")
89 check_c_source_compiles(
90 "#include<sha2.h>\nint main(void){return 0;}"
91 HAVE_LIBMD_STATIC)
92
93 if(NOT (HAVE_LIBBSD_STATIC
94 AND HAVE_LIBPTHREAD_STATIC
95 AND HAVE_LIBMD_STATIC))
96 message(WARNING ${WARNING_STATIC_BUILD})
97 endif() # NOT (HAVE_LIBBSD_STATIC AND ...)
98
99 list(APPEND EXTRA_LIBS bsd pthread md)
100
101 else() # NOT ANDROID
102 if(NOT (HAVE_LIBBSD_STATIC))
103 message(WARNING ${WARNING_STATIC_BUILD})
104 endif()
105 list(APPEND EXTRA_LIBS bsd)
106 endif() # NOT ANDROID
107
108 unset(CMAKE_REQUIRED_LIBRARIES)
109 unset(CMAKE_REQUIRED_LINK_OPTIONS)
110
111 endif() # HAVE_BSD_STRING_H AND HAVE_BSD_STDLIB_H
112
113endif() # OS_NAME MATCHES "Linux"
114
115if(OS_NAME MATCHES "(.*BSD)|(DragonFly)")
116 check_symbol_exists(strlcat "string.h" HAVE_STRLCAT)
117
118 if(HAVE_STRLCAT)
119 list(APPEND EXTRA_DEFINITIONS HAVE_STRLCAT)
120 endif() # HAVE_STRLCAT
121
122 check_symbol_exists(arc4random_uniform "stdlib.h" HAVE_ARC4RANDOM_UNIFORM)
123 if(HAVE_ARC4RANDOM_UNIFORM)
124 list(APPEND EXTRA_DEFINITIONS HAVE_ARC4RANDOM_UNIFORM)
125 endif() # HAVE_ARC4RANDOM_UNIFORM
126
127 check_symbol_exists(pledge "unistd.h" HAVE_PLEDGE)
128 if(HAVE_PLEDGE)
129 list(APPEND EXTRA_DEFINITIONS HAVE_PLEDGE)
130 endif() # HAVE_PLEDGE
131
132endif() # OS_NAME MATCHES "(.*BSD)|(DragonFly)"
133
134set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
135check_c_source_compiles(
136 "#include<stdio.h>\nint main(void){return 0;}" HAVE_LIBC_STATIC
137 )
138if(NOT HAVE_LIBC_STATIC)
139 message(WARNING ${WARNING_STATIC_BUILD})
140endif() # NOT HAVE_LIBC_STATIC
141
142target_link_libraries(nimisewi PUBLIC ${EXTRA_LIBS})
143target_compile_definitions(nimisewi PRIVATE ${EXTRA_DEFINITIONS})
144
145set(NIMISEWI_CGI_STATIC_BUILD FALSE)
146if(HAVE_LIBC_STATIC)
147 if(HAVE_BSD_STRING_H AND HAVE_BSD_STDLIB_H)
148 if(HAVE_LIBBSD_STATIC)
149 set(NIMISEWI_CGI_STATIC_BUILD TRUE)
150 endif() # HAVE_LIBBSD_STATIC
151 else() # HAVE_BSD_STRING_H AND ...
152 set(NIMISEWI_CGI_STATIC_BUILD TRUE)
153 endif() # HAVE_BSD_STRING_H AND ...
154endif() # HAVE_LIBBSD_STATIC
155
156# optional binaries
157
158option(BUILD_CGI "build cgi version of nimisewi" OFF)
159if(BUILD_CGI)
160 add_executable(nimisewi.cgi cgi.c nimisewi.c
161 ${PROJECT_BINARY_DIR}/nimitoki.c)
162 option(CGI_INSTALL_DIR "specify installation directory of cgi script")
163
164 if(CGI_INSTALL_DIR)
165 set_property(TARGET nimisewi.cgi PROPERTY CGI_INSTALL_DIR
166 ${CGI_INSTALL_DIR})
167 else() # CGI_INSTALL_DIR
168 set_property(TARGET nimisewi.cgi PROPERTY CGI_INSTALL_DIR
169 "var/www/htdocs/cgi-bin")
170 endif() # CGI_INSTALL_DIR
171
172 target_include_directories(nimisewi.cgi PUBLIC "${PROJECT_BINARY_DIR}")
173 target_compile_definitions(nimisewi.cgi PRIVATE ${EXTRA_DEFINITIONS})
174 target_link_libraries(nimisewi.cgi PUBLIC ${EXTRA_LIBS})
175
176 if(NIMISEWI_CGI_STATIC_BUILD)
177 target_link_options(nimisewi.cgi PUBLIC -static)
178 endif() # NIMISEWI_CGI_STATIC_BUILD
179
180endif() # BUILD_CGI
181
182option(BUILD_GEMINI_CGI "build cgi version of nimisewi for gemini protocol" OFF)
183if(BUILD_GEMINI_CGI)
184 add_executable(nimisewi_gemini.cgi cgi_gemini.c nimisewi.c
185 ${PROJECT_BINARY_DIR}/nimitoki.c)
186 option(GEMINI_CGI_INSTALL_DIR "specify installation directory of cgi script")
187
188 if(GEMINI_CGI_INSTALL_DIR)
189 set_property(TARGET nimisewi_gemini.cgi PROPERTY GEMINI_CGI_INSTALL_DIR
190 ${GEMINI_CGI_INSTALL_DIR})
191 else() # GEMINI_CGI_INSTALL_DIR
192 set_property(TARGET nimisewi_gemini.cgi PROPERTY GEMINI_CGI_INSTALL_DIR
193 "var/gemini/cgi-bin")
194 endif() # GEMINI_CGI_INSTALL_DIR
195
196 target_include_directories(nimisewi_gemini.cgi PUBLIC "${PROJECT_BINARY_DIR}")
197 target_compile_definitions(nimisewi_gemini.cgi PRIVATE ${EXTRA_DEFINITIONS})
198 target_link_libraries(nimisewi_gemini.cgi PUBLIC ${EXTRA_LIBS})
199
200 if(NIMISEWI_CGI_STATIC_BUILD)
201 target_link_options(nimisewi_gemini.cgi PUBLIC -static)
202 endif() # NIMISEWI_CGI_STATIC_BUILD
203
204endif() # BUILD_GEMINI_CGI
205
206# installation
207
208install(TARGETS nimisewi DESTINATION bin)
209
210if(BUILD_CGI)
211 install(TARGETS nimisewi.cgi
212 DESTINATION $<TARGET_PROPERTY:nimisewi.cgi,CGI_INSTALL_DIR>)
213endif() # BUILD_CGI
214
215if(BUILD_GEMINI_CGI)
216 install(TARGETS nimisewi_gemini.cgi
217 DESTINATION $<TARGET_PROPERTY:nimisewi_gemini.cgi,GEMINI_CGI_INSTALL_DIR>)
218endif() # BUILD_GEMINI_CGI
219
220# packaging
221
222include(InstallRequiredSystemLibraries)
223set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
224set(CPACK_PROJECT_VERSION_MAJOR ${nimisewi_VERSION_MAJOR})
225set(CPACK_PROJECT_VERSION_MINOR ${nimisewi_VERSION_MINOR})
226set(CPACK_PROJECT_VERSION_PATCH ${nimisewi_VERSION_PATCH})
227set(CPACK_PACKAGE_FILE_NAME
228 ${CMAKE_PROJECT_NAME}-${nimisewi_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
229set(CPACK_GENERATOR "TGZ" "ZIP")
230set(CPACK_SOURCE_GENERATOR "TGZ" "ZIP")
231set(CPACK_SOURCE_IGNORE_FILES
232 \.fslckout
233 \.fossil-settings
234 build/
235 utils/
236 download.md
237 )
238set(CPACK_STRIP_FILES TRUE)
239include(CPack)
240
241# testing
242
243enable_testing()
244
245add_test(NAME runs COMMAND nimisewi)
246
247add_test(NAME version COMMAND nimisewi -v)
248set_tests_properties(version
249 PROPERTIES PASS_REGULAR_EXPRESSION
250 "nimisewi [0-9]\.[0-9]\.[0-9]\n[a-z ]+(\n([A-Z_]+(\n)?)+)?")
251
252if(BUILD_CGI)
253 add_test(NAME cgi COMMAND nimisewi.cgi)
254 set_tests_properties(cgi
255 PROPERTIES PASS_REGULAR_EXPRESSION
256 "Status: 200 OK\rContent-Type: text\/html\r\r<.*>")
257endif() # BUILD_CGI
258
259if(BUILD_GEMINI_CGI)
260 add_test(NAME gemini_cgi COMMAND nimisewi_gemini.cgi)
261 set_tests_properties(gemini_cgi
262 PROPERTIES PASS_REGULAR_EXPRESSION "20 text\/gemini\r\n.*")
263endif() # BUILD_GEMINI_CGI