CMakeLists.txt (view raw)
1cmake_minimum_required(VERSION 3.10)
2
3# project specification
4
5project(nimisewi
6 VERSION 0.3.1
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()
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()
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 list(APPEND EXTRA_LIBS bsd pthread md)
98 endif()
99
100 else()
101 if(NOT (HAVE_LIBBSD_STATIC))
102 message(WARNING ${WARNING_STATIC_BUILD})
103 endif()
104 list(APPEND EXTRA_LIBS bsd)
105 endif()
106
107 unset(CMAKE_REQUIRED_LIBRARIES)
108 unset(CMAKE_REQUIRED_LINK_OPTIONS)
109 endif()
110endif()
111
112if(OS_NAME MATCHES "(.*BSD)|(DragonFly)")
113 check_symbol_exists(strlcat "string.h" HAVE_STRLCAT)
114 if(HAVE_STRLCAT)
115 list(APPEND EXTRA_DEFINITIONS HAVE_STRLCAT)
116 endif()
117 check_symbol_exists(arc4random_uniform "stdlib.h" HAVE_ARC4RANDOM_UNIFORM)
118 if(HAVE_ARC4RANDOM_UNIFORM)
119 list(APPEND EXTRA_DEFINITIONS HAVE_ARC4RANDOM_UNIFORM)
120 endif()
121 check_symbol_exists(pledge "unistd.h" HAVE_PLEDGE)
122 if(HAVE_PLEDGE)
123 list(APPEND EXTRA_DEFINITIONS HAVE_PLEDGE)
124 endif()
125endif()
126
127set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
128check_c_source_compiles(
129 "#include<stdio.h>\nint main(void){return 0;}" HAVE_LIBC_STATIC
130 )
131if(NOT HAVE_LIBC_STATIC)
132 message(WARNING ${WARNING_STATIC_BUILD})
133endif()
134
135target_link_libraries(nimisewi PUBLIC ${EXTRA_LIBS})
136target_compile_definitions(nimisewi PRIVATE ${EXTRA_DEFINITIONS})
137
138set(NIMISEWI_CGI_STATIC_BUILD FALSE)
139if(HAVE_LIBC_STATIC)
140 if(HAVE_BSD_STRING_H AND HAVE_BSD_STDLIB_H)
141 if(HAVE_LIBBSD_STATIC)
142 set(NIMISEWI_CGI_STATIC_BUILD TRUE)
143 endif()
144 else()
145 set(NIMISEWI_CGI_STATIC_BUILD TRUE)
146 endif()
147endif()
148
149# optional binaries
150
151option(BUILD_CGI "build cgi version of nimisewi" OFF)
152if(BUILD_CGI)
153 add_executable(nimisewi.cgi cgi.c nimisewi.c
154 ${PROJECT_BINARY_DIR}/nimitoki.c)
155 option(CGI_INSTALL_DIR "specify installation directory of cgi script")
156 if(CGI_INSTALL_DIR)
157 set_property(TARGET nimisewi.cgi PROPERTY CGI_INSTALL_DIR
158 ${CGI_INSTALL_DIR})
159 else()
160 set_property(TARGET nimisewi.cgi PROPERTY CGI_INSTALL_DIR
161 "var/www/htdocs/cgi-bin")
162 endif()
163 target_include_directories(nimisewi.cgi PUBLIC "${PROJECT_BINARY_DIR}")
164 target_compile_definitions(nimisewi.cgi PRIVATE ${EXTRA_DEFINITIONS})
165 target_link_libraries(nimisewi.cgi PUBLIC ${EXTRA_LIBS})
166 if(NIMISEWI_CGI_STATIC_BUILD)
167 target_link_options(nimisewi.cgi PUBLIC -static)
168 endif()
169endif()
170
171option(BUILD_GEMINI_CGI "build cgi version of nimisewi for gemini protocol" OFF)
172if(BUILD_GEMINI_CGI)
173 add_executable(nimisewi_gemini.cgi cgi_gemini.c nimisewi.c
174 ${PROJECT_BINARY_DIR}/nimitoki.c)
175 option(GEMINI_CGI_INSTALL_DIR "specify installation directory of cgi script")
176 if(GEMINI_CGI_INSTALL_DIR)
177 set_property(TARGET nimisewi_gemini.cgi PROPERTY GEMINI_CGI_INSTALL_DIR
178 ${GEMINI_CGI_INSTALL_DIR})
179 else()
180 set_property(TARGET nimisewi_gemini.cgi PROPERTY GEMINI_CGI_INSTALL_DIR
181 "var/gemini/cgi-bin")
182 endif()
183 target_include_directories(nimisewi_gemini.cgi PUBLIC "${PROJECT_BINARY_DIR}")
184 target_compile_definitions(nimisewi_gemini.cgi PRIVATE ${EXTRA_DEFINITIONS})
185 target_link_libraries(nimisewi_gemini.cgi PUBLIC ${EXTRA_LIBS})
186 if(NIMISEWI_CGI_STATIC_BUILD)
187 target_link_options(nimisewi_gemini.cgi PUBLIC -static)
188 endif()
189endif()
190
191# installation
192
193install(TARGETS nimisewi DESTINATION bin)
194if(BUILD_CGI)
195 install(TARGETS nimisewi.cgi
196 DESTINATION $<TARGET_PROPERTY:nimisewi.cgi,CGI_INSTALL_DIR>)
197endif()
198if(BUILD_GEMINI_CGI)
199 install(TARGETS nimisewi_gemini.cgi
200 DESTINATION $<TARGET_PROPERTY:nimisewi_gemini.cgi,GEMINI_CGI_INSTALL_DIR>)
201endif()
202
203# packaging
204
205include(InstallRequiredSystemLibraries)
206set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
207set(CPACK_PROJECT_VERSION_MAJOR ${nimisewi_VERSION_MAJOR})
208set(CPACK_PROJECT_VERSION_MINOR ${nimisewi_VERSION_MINOR})
209set(CPACK_PROJECT_VERSION_PATCH ${nimisewi_VERSION_PATCH})
210set(CPACK_PACKAGE_FILE_NAME
211 ${CMAKE_PROJECT_NAME}-${nimisewi_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
212set(CPACK_GENERATOR "TGZ" "ZIP")
213set(CPACK_SOURCE_GENERATOR "TGZ" "ZIP")
214set(CPACK_SOURCE_IGNORE_FILES
215 \.fslckout
216 \.fossil-settings
217 build/
218 utils/
219 download.md
220 )
221set(CPACK_STRIP_FILES TRUE)
222include(CPack)
223
224# testing
225
226enable_testing()
227
228add_test(NAME runs COMMAND nimisewi)
229
230add_test(NAME version COMMAND nimisewi -v)
231set_tests_properties(version
232 PROPERTIES PASS_REGULAR_EXPRESSION
233 "nimisewi [0-9]\.[0-9]\.[0-9]\n[a-z ]+(\nfeatures:\n([A-Z_]+(\n)?)+)?")
234
235if(BUILD_CGI)
236 add_test(NAME cgi COMMAND nimisewi.cgi)
237 set_tests_properties(cgi
238 PROPERTIES PASS_REGULAR_EXPRESSION
239 "Status: 200 OK\rContent-Type: text\/html\r\r<.*>")
240endif()
241if(BUILD_GEMINI_CGI)
242 add_test(NAME gemini_cgi COMMAND nimisewi_gemini.cgi)
243 set_tests_properties(gemini_cgi
244 PROPERTIES PASS_REGULAR_EXPRESSION "20 text\/gemini\r\n.*")
245endif()