CMakeLists.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. cmake_minimum_required(VERSION 3.16)
  2. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/Meta/CMake")
  3. project(SerenityOS C CXX ASM)
  4. if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "")
  5. message(FATAL_ERROR
  6. ": Don't use CMAKE_BUILD_TYPE when building serenity.\n"
  7. "The default build type is optimized with debug info and asserts enabled,\n"
  8. "and that's all there is.")
  9. endif()
  10. if(NOT CMAKE_SYSTEM_NAME STREQUAL "SerenityOS")
  11. message(FATAL_ERROR "System name is not SerenityOS, this is unsupported.\n"
  12. "Please re-read the BuildInstructions documentation, and use the superbuild configuration\n")
  13. endif()
  14. # Check for toolchain mismatch, user might need to rebuild toolchain
  15. set(GCC_VERSION "11.2.0")
  16. set(LLVM_VERSION "13.0.0")
  17. if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  18. set(EXPECTED_COMPILER_VERSION "${GCC_VERSION}")
  19. else()
  20. set(EXPECTED_COMPILER_VERSION "${LLVM_VERSION}")
  21. endif()
  22. if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "${EXPECTED_COMPILER_VERSION}")
  23. message(FATAL_ERROR "${CMAKE_CXX_COMPILER_ID} version (${CMAKE_CXX_COMPILER_VERSION}) does not match "
  24. "expected compiler version (${EXPECTED_COMPILER_VERSION}).\n"
  25. "Please rebuild the ${CMAKE_CXX_COMPILER_ID} Toolchain\n")
  26. endif()
  27. set(CMAKE_INSTALL_MESSAGE NEVER)
  28. set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
  29. if(NOT COMMAND serenity_option)
  30. macro(serenity_option)
  31. set(${ARGV})
  32. endmacro()
  33. endif()
  34. include(serenity_options)
  35. find_program(CCACHE_PROGRAM ccache)
  36. if(CCACHE_PROGRAM)
  37. set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE FILEPATH "Path to a compiler launcher program, e.g. ccache")
  38. set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE FILEPATH "Path to a compiler launcher program, e.g. ccache")
  39. endif()
  40. # FIXME: With cmake 3.18, we can change unzip/untar steps to use
  41. # file(ARCHIVE_EXTRACT) instead
  42. find_program(UNZIP unzip REQUIRED)
  43. find_program(TAR tar REQUIRED)
  44. # Host tools, required to generate files for the build
  45. find_package(Lagom CONFIG REQUIRED)
  46. # Meta target to run all code-gen steps in the build.
  47. add_custom_target(all_generated)
  48. add_custom_target(run
  49. COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_ARCH=${SERENITY_ARCH}" "${SerenityOS_SOURCE_DIR}/Meta/run.sh"
  50. USES_TERMINAL
  51. )
  52. # This can currently only be implemented by ordered commands
  53. # as cmake doesn't support inter dependency ordering, and we
  54. # would like to avoid inject dependencies on the existing
  55. # custom commands to allow people to run commands adhoc with
  56. # out forcing re-builds when they might not want them.
  57. add_custom_target(setup-and-run
  58. COMMAND ${CMAKE_MAKE_PROGRAM} install
  59. COMMAND ${CMAKE_MAKE_PROGRAM} image
  60. COMMAND ${CMAKE_MAKE_PROGRAM} run
  61. USES_TERMINAL
  62. )
  63. add_custom_target(image
  64. DEPENDS qemu-image
  65. )
  66. add_custom_target(qemu-image
  67. COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-qemu.sh"
  68. BYPRODUCTS "${CMAKE_BINARY_DIR}/_disk_image"
  69. USES_TERMINAL
  70. )
  71. add_custom_target(grub-image
  72. COMMAND ${CMAKE_COMMAND} -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-grub.sh"
  73. BYPRODUCTS ${CMAKE_BINARY_DIR}/grub_disk_image
  74. USES_TERMINAL
  75. )
  76. add_custom_target(extlinux-image
  77. COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-extlinux.sh"
  78. BYPRODUCTS "${CMAKE_BINARY_DIR}/extlinux_disk_image"
  79. USES_TERMINAL
  80. )
  81. add_custom_target(lint-shell-scripts
  82. COMMAND "${SerenityOS_SOURCE_DIR}/Meta/lint-shell-scripts.sh"
  83. USES_TERMINAL
  84. )
  85. add_custom_target(check-style
  86. COMMAND "${SerenityOS_SOURCE_DIR}/Meta/check-style.sh"
  87. USES_TERMINAL
  88. )
  89. add_custom_target(install-ports
  90. COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "${SerenityOS_SOURCE_DIR}/Meta/install-ports-tree.sh"
  91. USES_TERMINAL
  92. )
  93. add_custom_target(configure-components
  94. COMMAND "$<TARGET_FILE:Lagom::ConfigureComponents>"
  95. USES_TERMINAL
  96. )
  97. add_dependencies(configure-components Lagom::ConfigureComponents)
  98. set(CMAKE_CXX_STANDARD 20)
  99. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  100. set(CMAKE_CXX_EXTENSIONS OFF)
  101. if (ENABLE_ALL_DEBUG_FACILITIES)
  102. set(ENABLE_ALL_THE_DEBUG_MACROS ON)
  103. set(ENABLE_EXTRA_KERNEL_DEBUG_SYMBOLS ON)
  104. # Immediately finds violations during boot, shouldn't be discoverable
  105. # by people who aren't working on fixing issues. Use this check to make
  106. # sure this code continues to build instead of all_debug_macros to avoid
  107. # people filing bugs.
  108. set(KMALLOC_VERIFY_NO_SPINLOCK_HELD ON)
  109. # Enables KCOV API and injects kernel coverage instrumentation via
  110. # -fsanitize-coverage=trace-pc. Mostly here to ensure that the CI catches
  111. # commits breaking this flag.
  112. set(ENABLE_KERNEL_COVERAGE_COLLECTION ON)
  113. endif()
  114. if (ENABLE_ALL_THE_DEBUG_MACROS)
  115. include(all_the_debug_macros)
  116. endif(ENABLE_ALL_THE_DEBUG_MACROS)
  117. configure_file(AK/Debug.h.in AK/Debug.h @ONLY)
  118. configure_file(Kernel/Debug.h.in Kernel/Debug.h @ONLY)
  119. set(CMAKE_STAGING_PREFIX ${CMAKE_BINARY_DIR}/Root)
  120. set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Root)
  121. set(CMAKE_INSTALL_DATAROOTDIR ${CMAKE_BINARY_DIR}/Root/res)
  122. # We disable it completely because it makes cmake very spammy.
  123. # This will need to be revisited when the Loader supports RPATH/RUN_PATH.
  124. set(CMAKE_SKIP_RPATH TRUE)
  125. add_compile_options(-Wall)
  126. add_compile_options(-Wextra)
  127. if (NOT CMAKE_HOST_SYSTEM_NAME MATCHES SerenityOS)
  128. # FIXME: Something makes this go crazy and flag unused variables that aren't flagged as such when building with the toolchain.
  129. # Disable -Werror for now.
  130. add_compile_options(-Werror)
  131. endif()
  132. # The following warnings are sorted by the "base" name (the part excluding the initial Wno or W).
  133. add_compile_options(-Wno-address-of-packed-member)
  134. add_compile_options(-Wcast-qual)
  135. add_compile_options(-Wdeprecated-copy)
  136. add_compile_options(-Wduplicated-cond)
  137. add_compile_options(-Wformat=2)
  138. add_compile_options(-Wimplicit-fallthrough)
  139. add_compile_options(-Wlogical-op)
  140. add_compile_options(-Wmisleading-indentation)
  141. add_compile_options(-Wmissing-declarations)
  142. add_compile_options(-Wnon-virtual-dtor)
  143. add_compile_options(-Wsuggest-override)
  144. add_compile_options(-Wno-unknown-warning-option)
  145. add_compile_options(-Wundef)
  146. add_compile_options(-Wunused)
  147. add_compile_options(-Wno-unused-command-line-argument)
  148. add_compile_options(-Wwrite-strings)
  149. add_compile_options(-fdiagnostics-color=always)
  150. add_compile_options(-fno-delete-null-pointer-checks)
  151. add_compile_options(-ffile-prefix-map=${SerenityOS_SOURCE_DIR}=.)
  152. add_compile_options(-fno-exceptions)
  153. add_compile_options(-fno-semantic-interposition)
  154. add_compile_options(-fsized-deallocation)
  155. add_compile_options(-fstack-clash-protection)
  156. add_compile_options(-fstack-protector-strong)
  157. add_compile_options(-g1)
  158. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  159. add_compile_options(-Wno-literal-suffix)
  160. add_compile_options(-Wno-maybe-uninitialized)
  161. # Only ignore expansion-to-defined for g++, clang's implementation doesn't complain about function-like macros
  162. add_compile_options(-Wno-expansion-to-defined)
  163. add_compile_options(-Wcast-align)
  164. add_compile_options(-Wdouble-promotion)
  165. elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang$")
  166. add_compile_options(-Wno-user-defined-literals)
  167. add_compile_options(-Wno-atomic-alignment)
  168. add_compile_options(-Wno-implicit-const-int-float-conversion)
  169. add_compile_options(-Wno-unused-const-variable)
  170. add_compile_options(-Wno-unused-private-field)
  171. add_compile_options(-fconstexpr-steps=16777216)
  172. # Clang doesn't add compiler_rt to the search path when compiling with -nostdlib.
  173. link_directories(${TOOLCHAIN_ROOT}/lib/clang/${CMAKE_CXX_COMPILER_VERSION}/lib/${SERENITY_ARCH}-pc-serenity/)
  174. add_link_options(LINKER:--allow-shlib-undefined)
  175. endif()
  176. add_link_options(LINKER:-z,text)
  177. add_compile_definitions(SANITIZE_PTRS)
  178. set(CMAKE_CXX_FLAGS_STATIC "${CMAKE_CXX_FLAGS} -static")
  179. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pie -fpic")
  180. if (ENABLE_COMPILETIME_FORMAT_CHECK)
  181. add_compile_definitions(ENABLE_COMPILETIME_FORMAT_CHECK)
  182. endif()
  183. add_link_options(-Wno-unused-command-line-argument)
  184. include_directories(.)
  185. include_directories(Userland/Libraries)
  186. include_directories(Userland/Libraries/LibC)
  187. include_directories(Userland/Libraries/LibCrypt)
  188. include_directories(Userland/Libraries/LibM)
  189. include_directories(Userland/Libraries/LibPthread)
  190. include_directories(Userland/Libraries/LibSystem)
  191. include_directories(Userland/Services)
  192. include_directories(Userland)
  193. include_directories(${CMAKE_CURRENT_BINARY_DIR})
  194. include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland/Services)
  195. include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland/Libraries)
  196. include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland)
  197. # FIXME: vptr sanitizing requires.. intense ABI wrangling of std::type_info
  198. # And would be better served by porting ubsan_type_hash_itanium.cpp from compiler-rt
  199. if (ENABLE_UNDEFINED_SANITIZER)
  200. add_compile_options(-fsanitize=undefined -fno-sanitize=vptr)
  201. add_link_options(-fsanitize=undefined -fno-sanitize=vptr)
  202. endif()
  203. add_custom_target(components ALL)
  204. option(BUILD_EVERYTHING "Build all optional components" ON)
  205. include(utils)
  206. include(wasm_spec_tests)
  207. serenity_component(
  208. Tests
  209. RECOMMENDED
  210. )
  211. add_subdirectory(AK)
  212. add_subdirectory(Kernel)
  213. if(NOT "${SERENITY_ARCH}" STREQUAL "aarch64")
  214. add_subdirectory(Userland)
  215. add_subdirectory(Tests)
  216. endif()
  217. if (ENABLE_COMPILETIME_HEADER_CHECK)
  218. add_subdirectory(Meta/HeaderCheck)
  219. endif()
  220. export_components("${CMAKE_BINARY_DIR}/components.ini")
  221. set(PCI_IDS_FILE pci.ids)
  222. set(PCI_IDS_GZ_URL https://pci-ids.ucw.cz/v2.2/${PCI_IDS_FILE}.gz)
  223. set(PCI_IDS_GZ_PATH ${CMAKE_BINARY_DIR}/${PCI_IDS_FILE}.gz)
  224. set(PCI_IDS_PATH ${CMAKE_BINARY_DIR}/${PCI_IDS_FILE})
  225. set(PCI_IDS_INSTALL_PATH ${CMAKE_INSTALL_DATAROOTDIR}/${PCI_IDS_FILE})
  226. if(ENABLE_PCI_IDS_DOWNLOAD AND NOT EXISTS ${PCI_IDS_GZ_PATH})
  227. message(STATUS "Downloading PCI ID database from ${PCI_IDS_GZ_URL}...")
  228. file(DOWNLOAD ${PCI_IDS_GZ_URL} ${PCI_IDS_GZ_PATH} INACTIVITY_TIMEOUT 10)
  229. endif()
  230. if(EXISTS ${PCI_IDS_GZ_PATH} AND NOT EXISTS ${PCI_IDS_INSTALL_PATH})
  231. message(STATUS "Extracting PCI ID database from ${PCI_IDS_GZ_PATH}...")
  232. file(MAKE_DIRECTORY ${CMAKE_INSTALL_DATAROOTDIR})
  233. execute_process(COMMAND gzip -d -c "${PCI_IDS_GZ_PATH}" OUTPUT_FILE "${PCI_IDS_INSTALL_PATH}")
  234. endif()
  235. set(USB_IDS_FILE usb.ids)
  236. set(USB_IDS_GZ_URL http://www.linux-usb.org/${USB_IDS_FILE}.gz)
  237. set(USB_IDS_GZ_PATH ${CMAKE_BINARY_DIR}/${USB_IDS_FILE}.gz)
  238. set(USB_IDS_PATH ${CMAKE_BINARY_DIR}/${USB_IDS_FILE})
  239. set(USB_IDS_INSTALL_PATH ${CMAKE_INSTALL_DATAROOTDIR}/${USB_IDS_FILE})
  240. if(ENABLE_USB_IDS_DOWNLOAD AND NOT EXISTS ${USB_IDS_GZ_PATH})
  241. message(STATUS "Downloading USB ID database from ${USB_IDS_GZ_URL}...")
  242. file(DOWNLOAD ${USB_IDS_GZ_URL} ${USB_IDS_GZ_PATH} INACTIVITY_TIMEOUT 10)
  243. endif()
  244. if(EXISTS ${USB_IDS_GZ_PATH} AND NOT EXISTS ${USB_IDS_INSTALL_PATH})
  245. message(STATUS "Extracting USB ID database from ${USB_IDS_GZ_PATH}...")
  246. file(MAKE_DIRECTORY ${CMAKE_INSTALL_DATAROOTDIR})
  247. execute_process(COMMAND gzip -d -c "${USB_IDS_GZ_PATH}" OUTPUT_FILE "${USB_IDS_INSTALL_PATH}")
  248. endif()