Support highlight for string
[liba.git] / CMakeLists.txt
blob1a1ef71b35eb6d5dd3392753e20ee392b03e4ced
1 set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
2 set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
3 cmake_minimum_required(VERSION 2.8.12...4.0)
4 include(cmake/CMakeModulePath.cmake)
5 include(cmake/Languages.cmake)
6 project(liba ${LANGUAGES})
7 include(cmake/Project.cmake)
8 include(cmake/core/file.cmake)
9 include(cmake/core/string.cmake)
10 include(cmake/CMakeByteOrder.cmake)
11 include(cmake/CMakeBuildType.cmake)
12 include(cmake/EnabledLanguages.cmake)
13 include(cmake/TargetSupportsSharedLibs.cmake)
14 include(cmake/TargetSupportsExecutables.cmake)
15 include(cmake/TargetSupportsRelocatable.cmake)
16 include(cmake/TargetSupportsSymbolicLink.cmake)
18 option(LIBA_WARNINGS "Enable/Disable warnings" 0)
20 if(LIBA_WARNINGS)
21   include(cmake/TargetWarnings.cmake)
22 endif()
24 option(LIBA_ANALYZER "Enable/Disable analyzer" 0)
26 if(LIBA_ANALYZER)
27   include(cmake/TargetAnalyzer.cmake)
28 endif()
30 option(LIBA_SANITIZE "Enable/Disable sanitize" 0)
32 if(LIBA_SANITIZE)
33   include(cmake/TargetSanitize.cmake)
34 endif()
36 option(LIBA_STATIC "Enable/Disable finding and linking static libraries" 0)
38 if(LIBA_STATIC)
39   include(cmake/CMakeFindLibraryStatic.cmake)
40   include(cmake/TargetStatic.cmake)
41 endif()
43 option(LIBA_CCACHE "Enable/Disable ccache" 0)
45 if(LIBA_CCACHE)
46   include(cmake/UseCCache.cmake)
47 endif()
49 if(UNIX)
50   set(LIBA_MATH "m" CACHE FILEPATH "system math library")
51 else()
52   set(LIBA_MATH "" CACHE FILEPATH "system math library")
53 endif()
55 include(CheckLibraryExists)
56 set(LIBA_FLOAT 8 CACHE STRING "floating-point number bytes")
57 set_property(CACHE LIBA_FLOAT PROPERTY STRINGS 4 8 16)
59 function(check_math VARIABLE FUNCTION)
60   get_filename_component(LOCATION "${LIBA_MATH}" DIRECTORY)
61   list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBA_MATH})
63   if(LIBA_FLOAT GREATER 8)
64     set(FUNCTION ${FUNCTION}l)
65   elseif(LIBA_FLOAT EQUAL 4)
66     set(FUNCTION ${FUNCTION}f)
67   endif()
69   check_library_exists("${LIBA_MATH}"
70     ${FUNCTION} "${LOCATION}" ${VARIABLE}
71   )
72 endfunction()
74 check_math(A_HAVE_HYPOT hypot)
75 check_math(A_HAVE_LOG1P log1p)
76 check_math(A_HAVE_ATAN2 atan2)
77 check_math(A_HAVE_CSQRT csqrt)
78 check_math(A_HAVE_CPOW cpow)
79 check_math(A_HAVE_CEXP cexp)
80 check_math(A_HAVE_CLOG clog)
81 check_math(A_HAVE_CSIN csin)
82 check_math(A_HAVE_CCOS ccos)
83 check_math(A_HAVE_CTAN ctan)
84 check_math(A_HAVE_CSINH csinh)
85 check_math(A_HAVE_CCOSH ccosh)
86 check_math(A_HAVE_CTANH ctanh)
87 check_math(A_HAVE_CASIN casin)
88 check_math(A_HAVE_CACOS cacos)
89 check_math(A_HAVE_CATAN catan)
90 check_math(A_HAVE_CASINH casinh)
91 check_math(A_HAVE_CACOSH cacosh)
92 check_math(A_HAVE_CATANH catanh)
94 option(LIBA_PYTHON "Enable/Disable python" 0)
96 if(LIBA_PYTHON)
97   find_package(Python COMPONENTS Interpreter)
98   find_package(Cython)
99 endif()
101 option(LIBA_DOXYGEN "Enable/Disable doxygen" 0)
103 if(LIBA_DOXYGEN)
104   find_package(Doxygen OPTIONAL_COMPONENTS dot mscgen dia)
105 endif()
107 option(LIBA_CPPCHECK "Enable/Disable cppcheck" 0)
109 if(LIBA_CPPCHECK)
110   find_package(cppcheck)
111 endif()
113 option(LIBA_CLANG_TIDY "Enable/Disable clang-tidy" 0)
115 if(LIBA_CLANG_TIDY)
116   find_package(ClangTidy)
117 endif()
119 option(LIBA_IWYU "Enable/Disable include-what-you-use" 0)
121 if(LIBA_IWYU)
122   find_package(IWYU)
123 endif()
125 option(LIBA_IPO "Enable/Disable interprocedural optimization" 0)
127 # https://cmake.org/cmake/help/latest/module/CheckIPOSupported.html
128 if(NOT CMAKE_VERSION VERSION_LESS 3.9 AND LIBA_IPO)
129   cmake_policy(SET CMP0069 NEW)
130   include(CheckIPOSupported)
131   check_ipo_supported(RESULT LIBA_IPO)
132 endif()
134 if(DEFINED ENV{ANDROID_ROOT} AND EXISTS $ENV{ANDROID_ROOT})
135   option(LIBA_PIE "Enable/Disable position independent code" 1)
136 else()
137   option(LIBA_PIE "Enable/Disable position independent code" 0)
138 endif()
140 # https://cmake.org/cmake/help/latest/module/CheckPIESupported.html
141 if(NOT CMAKE_VERSION VERSION_LESS 3.14)
142   cmake_policy(SET CMP0083 NEW)
143   include(CheckPIESupported)
144   check_pie_supported()
145 endif()
147 function(set_library_options)
148   if(LIBA_IWYU AND IWYU_FOUND)
149     add_include_what_you_use(TARGETS ${ARGN})
150   endif()
152   if(LIBA_CLANG_TIDY AND CLANG_TIDY_FOUND)
153     add_clang_tidy(TARGETS ${ARGN} OPTIONS --fix)
154   endif()
156   if(LIBA_CPPCHECK AND CPPCHECK_FOUND)
157     add_cppcheck(TARGETS ${ARGN} OPTIONS --enable=warning,performance)
158   endif()
160   if(CMAKE_C_COMPILER_ID MATCHES "TinyCC" AND CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL .lib)
161     set_property(TARGET ${ARGN} PROPERTY IMPORT_SUFFIX .def)
162   endif()
164   set_target_properties(${ARGN} PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${LIBA_IPO}
165     C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1
166   )
168   if(LIBA_WARNINGS)
169     target_compile_warnings(${ARGN})
170   endif()
172   if(LIBA_ANALYZER)
173     target_compile_analyzer(${ARGN})
174   endif()
175 endfunction()
177 function(add_library_properties target scope source)
178   target_compile_definitions(${target} ${scope} $<TARGET_PROPERTY:${source},${ARGV3}COMPILE_DEFINITIONS>)
179   target_include_directories(${target} ${scope} $<TARGET_PROPERTY:${source},${ARGV3}INCLUDE_DIRECTORIES>)
181   if(${scope} MATCHES "PUBLIC|PRIVATE")
182     set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES $<TARGET_PROPERTY:${source},${ARGV3}LINK_LIBRARIES>)
183   endif()
185   if(${scope} MATCHES "PUBLIC|INTERFACE")
186     set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<TARGET_PROPERTY:${source},${ARGV3}LINK_LIBRARIES>)
187   endif()
188 endfunction()
190 option(LIBA_MIMALLOC "Enable/Disable override using mimalloc" 0)
191 set(A_HAVE_MIMALLOC_H)
193 if(LIBA_MIMALLOC)
194   find_package(mimalloc)
195 endif()
197 if(mimalloc_FOUND)
198   set(A_HAVE_MIMALLOC_H 1)
199 endif()
201 find_package(Git)
203 if(GIT_FOUND)
204   function(git_command output)
205     execute_process(ERROR_QUIET
206       COMMAND ${GIT_EXECUTABLE} ${ARGN}
207       OUTPUT_STRIP_TRAILING_WHITESPACE
208       OUTPUT_VARIABLE ${output}
209     )
210     set(${output} ${${output}} PARENT_SCOPE)
211   endfunction()
213   git_command(GIT_COMMIT_LONG log -1 --pretty=format:%H)
214   git_command(GIT_COMMIT_DATE log -1 --pretty=format:%cd --date=format:%Y%m%d)
215 endif()
217 if(GIT_COMMIT_DATE)
218   set(PROJECT_VERSION_TWEAK ${GIT_COMMIT_DATE})
219   set(${PROJECT_NAME}_VERSION_TWEAK ${GIT_COMMIT_DATE})
220 else()
221   string(TIMESTAMP PROJECT_VERSION_TWEAK %Y%m%d)
222   string(TIMESTAMP ${PROJECT_NAME}_VERSION_TWEAK %Y%m%d)
223 endif()
225 if(NOT EXISTS "${A_HAVE_H}")
226   set(A_HAVE_H ${CMAKE_CURRENT_BINARY_DIR}/a.cmake.h)
227   configure_file(${CMAKE_CURRENT_LIST_DIR}/include/a.cmake.h.in ${A_HAVE_H})
228 endif()
230 if(IS_ABSOLUTE "${LIBA_MATH}")
231   get_filename_component(math ${LIBA_MATH} NAME_WE)
232   string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}(.+)" "\\1" math "${math}")
233   set(LIBA_MATH $<BUILD_INTERFACE:${LIBA_MATH}> $<INSTALL_INTERFACE:${math}>)
234   set(math)
235 endif()
237 if(TARGET_SUPPORTS_SYMBOLIC_LINK)
238   option(LIBA_SYMLINK "Enable/Disable symbolic link" 1)
239 endif()
241 function(set_library_compile target)
242   if(EXISTS "${A_HAVE_H}")
243     file(RELATIVE_PATH a_have_h ${PROJECT_SOURCE_DIR}/include/a ${A_HAVE_H})
244     target_compile_definitions(${target} PUBLIC $<BUILD_INTERFACE:A_HAVE_H="${a_have_h}">)
245     set(a_have_h)
246   endif()
248   if((LIBA_SYMLINK OR WIN32) AND TARGET_SUPPORTS_SYMBOLIC_LINK)
249     set_target_properties(${target} PROPERTIES SOVERSION
250       ${PROJECT_VERSION_MAJOR} VERSION ${PROJECT_VERSION}
251     )
252   endif()
254   set_target_properties(${target} PROPERTIES OUTPUT_NAME a
255     POSITION_INDEPENDENT_CODE 1 DEFINE_SYMBOL A_EXPORTS
256   )
257   target_compile_definitions(${target} PRIVATE A_EXPORTS)
258   target_include_directories(${target} BEFORE PUBLIC
259     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
260     $<INSTALL_INTERFACE:include>
261   )
262   get_property(TYPE TARGET ${target} PROPERTY TYPE)
264   if(${TYPE} MATCHES "(STATIC|SHARED|MODULE)_LIBRARY")
265     target_link_libraries(${target} PUBLIC ${LIBA_MATH})
266   endif()
268   set_library_options(${target})
269 endfunction()
271 if(LIBA_CXX)
272   file_scaner(SOURCES RECURSE include src EXT c h cc hh cpp hpp)
273 else()
274   file_scaner(SOURCES RECURSE include src EXT c h)
275 endif()
277 add_library(a OBJECT ${SOURCES})
278 set_library_compile(a)
280 if(A_HAVE_MIMALLOC_H AND CMAKE_VERSION VERSION_LESS 3.12)
281   add_library_properties(a PUBLIC mimalloc-static INTERFACE_)
282 elseif(A_HAVE_MIMALLOC_H)
283   target_link_libraries(a PUBLIC mimalloc-static)
284 endif()
286 include(GNUInstallDirs)
287 set(INSTALL_TARGETS "")
288 set(LIBA_INSTALL "" CACHE STRING "Specify the installation")
290 if(NOT LIBA_INSTALL)
291   list(APPEND INSTALL_TARGETS alib)
292 endif()
294 add_library(alib $<TARGET_OBJECTS:a>)
295 set_library_compile(alib)
297 if(A_HAVE_MIMALLOC_H)
298   target_link_libraries(alib PUBLIC mimalloc-static)
299 endif()
301 if(TARGET_SUPPORTS_SHARED_LIBS)
302   if(NOT LIBA_INSTALL)
303     list(APPEND INSTALL_TARGETS liba)
304   endif()
306   if(BUILD_SHARED_LIBS)
307     set(module STATIC)
308     set(shared alib)
309   else()
310     set(module SHARED)
311     set(shared liba)
312   endif()
314   add_library(liba ${module} $<TARGET_OBJECTS:a>)
315   set_library_compile(liba)
317   if(A_HAVE_MIMALLOC_H)
318     target_link_libraries(liba PUBLIC mimalloc-static)
319   endif()
321   if(CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL .lib)
322     set_property(TARGET ${shared} PROPERTY OUTPUT_NAME liba)
323   endif()
325   target_compile_definitions(${shared} INTERFACE A_IMPORTS)
327   if(LIBA_STATIC)
328     target_link_static(${shared})
329   endif()
330 endif()
332 if(LIBA_SANITIZE)
333   add_library(asan OBJECT ${SOURCES})
334   set_library_compile(asan)
335   target_compile_sanitize(asan)
337   if(A_HAVE_MIMALLOC_H AND CMAKE_VERSION VERSION_LESS 3.12)
338     add_library_properties(asan PUBLIC mimalloc INTERFACE_)
339   elseif(A_HAVE_MIMALLOC_H)
340     target_link_libraries(asan PUBLIC mimalloc)
341   endif()
343   if(TARGET_SUPPORTS_SHARED_LIBS)
344     add_library(libasan SHARED $<TARGET_OBJECTS:asan>)
345     set_library_compile(libasan)
347     set_property(TARGET libasan PROPERTY OUTPUT_NAME a.san)
348     target_compile_definitions(libasan INTERFACE A_IMPORTS)
349     target_link_sanitize(libasan)
351     if(A_HAVE_MIMALLOC_H)
352       target_link_libraries(libasan PUBLIC mimalloc)
353     endif()
355     if(LIBA_STATIC)
356       target_link_static(libasan)
357     endif()
358   endif()
359 endif()
361 if(TARGET_SUPPORTS_RELOCATABLE)
362   file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/lib/CMakeLists.txt "get_cmake_property(ENABLED_LANGUAGES ENABLED_LANGUAGES)
363 foreach(LANG \${ENABLED_LANGUAGES})
364 \tset(CMAKE_\${LANG}_LINK_EXECUTABLE
365 \t\t\"<CMAKE_\${LANG}_COMPILER> <FLAGS> -nostdlib -o <TARGET>\${CMAKE_EXECUTABLE_SUFFIX} -r <OBJECTS>\"
366 \t\t\"\${CMAKE_COMMAND} -E copy <TARGET>\${CMAKE_EXECUTABLE_SUFFIX} <TARGET>.o\"
368 \tif(CMAKE_EXECUTABLE_SUFFIX)
369 \t\tset(RM rm)\n\t\tif(CMAKE_VERSION VERSION_LESS 3.17)\n\t\t\tset(RM remove)\n\t\tendif()
370 \t\tlist(APPEND CMAKE_\${LANG}_LINK_EXECUTABLE \"\${CMAKE_COMMAND} -E \${RM} -f <TARGET>\"
371 \t\t\t\"\${CMAKE_COMMAND} -E rename <TARGET>\${CMAKE_EXECUTABLE_SUFFIX} <TARGET>\"
372 \t\t)\n\t\tset(RM)
373 \tendif()
374 \tset(CMAKE_\${LANG}_CREATE_STATIC_LIBRARY \"\")
375 endforeach()
376 set(CMAKE_EXECUTABLE_SUFFIX \"\")
377 set(CMAKE_STATIC_LIBRARY_SUFFIX .o)
378 set(CMAKE_STATIC_LIBRARY_PREFIX lib)
379 add_executable(a.o \$<TARGET_OBJECTS:a>)
380 add_library(liba.o STATIC \$<TARGET_OBJECTS:a>)
381 set_library_compile(liba.o)\nadd_dependencies(liba.o a.o)
382 set_target_properties(a.o PROPERTIES OUTPUT_NAME liba
383 \tINTERPROCEDURAL_OPTIMIZATION \${LIBA_IPO}
385 if(A_HAVE_MIMALLOC_H AND CMAKE_VERSION VERSION_LESS 3.12)
386 \tadd_library_properties(liba.o PUBLIC mimalloc-static INTERFACE_)
387 elseif(A_HAVE_MIMALLOC_H)
388 \ttarget_link_libraries(liba.o PUBLIC mimalloc-static)
389 endif()
390 if(NOT LIBA_INSTALL)
391 \tinstall(TARGETS liba.o EXPORT \${PROJECT_NAME}-targets
392 \t\tARCHIVE DESTINATION \${CMAKE_INSTALL_LIBDIR}
393 \t\tLIBRARY DESTINATION \${CMAKE_INSTALL_LIBDIR}
394 \t)\nendif()")
395   add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/lib lib)
396 else()
397   add_library(liba.o ALIAS alib)
398 endif()
400 if(INSTALL_TARGETS)
401   include(cmake/InstallTargets.cmake)
402   install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/a DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
404   if(EXISTS "${A_HAVE_H}")
405     install(FILES ${A_HAVE_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/a)
406     install_fixup(${CMAKE_INSTALL_INCLUDEDIR}/a/a.h A_HAVE_H ${A_HAVE_H})
407   endif()
408 endif()
410 option(LIBA_PKGCONFIG "Enable/Disable pkgconfig" 0)
412 if(LIBA_PKGCONFIG)
413   include(cmake/InstallPkgConfig.cmake)
414   install_pkgconfig(${PROJECT_NAME} alib)
415 endif()
417 option(LIBA_LIBTOOL "Enable/Disable libtool" 0)
419 if(LIBA_LIBTOOL AND INSTALL_TARGETS)
420   include(cmake/InstallLibtool.cmake)
421   install_libtool(${INSTALL_TARGETS})
422 endif()
424 option(LIBA_VCPKG "Enable/Disable vcpkg" 0)
426 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/vcpkg AND LIBA_VCPKG AND GIT_COMMIT_LONG)
427   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vcpkg DESTINATION ${CMAKE_INSTALL_DATADIR})
428   configure_file(
429     ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/portfile.cmake
430     ${CMAKE_CURRENT_BINARY_DIR}/vcpkg/ports/${PROJECT_NAME}/portfile.cmake
431     @ONLY
432   )
433   configure_file(
434     ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/vcpkg.json
435     ${CMAKE_CURRENT_BINARY_DIR}/vcpkg/ports/${PROJECT_NAME}/vcpkg.json
436     @ONLY
437   )
438 endif()
440 if(PROJECT_IS_TOP_LEVEL)
441   add_custom_target(afmt)
442   add_custom_target(adoc)
443   include(CTest)
444 endif()
446 if(NOT CMAKE_FIND_LIBRARY_PREFIXES)
447   set(CMAKE_FIND_LIBRARY_PREFIXES ";lib")
448 endif()
450 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/java/CMakeLists.txt)
451   option(LIBA_JAVA "Enable/Disable java" 0)
453   if(LIBA_JAVA)
454     find_package(Java)
455     find_package(JNI)
456   endif()
458   if(LIBA_JAVA AND Java_JAVAC_EXECUTABLE)
459     add_subdirectory(java)
460   endif()
461 endif()
463 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/javascript/CMakeLists.txt)
464   if(EMSCRIPTEN)
465     option(LIBA_JAVASCRIPT "Enable/Disable javascript" 1)
466   else()
467     option(LIBA_JAVASCRIPT "Enable/Disable javascript" 0)
468   endif()
470   if(LIBA_JAVASCRIPT)
471     if(NOT EMSCRIPTEN)
472       find_package(Emscripten)
473     endif()
475     if(EMSCRIPTEN OR EMSCRIPTEN_FOUND)
476       add_subdirectory(javascript)
477     endif()
478   endif()
479 endif()
481 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/lua/CMakeLists.txt)
482   option(LIBA_LUA "Enable/Disable lua" 0)
483   option(LIBA_LUAJIT "Enable/Disable luajit" 0)
484   option(LIBA_WITH_LUA "Enable/Disable build with lua" 0)
486   if(LIBA_LUA OR LIBA_LUAJIT OR LIBA_WITH_LUA)
487     set(LUA_MATH_LIBRARY ${LIBA_MATH} CACHE STRING "lua math library")
488   endif()
490   if(NOT LIBA_WITH_LUA AND LIBA_LUA)
491     find_package(Lua OPTIONAL_COMPONENTS lua)
492     set(LUA_LIBRARIES lualib)
493   endif()
495   if((LIBA_LUA AND NOT LUA_FOUND AND NOT LIBA_WITH_LUA) OR LIBA_LUAJIT)
496     find_package(LuaJIT OPTIONAL_COMPONENTS luajit)
497     set(LUA_EXECUTABLE ${LUAJIT_EXECUTABLE})
498     set(LUA_LIBRARIES luajit)
499   endif()
501   if(LIBA_LUA AND LUA_FOUND)
502     add_subdirectory(lua)
503   elseif(LIBA_LUAJIT AND LUAJIT_FOUND)
504     add_subdirectory(lua)
505   elseif(LIBA_WITH_LUA)
506     add_subdirectory(lua)
507   endif()
508 endif()
510 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/python/CMakeLists.txt)
511   if(LIBA_PYTHON AND PYTHON_FOUND)
512     add_subdirectory(python)
513   endif()
514 endif()
516 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/quickjs/CMakeLists.txt)
517   option(LIBA_QUICKJS "Enable/Disable quickjs" 0)
519   if(LIBA_QUICKJS)
520     find_package(QuickJS)
521   endif()
523   if(LIBA_QUICKJS AND QUICKJS_FOUND)
524     add_subdirectory(quickjs)
525   endif()
526 endif()
528 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/swig/CMakeLists.txt)
529   option(LIBA_SWIG "Enable/Disable swig" 0)
531   if(LIBA_SWIG)
532     if(POLICY CMP0078) # 3.13
533       cmake_policy(SET CMP0078 NEW)
534     endif() # UseSWIG_TARGET_NAME_PREFERENCE
536     if(POLICY CMP0086) # 3.14
537       cmake_policy(SET CMP0086 NEW)
538     endif() # SWIG_MODULE_NAME
540     find_package(SWIG)
541   endif()
543   if(LIBA_SWIG AND SWIG_FOUND)
544     add_subdirectory(swig)
545   endif()
546 endif()
548 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/test/CMakeLists.txt)
549   if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
550     add_subdirectory(test)
551   endif()
552 endif()
554 set(CPACK_SOURCE_IGNORE_FILES
555   ${CMAKE_CURRENT_LIST_DIR}/.git
556   ${CMAKE_CURRENT_LIST_DIR}/.cache
557   ${CMAKE_CURRENT_LIST_DIR}/.vscode
558   ${CMAKE_CURRENT_LIST_DIR}/.github
559   ${CMAKE_CURRENT_LIST_DIR}/.gitignore
560   ${CMAKE_CURRENT_LIST_DIR}/.gitmodules
561   ${CMAKE_CURRENT_LIST_DIR}/.gitattributes
562   ${PROJECT_BINARY_DIR}
564 set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_LIST_DIR}/README.md)
565 set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_LIST_DIR}/LICENSE.txt)
566 include(CPack)
568 if(PROJECT_IS_TOP_LEVEL)
569   find_package(ClangFormat)
570   find_package(Black)
571 endif()
573 if(CLANG_FORMAT_FOUND)
574   file_scaner(SOURCES RECURSE include src test java/src javascript/src lua/src quickjs/src EXT c h cc hh cpp hpp)
575   add_clang_format(aformat VERBOSE ${SOURCES})
576   add_dependencies(afmt aformat)
577 endif()
579 if(BLACK_FOUND)
580   add_black(ablack ${CMAKE_CURRENT_LIST_DIR})
581   add_dependencies(afmt ablack)
582 endif()
584 if(PYTHON_FOUND)
585   add_custom_target(apip # https://pip.readthedocs.io/en/stable
586     ${PYTHON_EXECUTABLE} -m pip install -r ${CMAKE_CURRENT_LIST_DIR}/requirements.txt
587     COMMENT "${PYTHON_EXECUTABLE} -m pip install -r requirements.txt"
588   )
589 endif()
591 if(PYTHON_FOUND AND CYTHON_FOUND)
592   set(OPTIONS)
594   if(NOT CMAKE_VERSION VERSION_LESS 3.2)
595     file_scaner(SOURCES RECURSE python/src EXT c h cc hh cpp hpp)
596     list(APPEND OPTIONS BYPRODUCTS ${SOURCES})
597     file(GLOB PRODUCTS ${PROJECT_NAME}*.so ${PROJECT_NAME}*.pyd)
598     list(APPEND OPTIONS ${PRODUCTS})
599     file(GLOB_RECURSE PRODUCTS build/lib.*/*.* build/temp.*/*.*)
600     list(APPEND OPTIONS ${PRODUCTS})
601     set(PRODUCTS)
602   endif()
604   add_custom_target(apy ALL # https://cython.readthedocs.io/en/stable
605     ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/setup.py ${OPTIONS}
606   )
607   set(OPTIONS)
608 endif()
610 if(NOT CMAKE_VERSION VERSION_LESS 3.9 AND DOXYGEN_FOUND)
611   # Project related configuration options
612   set(DOXYGEN_CREATE_SUBDIRS YES)
613   set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
615   # Build related configuration options
616   # Configuration options related to warning and progress messages
617   set(DOXYGEN_WARN_IF_UNDOCUMENTED NO)
618   set(DOXYGEN_WARN_NO_PARAMDOC YES)
620   # Configuration options related to the input files
621   set(DOXYGEN_RECURSIVE YES)
623   # Configuration options related to source browsing
624   # Configuration options related to the alphabetical class index
625   # Configuration options related to the HTML output
626   set(DOXYGEN_GENERATE_HTML YES)
627   set(DOXYGEN_USE_MATHJAX YES)
628   set(DOXYGEN_MATHJAX_VERSION MathJax_3)
630   # Configuration options related to the LaTeX output
631   # Configuration options related to the RTF output
632   # Configuration options related to the man page output
633   # Configuration options related to the XML output
634   set(DOXYGEN_GENERATE_XML YES)
636   # Configuration options related to the DOCBOOK output
637   # Configuration options for the AutoGen Definitions output
638   # Configuration options related to Sqlite3 output
639   # Configuration options related to the Perl module output
640   # Configuration options related to the preprocessor
641   set(DOXYGEN_MACRO_EXPANSION YES)
642   set(DOXYGEN_PREDEFINED
643     "__STDC_VERSION__=201112L"
644     "__cplusplus=201103L"
645     "A_BYTE_ORDER=1234"
646     "A_SIZE_POINTER=8"
647     "A_EXTERN:="
648     "A_INTERN:="
649     "A_PUBLIC:="
650     "A_HIDDEN:="
651   )
653   file(STRINGS "${A_HAVE_H}" macros REGEX "#define[ ]+A_HAVE_.+")
655   foreach(macro ${macros})
656     string(REGEX REPLACE "#define[ ]+(.*)[ ]+(.+)" "\\1=\\2" macro "${macro}")
657     list(APPEND DOXYGEN_PREDEFINED ${macro})
658   endforeach()
660   # Configuration options related to external references
661   # Configuration options related to the dot tool
662   if(Doxygen_dot_FOUND)
663     set(DOXYGEN_HAVE_DOT YES)
664     set(DOXYGEN_INTERACTIVE_SVG YES)
665     set(DOXYGEN_DOT_IMAGE_FORMAT svg)
666     set(DOXYGEN_DOT_MULTI_TARGETS YES)
667   endif()
669   # https://www.doxygen.nl/manual/config.html
670   doxygen_add_docs(adoxygen WORKING_DIRECTORY
671     ${CMAKE_CURRENT_LIST_DIR}/include/a
672     ${CMAKE_CURRENT_LIST_DIR}/include/a
673     ${CMAKE_CURRENT_LIST_DIR}/README.md
674   )
675   add_dependencies(adoc adoxygen)
676 endif()