all repos — nimisewi_c @ b9307275555b201aecaca213003e14da142909bf

simple random toki pona phrase generator

CMakeLists.txt (view raw)

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