optimize implementation
[liba.git] / CMakeLists.txt
blob3a1622db38468d75da7ef50a10dd78436458506c
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_EXPM1 expm1)
75 check_math(A_HAVE_LOG1P log1p)
76 check_math(A_HAVE_HYPOT hypot)
77 check_math(A_HAVE_ATAN2 atan2)
78 check_math(A_HAVE_CSQRT csqrt)
79 check_math(A_HAVE_CPOW cpow)
80 check_math(A_HAVE_CEXP cexp)
81 check_math(A_HAVE_CLOG clog)
82 check_math(A_HAVE_CSIN csin)
83 check_math(A_HAVE_CCOS ccos)
84 check_math(A_HAVE_CTAN ctan)
85 check_math(A_HAVE_CSINH csinh)
86 check_math(A_HAVE_CCOSH ccosh)
87 check_math(A_HAVE_CTANH ctanh)
88 check_math(A_HAVE_CASIN casin)
89 check_math(A_HAVE_CACOS cacos)
90 check_math(A_HAVE_CATAN catan)
91 check_math(A_HAVE_CASINH casinh)
92 check_math(A_HAVE_CACOSH cacosh)
93 check_math(A_HAVE_CATANH catanh)
95 option(LIBA_PYTHON "Enable/Disable python" 0)
97 if(LIBA_PYTHON)
98   find_package(Python COMPONENTS Interpreter)
99   find_package(Cython)
100 endif()
102 option(LIBA_DOXYGEN "Enable/Disable doxygen" 0)
104 if(LIBA_DOXYGEN)
105   find_package(Doxygen OPTIONAL_COMPONENTS dot mscgen dia)
106 endif()
108 option(LIBA_CPPCHECK "Enable/Disable cppcheck" 0)
110 if(LIBA_CPPCHECK)
111   find_package(cppcheck)
112 endif()
114 option(LIBA_CLANG_TIDY "Enable/Disable clang-tidy" 0)
116 if(LIBA_CLANG_TIDY)
117   find_package(ClangTidy)
118 endif()
120 option(LIBA_IWYU "Enable/Disable include-what-you-use" 0)
122 if(LIBA_IWYU)
123   find_package(IWYU)
124 endif()
126 option(LIBA_IPO "Enable/Disable interprocedural optimization" 0)
128 # https://cmake.org/cmake/help/latest/module/CheckIPOSupported.html
129 if(NOT CMAKE_VERSION VERSION_LESS 3.9 AND LIBA_IPO)
130   cmake_policy(SET CMP0069 NEW)
131   include(CheckIPOSupported)
132   check_ipo_supported(RESULT LIBA_IPO)
133 endif()
135 if(DEFINED ENV{ANDROID_ROOT} AND EXISTS $ENV{ANDROID_ROOT})
136   option(LIBA_PIE "Enable/Disable position independent code" 1)
137 else()
138   option(LIBA_PIE "Enable/Disable position independent code" 0)
139 endif()
141 # https://cmake.org/cmake/help/latest/module/CheckPIESupported.html
142 if(NOT CMAKE_VERSION VERSION_LESS 3.14)
143   cmake_policy(SET CMP0083 NEW)
144   include(CheckPIESupported)
145   check_pie_supported()
146 endif()
148 function(set_library_options)
149   if(LIBA_IWYU AND IWYU_FOUND)
150     add_include_what_you_use(TARGETS ${ARGN})
151   endif()
153   if(LIBA_CLANG_TIDY AND CLANG_TIDY_FOUND)
154     add_clang_tidy(TARGETS ${ARGN} OPTIONS --fix)
155   endif()
157   if(LIBA_CPPCHECK AND CPPCHECK_FOUND)
158     add_cppcheck(TARGETS ${ARGN} OPTIONS --enable=warning,performance)
159   endif()
161   if(CMAKE_C_COMPILER_ID MATCHES "TinyCC" AND CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL .lib)
162     set_property(TARGET ${ARGN} PROPERTY IMPORT_SUFFIX .def)
163   endif()
165   set_target_properties(${ARGN} PROPERTIES INTERPROCEDURAL_OPTIMIZATION ${LIBA_IPO}
166     C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1
167   )
169   if(LIBA_WARNINGS)
170     target_compile_warnings(${ARGN})
171   endif()
173   if(LIBA_ANALYZER)
174     target_compile_analyzer(${ARGN})
175   endif()
176 endfunction()
178 function(add_library_properties target scope source)
179   target_compile_definitions(${target} ${scope} $<TARGET_PROPERTY:${source},${ARGV3}COMPILE_DEFINITIONS>)
180   target_include_directories(${target} ${scope} $<TARGET_PROPERTY:${source},${ARGV3}INCLUDE_DIRECTORIES>)
182   if(${scope} MATCHES "PUBLIC|PRIVATE")
183     set_property(TARGET ${target} APPEND PROPERTY LINK_LIBRARIES $<TARGET_PROPERTY:${source},${ARGV3}LINK_LIBRARIES>)
184   endif()
186   if(${scope} MATCHES "PUBLIC|INTERFACE")
187     set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<TARGET_PROPERTY:${source},${ARGV3}LINK_LIBRARIES>)
188   endif()
189 endfunction()
191 option(LIBA_MIMALLOC "Enable/Disable override using mimalloc" 0)
193 if(LIBA_MIMALLOC)
194   find_package(mimalloc)
195 endif()
197 if(mimalloc_FOUND)
198   if(TARGET mimalloc-static)
199     set(MIMALLOC_LIBRARY mimalloc-static)
200   else()
201     set(MIMALLOC_LIBRARY mimalloc)
202   endif()
203 endif()
205 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/.git)
206   find_package(Git)
208   if(GIT_FOUND)
209     function(git_command output)
210       execute_process(ERROR_QUIET
211         COMMAND ${GIT_EXECUTABLE} ${ARGN}
212         OUTPUT_STRIP_TRAILING_WHITESPACE
213         OUTPUT_VARIABLE ${output}
214       )
215       set(${output} ${${output}} PARENT_SCOPE)
216     endfunction()
218     git_command(GIT_COMMIT_LONG log -1 --pretty=format:%H)
219     git_command(GIT_COMMIT_DATE log -1 --pretty=format:%cd --date=format:%Y%m%d)
220   endif()
222   if(GIT_COMMIT_DATE)
223     set(${PROJECT_NAME}_VERSION_TWEAK ${GIT_COMMIT_DATE})
224     set(PROJECT_VERSION_TWEAK ${GIT_COMMIT_DATE})
225     set(A_VERSION_TWEAK ${GIT_COMMIT_DATE})
226   endif()
227 endif()
229 if(NOT EXISTS "${A_HAVE_H}")
230   set(A_HAVE_H ${CMAKE_CURRENT_BINARY_DIR}/a.cmake.h)
231   configure_file(${CMAKE_CURRENT_LIST_DIR}/include/a.cmake.h.in ${A_HAVE_H})
232 endif()
234 if(IS_ABSOLUTE "${LIBA_MATH}")
235   get_filename_component(math ${LIBA_MATH} NAME_WE)
236   string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}(.+)" "\\1" math "${math}")
237   set(LIBA_MATH $<BUILD_INTERFACE:${LIBA_MATH}> $<INSTALL_INTERFACE:${math}>)
238   set(math)
239 endif()
241 if(TARGET_SUPPORTS_SYMBOLIC_LINK)
242   option(LIBA_SYMLINK "Enable/Disable symbolic link" 1)
243 endif()
245 function(set_library_compile target)
246   if(EXISTS "${A_HAVE_H}")
247     file(RELATIVE_PATH a_have_h ${PROJECT_SOURCE_DIR}/include/a ${A_HAVE_H})
248     target_compile_definitions(${target} PUBLIC $<BUILD_INTERFACE:A_HAVE_H="${a_have_h}">)
249     set(a_have_h)
250   endif()
252   if((LIBA_SYMLINK OR WIN32) AND TARGET_SUPPORTS_SYMBOLIC_LINK)
253     set_target_properties(${target} PROPERTIES SOVERSION
254       ${PROJECT_VERSION_MAJOR} VERSION ${PROJECT_VERSION}
255     )
256   endif()
258   set_target_properties(${target} PROPERTIES OUTPUT_NAME a
259     POSITION_INDEPENDENT_CODE 1 DEFINE_SYMBOL A_EXPORTS
260   )
261   target_compile_definitions(${target} PRIVATE A_EXPORTS)
262   target_include_directories(${target} BEFORE PUBLIC
263     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
264     $<INSTALL_INTERFACE:include>
265   )
266   get_property(TYPE TARGET ${target} PROPERTY TYPE)
268   if(${TYPE} MATCHES "(STATIC|SHARED|MODULE)_LIBRARY")
269     target_link_libraries(${target} PUBLIC ${LIBA_MATH})
270   endif()
272   set_library_options(${target})
273 endfunction()
275 if(LIBA_CXX)
276   file_scaner(SOURCES RECURSE include src EXT c h cc hh cpp hpp)
277 else()
278   file_scaner(SOURCES RECURSE include src EXT c h)
279 endif()
281 add_library(a OBJECT ${SOURCES})
282 set_library_compile(a)
284 if(LIBA_MIMALLOC AND mimalloc_FOUND)
285   set_property(SOURCE ${CMAKE_CURRENT_LIST_DIR}/src/a.c
286     APPEND PROPERTY COMPILE_DEFINITIONS A_HAVE_MIMALLOC_H
287   )
289   if(CMAKE_VERSION VERSION_LESS 3.12)
290     add_library_properties(a PUBLIC ${MIMALLOC_LIBRARY} INTERFACE_)
291   else()
292     target_link_libraries(a PUBLIC ${MIMALLOC_LIBRARY})
293   endif()
294 endif()
296 include(GNUInstallDirs)
297 set(INSTALL_TARGETS "")
298 set(LIBA_INSTALL "" CACHE STRING "Specify the installation")
300 if(NOT LIBA_INSTALL)
301   list(APPEND INSTALL_TARGETS alib)
302 endif()
304 add_library(alib STATIC $<TARGET_OBJECTS:a>)
305 set_library_compile(alib)
307 if(LIBA_MIMALLOC AND mimalloc_FOUND)
308   target_link_libraries(alib PUBLIC ${MIMALLOC_LIBRARY})
309 endif()
311 if(TARGET_SUPPORTS_SHARED_LIBS)
312   if(NOT LIBA_INSTALL)
313     list(APPEND INSTALL_TARGETS liba)
314   endif()
316   add_library(liba SHARED $<TARGET_OBJECTS:a>)
317   set_library_compile(liba)
319   if(LIBA_MIMALLOC AND mimalloc_FOUND)
320     target_link_libraries(liba PUBLIC ${MIMALLOC_LIBRARY})
321   endif()
323   if(CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL .lib)
324     set_property(TARGET liba PROPERTY OUTPUT_NAME liba)
325   endif()
327   target_compile_definitions(liba INTERFACE A_IMPORTS)
329   if(LIBA_STATIC)
330     target_link_static(liba)
331   endif()
332 endif()
334 if(LIBA_SANITIZE)
335   add_library(asan OBJECT ${SOURCES})
336   set_library_compile(asan)
337   target_compile_sanitize(asan)
339   if(LIBA_MIMALLOC AND mimalloc_FOUND)
340     if(CMAKE_VERSION VERSION_LESS 3.12)
341       add_library_properties(asan PUBLIC ${MIMALLOC_LIBRARY} INTERFACE_)
342     else()
343       target_link_libraries(asan PUBLIC ${MIMALLOC_LIBRARY})
344     endif()
345   endif()
347   if(TARGET_SUPPORTS_SHARED_LIBS)
348     add_library(libasan SHARED $<TARGET_OBJECTS:asan>)
349     set_library_compile(libasan)
351     set_property(TARGET libasan PROPERTY OUTPUT_NAME a.san)
352     target_compile_definitions(libasan INTERFACE A_IMPORTS)
353     target_link_sanitize(libasan)
355     if(LIBA_MIMALLOC AND mimalloc_FOUND)
356       target_link_libraries(libasan PUBLIC ${MIMALLOC_LIBRARY})
357     endif()
359     if(LIBA_STATIC)
360       target_link_static(libasan)
361     endif()
362   endif()
363 endif()
365 if(TARGET_SUPPORTS_RELOCATABLE)
366   file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/lib/CMakeLists.txt "get_cmake_property(ENABLED_LANGUAGES ENABLED_LANGUAGES)
367 foreach(LANG \${ENABLED_LANGUAGES})
368 \tset(CMAKE_\${LANG}_CREATE_STATIC_LIBRARY \"\")
369 \tset(CMAKE_\${LANG}_LINK_EXECUTABLE
370 \t\t\"<CMAKE_\${LANG}_COMPILER> <FLAGS> -nostdlib -o <TARGET>.o -r <OBJECTS>\"
371 \t\t\"\${CMAKE_COMMAND} -E copy <TARGET>.o <TARGET>\"
373 endforeach()
374 set(CMAKE_EXECUTABLE_SUFFIX \"\")
375 set(CMAKE_STATIC_LIBRARY_SUFFIX .o)
376 set(CMAKE_STATIC_LIBRARY_PREFIX lib)
377 add_executable(a.o \$<TARGET_OBJECTS:a>)
378 add_library(liba.o STATIC \$<TARGET_OBJECTS:a>)
379 set_library_compile(liba.o)\nadd_dependencies(liba.o a.o)
380 set_target_properties(a.o PROPERTIES OUTPUT_NAME liba
381 \tINTERPROCEDURAL_OPTIMIZATION \${LIBA_IPO}
383 if(LIBA_MIMALLOC AND mimalloc_FOUND)
384 \ttarget_link_libraries(liba.o PUBLIC ${MIMALLOC_LIBRARY})
385 endif()
386 if(NOT LIBA_INSTALL)
387 \tinstall(TARGETS liba.o EXPORT \${PROJECT_NAME}-targets
388 \t\tARCHIVE DESTINATION \${CMAKE_INSTALL_LIBDIR}
389 \t\tLIBRARY DESTINATION \${CMAKE_INSTALL_LIBDIR}
390 \t)\nendif()")
391   add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/lib lib)
392 else()
393   add_library(liba.o ALIAS alib)
394 endif()
396 if(INSTALL_TARGETS)
397   include(cmake/InstallTargets.cmake)
398   install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/a DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
400   if(EXISTS "${A_HAVE_H}")
401     install(FILES ${A_HAVE_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/a)
402     install_fixup(${CMAKE_INSTALL_INCLUDEDIR}/a/a.h A_HAVE_H ${A_HAVE_H})
403   endif()
404 endif()
406 option(LIBA_PKGCONFIG "Enable/Disable pkgconfig" 0)
408 if(LIBA_PKGCONFIG)
409   include(cmake/InstallPkgConfig.cmake)
410   install_pkgconfig(${PROJECT_NAME} alib)
411 endif()
413 option(LIBA_LIBTOOL "Enable/Disable libtool" 0)
415 if(LIBA_LIBTOOL AND INSTALL_TARGETS)
416   include(cmake/InstallLibtool.cmake)
417   install_libtool(${INSTALL_TARGETS})
418 endif()
420 option(LIBA_VCPKG "Enable/Disable vcpkg" 0)
422 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/vcpkg AND LIBA_VCPKG AND GIT_COMMIT_LONG)
423   install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vcpkg DESTINATION ${CMAKE_INSTALL_DATADIR})
424   configure_file(
425     ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/portfile.cmake
426     ${CMAKE_CURRENT_BINARY_DIR}/vcpkg/ports/${PROJECT_NAME}/portfile.cmake
427     @ONLY
428   )
429   configure_file(
430     ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/vcpkg.json
431     ${CMAKE_CURRENT_BINARY_DIR}/vcpkg/ports/${PROJECT_NAME}/vcpkg.json
432     @ONLY
433   )
434 endif()
436 if(PROJECT_IS_TOP_LEVEL)
437   add_custom_target(afmt)
438   add_custom_target(adoc)
439   include(CTest)
440 endif()
442 if(NOT CMAKE_FIND_LIBRARY_PREFIXES)
443   set(CMAKE_FIND_LIBRARY_PREFIXES ";lib")
444 endif()
446 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/java/CMakeLists.txt)
447   option(LIBA_JAVA "Enable/Disable java" 0)
449   if(LIBA_JAVA)
450     find_package(Java)
451     find_package(JNI)
452   endif()
454   if(LIBA_JAVA AND Java_JAVAC_EXECUTABLE)
455     add_subdirectory(java)
456   endif()
457 endif()
459 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/javascript/CMakeLists.txt)
460   if(EMSCRIPTEN)
461     option(LIBA_JAVASCRIPT "Enable/Disable javascript" 1)
462   else()
463     option(LIBA_JAVASCRIPT "Enable/Disable javascript" 0)
464   endif()
466   if(LIBA_JAVASCRIPT)
467     if(NOT EMSCRIPTEN)
468       find_package(Emscripten)
469     endif()
471     if(EMSCRIPTEN OR EMSCRIPTEN_FOUND)
472       add_subdirectory(javascript)
473     endif()
474   endif()
475 endif()
477 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/lua/CMakeLists.txt)
478   option(LIBA_LUA "Enable/Disable lua" 0)
479   option(LIBA_LUAJIT "Enable/Disable luajit" 0)
480   option(LIBA_WITH_LUA "Enable/Disable build with lua" 0)
482   if(LIBA_LUA OR LIBA_LUAJIT OR LIBA_WITH_LUA)
483     set(LUA_MATH_LIBRARY ${LIBA_MATH} CACHE STRING "lua math library")
484   endif()
486   if(NOT LIBA_WITH_LUA AND LIBA_LUA)
487     find_package(Lua OPTIONAL_COMPONENTS lua)
488     set(LUA_LIBRARIES lualib)
489   endif()
491   if((LIBA_LUA AND NOT LUA_FOUND AND NOT LIBA_WITH_LUA) OR LIBA_LUAJIT)
492     find_package(LuaJIT OPTIONAL_COMPONENTS luajit)
493     set(LUA_EXECUTABLE ${LUAJIT_EXECUTABLE})
494     set(LUA_LIBRARIES luajit)
495   endif()
497   if(LIBA_LUA AND LUA_FOUND)
498     add_subdirectory(lua)
499   elseif(LIBA_LUAJIT AND LUAJIT_FOUND)
500     add_subdirectory(lua)
501   elseif(LIBA_WITH_LUA)
502     add_subdirectory(lua)
503   endif()
504 endif()
506 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/python/CMakeLists.txt)
507   if(LIBA_PYTHON AND PYTHON_FOUND)
508     add_subdirectory(python)
509   endif()
510 endif()
512 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/quickjs/CMakeLists.txt)
513   option(LIBA_QUICKJS "Enable/Disable quickjs" 0)
515   if(LIBA_QUICKJS)
516     find_package(QuickJS)
517   endif()
519   if(LIBA_QUICKJS AND QUICKJS_FOUND)
520     add_subdirectory(quickjs)
521   endif()
522 endif()
524 if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/test/CMakeLists.txt)
525   if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
526     add_subdirectory(test)
527   endif()
528 endif()
530 set(CPACK_SOURCE_IGNORE_FILES
531   ${CMAKE_CURRENT_LIST_DIR}/.git
532   ${CMAKE_CURRENT_LIST_DIR}/.cache
533   ${CMAKE_CURRENT_LIST_DIR}/.vscode
534   ${CMAKE_CURRENT_LIST_DIR}/.github
535   ${CMAKE_CURRENT_LIST_DIR}/.gitignore
536   ${CMAKE_CURRENT_LIST_DIR}/.gitmodules
537   ${CMAKE_CURRENT_LIST_DIR}/.gitattributes
538   ${PROJECT_BINARY_DIR}
540 set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_LIST_DIR}/README.md)
541 set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_LIST_DIR}/LICENSE.txt)
542 include(CPack)
544 if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
545   find_package(ClangFormat)
546 endif()
548 if(CLANG_FORMAT_FOUND)
549   file_scaner(SOURCES RECURSE include src test java/src javascript/src lua/src quickjs/src EXT c h cc hh cpp hpp)
550   add_clang_format(afmt.c VERBOSE ${SOURCES})
551   add_dependencies(afmt afmt.c)
552 endif()
554 if(PROJECT_IS_TOP_LEVEL AND BUILD_TESTING AND LIBA_PYTHON)
555   find_package(Black)
556 endif()
558 if(PYTHON_FOUND AND BLACK_FOUND)
559   add_black(afmt.py ${CMAKE_CURRENT_LIST_DIR})
560   add_dependencies(afmt afmt.py)
561 endif()
563 if(PYTHON_FOUND AND CYTHON_FOUND)
564   set(OPTIONS)
566   if(NOT CMAKE_VERSION VERSION_LESS 3.2)
567     file_scaner(SOURCES RECURSE python/src EXT c h cc hh cpp hpp)
568     list(APPEND OPTIONS BYPRODUCTS ${SOURCES})
569     file(GLOB PRODUCTS ${PROJECT_NAME}*.so ${PROJECT_NAME}*.pyd)
570     list(APPEND OPTIONS ${PRODUCTS})
571     file(GLOB_RECURSE PRODUCTS build/lib.*/*.* build/temp.*/*.*)
572     list(APPEND OPTIONS ${PRODUCTS})
573     set(PRODUCTS)
574   endif()
576   add_custom_target(apy ALL # https://cython.readthedocs.io/en/stable
577     ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/setup.py ${OPTIONS}
578   )
579   set(OPTIONS)
580 endif()
582 if(NOT CMAKE_VERSION VERSION_LESS 3.9 AND DOXYGEN_FOUND)
583   # Project related configuration options
584   set(DOXYGEN_CREATE_SUBDIRS YES)
585   set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
587   # Build related configuration options
588   set(DOXYGEN_EXTRACT_STATIC YES)
590   # Configuration options related to warning and progress messages
591   set(DOXYGEN_WARN_IF_UNDOCUMENTED NO)
592   set(DOXYGEN_WARN_NO_PARAMDOC YES)
594   # Configuration options related to the input files
595   set(DOXYGEN_RECURSIVE YES)
597   # Configuration options related to source browsing
598   # Configuration options related to the alphabetical class index
599   # Configuration options related to the HTML output
600   set(DOXYGEN_GENERATE_HTML YES)
601   set(DOXYGEN_USE_MATHJAX YES)
602   set(DOXYGEN_MATHJAX_VERSION MathJax_3)
604   # Configuration options related to the LaTeX output
605   # Configuration options related to the RTF output
606   # Configuration options related to the man page output
607   # Configuration options related to the XML output
608   set(DOXYGEN_GENERATE_XML YES)
610   # Configuration options related to the DOCBOOK output
611   # Configuration options for the AutoGen Definitions output
612   # Configuration options related to Sqlite3 output
613   # Configuration options related to the Perl module output
614   # Configuration options related to the preprocessor
615   set(DOXYGEN_MACRO_EXPANSION YES)
616   set(DOXYGEN_PREDEFINED
617     "__STDC_VERSION__=201112L"
618     "__cplusplus=201103L"
619     "A_BYTE_ORDER=1234"
620     "A_SIZE_POINTER=8"
621     "A_INLINE:=inline"
622     "A_EXTERN:="
623     "A_INTERN:="
624     "A_PUBLIC:="
625     "A_HIDDEN:="
626   )
628   file(STRINGS "${A_HAVE_H}" macros REGEX "#define[ ]+A_HAVE_.+")
630   foreach(macro ${macros})
631     string(REGEX REPLACE "#define[ ]+(.*)[ ]+(.+)" "\\1=\\2" macro "${macro}")
632     list(APPEND DOXYGEN_PREDEFINED ${macro})
633   endforeach()
635   # Configuration options related to external references
636   # Configuration options related to the dot tool
637   if(Doxygen_dot_FOUND)
638     set(DOXYGEN_HAVE_DOT YES)
639     set(DOXYGEN_INTERACTIVE_SVG YES)
640     set(DOXYGEN_DOT_IMAGE_FORMAT svg)
641     set(DOXYGEN_DOT_MULTI_TARGETS YES)
642   endif()
644   # https://www.doxygen.nl/manual/config.html
645   doxygen_add_docs(adoc.c WORKING_DIRECTORY
646     ${CMAKE_CURRENT_LIST_DIR}/include/a
647     ${CMAKE_CURRENT_LIST_DIR}/include/a
648     ${CMAKE_CURRENT_LIST_DIR}/README.md
649   )
650   add_dependencies(adoc adoc.c)
651 endif()