enable analyzer on CI
[liba.git] / CMakeLists.txt
blob6de86034c4724e1bd205aea0054115fba5d45c20
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_STATIC "Enable/Disable finding and linking static libraries" 0)
20 if(LIBA_STATIC)
21   include(cmake/CMakeFindLibraryStatic.cmake)
22 endif()
24 option(LIBA_WARNINGS "Enable/Disable warnings" 0)
26 if(LIBA_WARNINGS)
27   include(cmake/TargetWarnings.cmake)
28 endif()
30 option(LIBA_ANALYZER "Enable/Disable analyzer" 0)
32 if(LIBA_ANALYZER)
33   include(cmake/TargetAnalyzer.cmake)
34 endif()
36 option(LIBA_SANITIZE "Enable/Disable sanitize" 0)
38 if(LIBA_SANITIZE)
39   include(cmake/TargetSanitize.cmake)
40 endif()
42 if(LIBA_STATIC)
43   include(cmake/TargetStatic.cmake)
44 endif()
46 option(LIBA_CCACHE "Enable/Disable ccache" 0)
48 if(LIBA_CCACHE)
49   include(cmake/UseCCache.cmake)
50 endif()
52 if(UNIX)
53   set(LIBA_MATH "m" CACHE FILEPATH "system math library")
54 else()
55   set(LIBA_MATH "" CACHE FILEPATH "system math library")
56 endif()
58 include(CheckLibraryExists)
59 set(LIBA_FLOAT 8 CACHE STRING "floating-point number bytes")
60 set_property(CACHE LIBA_FLOAT PROPERTY STRINGS 4 8 16)
62 function(check_math VARIABLE FUNCTION)
63   get_filename_component(LOCATION "${LIBA_MATH}" DIRECTORY)
64   list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBA_MATH})
66   if(LIBA_FLOAT GREATER 8)
67     set(FUNCTION ${FUNCTION}l)
68   elseif(LIBA_FLOAT EQUAL 4)
69     set(FUNCTION ${FUNCTION}f)
70   endif()
72   check_library_exists("${LIBA_MATH}"
73     ${FUNCTION} "${LOCATION}" ${VARIABLE}
74   )
75 endfunction()
77 check_math(A_HAVE_EXPM1 expm1)
78 check_math(A_HAVE_LOG1P log1p)
79 check_math(A_HAVE_HYPOT hypot)
80 check_math(A_HAVE_ATAN2 atan2)
81 check_math(A_HAVE_CSQRT csqrt)
82 check_math(A_HAVE_CPOW cpow)
83 check_math(A_HAVE_CEXP cexp)
84 check_math(A_HAVE_CLOG clog)
85 check_math(A_HAVE_CSIN csin)
86 check_math(A_HAVE_CCOS ccos)
87 check_math(A_HAVE_CTAN ctan)
88 check_math(A_HAVE_CSINH csinh)
89 check_math(A_HAVE_CCOSH ccosh)
90 check_math(A_HAVE_CTANH ctanh)
91 check_math(A_HAVE_CASIN casin)
92 check_math(A_HAVE_CACOS cacos)
93 check_math(A_HAVE_CATAN catan)
94 check_math(A_HAVE_CASINH casinh)
95 check_math(A_HAVE_CACOSH cacosh)
96 check_math(A_HAVE_CATANH catanh)
98 option(LIBA_PYTHON "Enable/Disable python" 0)
100 if(LIBA_PYTHON)
101   find_package(Python COMPONENTS Interpreter)
102   find_package(Cython)
103 endif()
105 option(LIBA_DOXYGEN "Enable/Disable doxygen" 0)
107 if(LIBA_DOXYGEN)
108   find_package(Doxygen OPTIONAL_COMPONENTS dot mscgen dia)
109 endif()
111 option(LIBA_CPPCHECK "Enable/Disable cppcheck" 0)
113 if(LIBA_CPPCHECK)
114   find_package(cppcheck)
115 endif()
117 option(LIBA_CLANG_TIDY "Enable/Disable clang-tidy" 0)
119 if(LIBA_CLANG_TIDY)
120   find_package(ClangTidy)
121 endif()
123 option(LIBA_IWYU "Enable/Disable include-what-you-use" 0)
125 if(LIBA_IWYU)
126   find_package(IWYU)
127 endif()
129 option(LIBA_IPO "Enable/Disable interprocedural optimization" 0)
131 # https://cmake.org/cmake/help/latest/module/CheckIPOSupported.html
132 if(NOT CMAKE_VERSION VERSION_LESS 3.9 AND LIBA_IPO)
133   cmake_policy(SET CMP0069 NEW)
134   include(CheckIPOSupported)
135   check_ipo_supported(RESULT LIBA_IPO)
136 endif()
138 if(DEFINED ENV{ANDROID_ROOT} AND EXISTS $ENV{ANDROID_ROOT})
139   option(LIBA_PIE "Enable/Disable position independent code" 1)
140 else()
141   option(LIBA_PIE "Enable/Disable position independent code" 0)
142 endif()
144 # https://cmake.org/cmake/help/latest/module/CheckPIESupported.html
145 if(NOT CMAKE_VERSION VERSION_LESS 3.14)
146   cmake_policy(SET CMP0083 NEW)
147   include(CheckPIESupported)
148   check_pie_supported()
149 endif()
151 function(set_library_options)
152   if(LIBA_IWYU AND IWYU_FOUND)
153     add_include_what_you_use(TARGETS ${ARGN})
154   endif()
156   if(LIBA_CLANG_TIDY AND CLANG_TIDY_FOUND)
157     add_clang_tidy(TARGETS ${ARGN} OPTIONS --fix)
158   endif()
160   if(LIBA_CPPCHECK AND CPPCHECK_FOUND)
161     add_cppcheck(TARGETS ${ARGN} OPTIONS --enable=warning,performance)
162   endif()
164   if(CMAKE_C_COMPILER_ID MATCHES "TinyCC" AND CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL .lib)
165     set_property(TARGET ${ARGN} PROPERTY IMPORT_SUFFIX .def)
166   endif()
168   set_target_properties(${ARGN} PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${LIBA_IPO}
169     C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1
170   )
172   if(LIBA_WARNINGS)
173     target_compile_warnings(${ARGN})
174   endif()
176   if(LIBA_ANALYZER)
177     target_compile_analyzer(${ARGN})
178   endif()
179 endfunction()
181 function(add_library_properties target scope source)
182   target_compile_definitions(${target} ${scope} $<TARGET_PROPERTY:${source},${ARGV3}COMPILE_DEFINITIONS>)
183   target_include_directories(${target} ${scope} $<TARGET_PROPERTY:${source},${ARGV3}INCLUDE_DIRECTORIES>)
185   if(${scope} MATCHES "PUBLIC|PRIVATE")
186     set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES $<TARGET_PROPERTY:${source},${ARGV3}LINK_LIBRARIES>)
187   endif()
189   if(${scope} MATCHES "PUBLIC|INTERFACE")
190     set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<TARGET_PROPERTY:${source},${ARGV3}LINK_LIBRARIES>)
191   endif()
192 endfunction()
194 option(LIBA_MIMALLOC "Enable/Disable override using mimalloc" 0)
196 if(LIBA_MIMALLOC)
197   find_package(mimalloc)
198 endif()
200 if(mimalloc_FOUND)
201   if(TARGET mimalloc-static)
202     set(MIMALLOC_LIBRARY mimalloc-static)
203   else()
204     set(MIMALLOC_LIBRARY mimalloc)
205   endif()
206 endif()
208 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/.git)
209   find_package(Git)
211   if(GIT_FOUND)
212     function(git_command output)
213       execute_process(ERROR_QUIET
214         COMMAND ${GIT_EXECUTABLE} ${ARGN}
215         OUTPUT_STRIP_TRAILING_WHITESPACE
216         OUTPUT_VARIABLE ${output}
217       )
218       set(${output} ${${output}} PARENT_SCOPE)
219     endfunction()
221     git_command(GIT_COMMIT_LONG log -1 --pretty=format:%H)
222     git_command(GIT_COMMIT_DATE log -1 --pretty=format:%cd --date=format:%Y%m%d)
223   endif()
225   if(GIT_COMMIT_DATE)
226     set(${PROJECT_NAME}_VERSION_TWEAK ${GIT_COMMIT_DATE})
227     set(PROJECT_VERSION_TWEAK ${GIT_COMMIT_DATE})
228     set(A_VERSION_TWEAK ${GIT_COMMIT_DATE})
229   endif()
230 endif()
232 if(NOT EXISTS "${A_HAVE_H}")
233   set(A_HAVE_H ${CMAKE_CURRENT_BINARY_DIR}/a.cmake.h)
234   configure_file(${CMAKE_CURRENT_LIST_DIR}/include/a.cmake.h.in ${A_HAVE_H})
235 endif()
237 if(IS_ABSOLUTE "${LIBA_MATH}")
238   get_filename_component(math ${LIBA_MATH} NAME_WE)
239   string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}(.+)" "\\1" math "${math}")
240   set(LIBA_MATH $<BUILD_INTERFACE:${LIBA_MATH}> $<INSTALL_INTERFACE:${math}>)
241   set(math)
242 endif()
244 if(TARGET_SUPPORTS_SYMBOLIC_LINK)
245   option(LIBA_SYMLINK "Enable/Disable symbolic link" 1)
246 endif()
248 function(set_library_compile target)
249   if(EXISTS "${A_HAVE_H}")
250     file(RELATIVE_PATH a_have_h ${PROJECT_SOURCE_DIR}/include/a ${A_HAVE_H})
251     target_compile_definitions(${target} PUBLIC $<BUILD_INTERFACE:A_HAVE_H="${a_have_h}">)
252     set(a_have_h)
253   endif()
255   if((LIBA_SYMLINK OR WIN32) AND TARGET_SUPPORTS_SYMBOLIC_LINK)
256     set_target_properties(${target} PROPERTIES SOVERSION
257       ${PROJECT_VERSION_MAJOR} VERSION ${PROJECT_VERSION}
258     )
259   endif()
261   set_target_properties(${target} PROPERTIES OUTPUT_NAME a
262     POSITION_INDEPENDENT_CODE 1 DEFINE_SYMBOL A_EXPORTS
263   )
264   target_compile_definitions(${target} PRIVATE A_EXPORTS)
265   target_include_directories(${target} BEFORE PUBLIC
266     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
267     $<INSTALL_INTERFACE:include>
268   )
269   get_property(TYPE TARGET ${target} PROPERTY TYPE)
271   if(${TYPE} MATCHES "(STATIC|SHARED|MODULE)_LIBRARY")
272     target_link_libraries(${target} PUBLIC ${LIBA_MATH})
273   endif()
275   set_library_options(${target})
276 endfunction()
278 if(LIBA_CXX)
279   file_scaner(SOURCES RECURSE include src EXT c h cc hh cpp hpp)
280 else()
281   file_scaner(SOURCES RECURSE include src EXT c h)
282 endif()
284 add_library(a OBJECT ${SOURCES})
285 set_library_compile(a)
287 if(LIBA_MIMALLOC AND mimalloc_FOUND)
288   set_property(SOURCE ${CMAKE_CURRENT_LIST_DIR}/src/a.c
289     APPEND PROPERTY COMPILE_DEFINITIONS A_HAVE_MIMALLOC_H
290   )
292   if(CMAKE_VERSION VERSION_LESS 3.12)
293     add_library_properties(a PUBLIC ${MIMALLOC_LIBRARY} INTERFACE_)
294   else()
295     target_link_libraries(a PUBLIC ${MIMALLOC_LIBRARY})
296   endif()
297 endif()
299 include(GNUInstallDirs)
300 set(INSTALL_TARGETS "")
301 set(LIBA_INSTALL "" CACHE STRING "Specify the installation")
303 if(NOT LIBA_INSTALL)
304   list(APPEND INSTALL_TARGETS alib)
305 endif()
307 add_library(alib STATIC $<TARGET_OBJECTS:a>)
308 set_library_compile(alib)
310 if(LIBA_MIMALLOC AND mimalloc_FOUND)
311   target_link_libraries(alib PUBLIC ${MIMALLOC_LIBRARY})
312 endif()
314 if(TARGET_SUPPORTS_SHARED_LIBS)
315   if(NOT LIBA_INSTALL)
316     list(APPEND INSTALL_TARGETS liba)
317   endif()
319   add_library(liba SHARED $<TARGET_OBJECTS:a>)
320   set_library_compile(liba)
322   if(LIBA_MIMALLOC AND mimalloc_FOUND)
323     target_link_libraries(liba PUBLIC ${MIMALLOC_LIBRARY})
324   endif()
326   if(CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL .lib)
327     set_property(TARGET liba PROPERTY OUTPUT_NAME liba)
328   endif()
330   target_compile_definitions(liba INTERFACE A_IMPORTS)
332   if(LIBA_STATIC)
333     target_link_static(liba)
334   endif()
335 endif()
337 if(LIBA_SANITIZE)
338   add_library(asan OBJECT ${SOURCES})
339   set_library_compile(asan)
340   target_compile_sanitize(asan)
342   if(LIBA_MIMALLOC AND mimalloc_FOUND)
343     if(CMAKE_VERSION VERSION_LESS 3.12)
344       add_library_properties(asan PUBLIC ${MIMALLOC_LIBRARY} INTERFACE_)
345     else()
346       target_link_libraries(asan PUBLIC ${MIMALLOC_LIBRARY})
347     endif()
348   endif()
350   if(TARGET_SUPPORTS_SHARED_LIBS)
351     add_library(libasan SHARED $<TARGET_OBJECTS:asan>)
352     set_library_compile(libasan)
354     set_property(TARGET libasan PROPERTY OUTPUT_NAME a.san)
355     target_compile_definitions(libasan INTERFACE A_IMPORTS)
356     target_link_sanitize(libasan)
358     if(LIBA_MIMALLOC AND mimalloc_FOUND)
359       target_link_libraries(libasan PUBLIC ${MIMALLOC_LIBRARY})
360     endif()
362     if(LIBA_STATIC)
363       target_link_static(libasan)
364     endif()
365   endif()
366 endif()
368 if(TARGET_SUPPORTS_RELOCATABLE)
369   file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/lib/CMakeLists.txt "get_cmake_property(ENABLED_LANGUAGES ENABLED_LANGUAGES)
370 foreach(LANG \${ENABLED_LANGUAGES})
371 \tset(CMAKE_\${LANG}_CREATE_STATIC_LIBRARY \"\")
372 \tset(CMAKE_\${LANG}_LINK_EXECUTABLE
373 \t\t\"<CMAKE_\${LANG}_COMPILER> <FLAGS> -nostdlib -o <TARGET>.o -r <OBJECTS>\"
374 \t\t\"\${CMAKE_COMMAND} -E copy <TARGET>.o <TARGET>\"
376 endforeach()
377 set(CMAKE_EXECUTABLE_SUFFIX \"\")
378 set(CMAKE_STATIC_LIBRARY_SUFFIX .o)
379 set(CMAKE_STATIC_LIBRARY_PREFIX lib)
380 add_executable(a.o \$<TARGET_OBJECTS:a>)
381 add_library(liba.o STATIC \$<TARGET_OBJECTS:a>)
382 set_library_compile(liba.o)\nadd_dependencies(liba.o a.o)
383 set_target_properties(a.o PROPERTIES OUTPUT_NAME liba
384 \tINTERPROCEDURAL_OPTIMIZATION \${LIBA_IPO}
386 if(LIBA_MIMALLOC AND mimalloc_FOUND)
387 \ttarget_link_libraries(liba.o PUBLIC ${MIMALLOC_LIBRARY})
388 endif()
389 if(NOT LIBA_INSTALL)
390 \tinstall(TARGETS liba.o EXPORT \${PROJECT_NAME}-targets
391 \t\tARCHIVE DESTINATION \${CMAKE_INSTALL_LIBDIR}
392 \t\tLIBRARY DESTINATION \${CMAKE_INSTALL_LIBDIR}
393 \t)\nendif()")
394   add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/lib lib)
395 else()
396   add_library(liba.o ALIAS alib)
397 endif()
399 if(INSTALL_TARGETS)
400   include(cmake/InstallTargets.cmake)
401   install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/a DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
403   if(EXISTS "${A_HAVE_H}")
404     install(FILES ${A_HAVE_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/a)
405     install_fixup(${CMAKE_INSTALL_INCLUDEDIR}/a/a.h A_HAVE_H ${A_HAVE_H})
406   endif()
407 endif()
409 option(LIBA_PKGCONFIG "Enable/Disable pkgconfig" 0)
411 if(LIBA_PKGCONFIG)
412   include(cmake/InstallPkgConfig.cmake)
413   install_pkgconfig(${PROJECT_NAME} alib)
414 endif()
416 option(LIBA_LIBTOOL "Enable/Disable libtool" 0)
418 if(LIBA_LIBTOOL AND INSTALL_TARGETS)
419   include(cmake/InstallLibtool.cmake)
420   install_libtool(${INSTALL_TARGETS})
421 endif()
423 option(LIBA_VCPKG "Enable/Disable vcpkg" 0)
425 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/vcpkg AND LIBA_VCPKG AND GIT_COMMIT_LONG)
426   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vcpkg DESTINATION ${CMAKE_INSTALL_DATADIR})
427   configure_file(
428     ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/portfile.cmake
429     ${CMAKE_CURRENT_BINARY_DIR}/vcpkg/ports/${PROJECT_NAME}/portfile.cmake
430     @ONLY
431   )
432   configure_file(
433     ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/vcpkg.json
434     ${CMAKE_CURRENT_BINARY_DIR}/vcpkg/ports/${PROJECT_NAME}/vcpkg.json
435     @ONLY
436   )
437 endif()
439 if(PROJECT_IS_TOP_LEVEL)
440   add_custom_target(afmt)
441   add_custom_target(adoc)
442   include(CTest)
443 endif()
445 if(NOT CMAKE_FIND_LIBRARY_PREFIXES)
446   set(CMAKE_FIND_LIBRARY_PREFIXES ";lib")
447 endif()
449 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/java/CMakeLists.txt)
450   option(LIBA_JAVA "Enable/Disable java" 0)
452   if(LIBA_JAVA)
453     find_package(Java)
454     find_package(JNI)
455   endif()
457   if(LIBA_JAVA AND Java_JAVAC_EXECUTABLE)
458     add_subdirectory(java)
459   endif()
460 endif()
462 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/javascript/CMakeLists.txt)
463   if(EMSCRIPTEN)
464     option(LIBA_JAVASCRIPT "Enable/Disable javascript" 1)
465   else()
466     option(LIBA_JAVASCRIPT "Enable/Disable javascript" 0)
467   endif()
469   if(LIBA_JAVASCRIPT)
470     if(NOT EMSCRIPTEN)
471       find_package(Emscripten)
472     endif()
474     if(EMSCRIPTEN OR EMSCRIPTEN_FOUND)
475       add_subdirectory(javascript)
476     endif()
477   endif()
478 endif()
480 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/lua/CMakeLists.txt)
481   option(LIBA_LUA "Enable/Disable lua" 0)
482   option(LIBA_LUAJIT "Enable/Disable luajit" 0)
483   option(LIBA_WITH_LUA "Enable/Disable build with lua" 0)
485   if(LIBA_LUA OR LIBA_LUAJIT OR LIBA_WITH_LUA)
486     set(LUA_MATH_LIBRARY ${LIBA_MATH} CACHE STRING "lua math library")
487   endif()
489   if(NOT LIBA_WITH_LUA AND LIBA_LUA)
490     find_package(Lua OPTIONAL_COMPONENTS lua)
491     set(LUA_LIBRARIES lualib)
492   endif()
494   if((LIBA_LUA AND NOT LUA_FOUND AND NOT LIBA_WITH_LUA) OR LIBA_LUAJIT)
495     find_package(LuaJIT OPTIONAL_COMPONENTS luajit)
496     set(LUA_EXECUTABLE ${LUAJIT_EXECUTABLE})
497     set(LUA_LIBRARIES luajit)
498   endif()
500   if(LIBA_LUA AND LUA_FOUND)
501     add_subdirectory(lua)
502   elseif(LIBA_LUAJIT AND LUAJIT_FOUND)
503     add_subdirectory(lua)
504   elseif(LIBA_WITH_LUA)
505     add_subdirectory(lua)
506   endif()
507 endif()
509 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/python/CMakeLists.txt)
510   if(LIBA_PYTHON AND PYTHON_FOUND)
511     add_subdirectory(python)
512   endif()
513 endif()
515 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/quickjs/CMakeLists.txt)
516   option(LIBA_QUICKJS "Enable/Disable quickjs" 0)
518   if(LIBA_QUICKJS)
519     find_package(QuickJS)
520   endif()
522   if(LIBA_QUICKJS AND QUICKJS_FOUND)
523     add_subdirectory(quickjs)
524   endif()
525 endif()
527 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/test/CMakeLists.txt)
528   if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
529     add_subdirectory(test)
530   endif()
531 endif()
533 set(CPACK_SOURCE_IGNORE_FILES
534   ${CMAKE_CURRENT_LIST_DIR}/.git
535   ${CMAKE_CURRENT_LIST_DIR}/.cache
536   ${CMAKE_CURRENT_LIST_DIR}/.vscode
537   ${CMAKE_CURRENT_LIST_DIR}/.github
538   ${CMAKE_CURRENT_LIST_DIR}/.gitignore
539   ${CMAKE_CURRENT_LIST_DIR}/.gitmodules
540   ${CMAKE_CURRENT_LIST_DIR}/.gitattributes
541   ${PROJECT_BINARY_DIR}
543 set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_LIST_DIR}/README.md)
544 set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_LIST_DIR}/LICENSE.txt)
545 include(CPack)
547 if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
548   find_package(ClangFormat)
549 endif()
551 if(CLANG_FORMAT_FOUND)
552   file_scaner(SOURCES RECURSE include src test java/src javascript/src lua/src quickjs/src EXT c h cc hh cpp hpp)
553   add_clang_format(afmt.c VERBOSE ${SOURCES})
554   add_dependencies(afmt afmt.c)
555 endif()
557 if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING AND LIBA_PYTHON)
558   find_package(Black)
559 endif()
561 if(PYTHON_FOUND AND BLACK_FOUND)
562   add_black(afmt.py ${CMAKE_CURRENT_LIST_DIR})
563   add_dependencies(afmt afmt.py)
564 endif()
566 if(PYTHON_FOUND AND CYTHON_FOUND)
567   set(OPTIONS)
569   if(NOT CMAKE_VERSION VERSION_LESS 3.2)
570     file_scaner(SOURCES RECURSE python/src EXT c h cc hh cpp hpp)
571     list(APPEND OPTIONS BYPRODUCTS ${SOURCES})
572     file(GLOB PRODUCTS ${PROJECT_NAME}*.so ${PROJECT_NAME}*.pyd)
573     list(APPEND OPTIONS ${PRODUCTS})
574     file(GLOB_RECURSE PRODUCTS build/lib.*/*.* build/temp.*/*.*)
575     list(APPEND OPTIONS ${PRODUCTS})
576     set(PRODUCTS)
577   endif()
579   add_custom_target(apy ALL # https://cython.readthedocs.io/en/stable
580     ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/setup.py ${OPTIONS}
581   )
582   set(OPTIONS)
583 endif()
585 if(NOT CMAKE_VERSION VERSION_LESS 3.9 AND DOXYGEN_FOUND)
586   # Project related configuration options
587   set(DOXYGEN_CREATE_SUBDIRS YES)
588   set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
590   # Build related configuration options
591   set(DOXYGEN_EXTRACT_STATIC YES)
593   # Configuration options related to warning and progress messages
594   set(DOXYGEN_WARN_IF_UNDOCUMENTED NO)
595   set(DOXYGEN_WARN_NO_PARAMDOC YES)
597   # Configuration options related to the input files
598   set(DOXYGEN_RECURSIVE YES)
600   # Configuration options related to source browsing
601   # Configuration options related to the alphabetical class index
602   # Configuration options related to the HTML output
603   set(DOXYGEN_GENERATE_HTML YES)
604   set(DOXYGEN_USE_MATHJAX YES)
605   set(DOXYGEN_MATHJAX_VERSION MathJax_3)
607   # Configuration options related to the LaTeX output
608   # Configuration options related to the RTF output
609   # Configuration options related to the man page output
610   # Configuration options related to the XML output
611   set(DOXYGEN_GENERATE_XML YES)
613   # Configuration options related to the DOCBOOK output
614   # Configuration options for the AutoGen Definitions output
615   # Configuration options related to Sqlite3 output
616   # Configuration options related to the Perl module output
617   # Configuration options related to the preprocessor
618   set(DOXYGEN_MACRO_EXPANSION YES)
619   set(DOXYGEN_PREDEFINED
620     "__STDC_VERSION__=201112L"
621     "__cplusplus=201103L"
622     "A_BYTE_ORDER=1234"
623     "A_SIZE_POINTER=8"
624     "A_INLINE:=inline"
625     "A_EXTERN:="
626     "A_INTERN:="
627     "A_PUBLIC:="
628     "A_HIDDEN:="
629   )
631   file(STRINGS "${A_HAVE_H}" macros REGEX "#define[ ]+A_HAVE_.+")
633   foreach(macro ${macros})
634     string(REGEX REPLACE "#define[ ]+(.*)[ ]+(.+)" "\\1=\\2" macro "${macro}")
635     list(APPEND DOXYGEN_PREDEFINED ${macro})
636   endforeach()
638   # Configuration options related to external references
639   # Configuration options related to the dot tool
640   if(Doxygen_dot_FOUND)
641     set(DOXYGEN_HAVE_DOT YES)
642     set(DOXYGEN_INTERACTIVE_SVG YES)
643     set(DOXYGEN_DOT_IMAGE_FORMAT svg)
644     set(DOXYGEN_DOT_MULTI_TARGETS YES)
645   endif()
647   # https://www.doxygen.nl/manual/config.html
648   doxygen_add_docs(adoc.c WORKING_DIRECTORY
649     ${CMAKE_CURRENT_LIST_DIR}/include/a
650     ${CMAKE_CURRENT_LIST_DIR}/include/a
651     ${CMAKE_CURRENT_LIST_DIR}/README.md
652   )
653   add_dependencies(adoc adoc.c)
654 endif()