utils.cmake 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. include(${CMAKE_CURRENT_LIST_DIR}/serenity_components.cmake)
  2. include(${CMAKE_CURRENT_LIST_DIR}/code_generators.cmake)
  3. include(${CMAKE_CURRENT_LIST_DIR}/unicode_data.cmake)
  4. function(serenity_install_headers target_name)
  5. file(GLOB_RECURSE headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
  6. foreach(header ${headers})
  7. get_filename_component(subdirectory ${header} DIRECTORY)
  8. install(FILES ${header} DESTINATION usr/include/${target_name}/${subdirectory} OPTIONAL)
  9. endforeach()
  10. endfunction()
  11. function(serenity_install_sources)
  12. string(LENGTH ${SerenityOS_SOURCE_DIR} root_source_dir_length)
  13. string(SUBSTRING ${CMAKE_CURRENT_SOURCE_DIR} ${root_source_dir_length} -1 current_source_dir_relative)
  14. file(GLOB_RECURSE sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h" "*.cpp")
  15. foreach(source ${sources})
  16. get_filename_component(subdirectory ${source} DIRECTORY)
  17. install(FILES ${source} DESTINATION usr/src/serenity/${current_source_dir_relative}/${subdirectory} OPTIONAL)
  18. endforeach()
  19. endfunction()
  20. function(serenity_generated_sources target_name)
  21. if(DEFINED GENERATED_SOURCES)
  22. set_source_files_properties(${GENERATED_SOURCES} PROPERTIES GENERATED 1)
  23. foreach(generated ${GENERATED_SOURCES})
  24. get_filename_component(generated_name ${generated} NAME)
  25. add_dependencies(${target_name} generate_${generated_name})
  26. add_dependencies(all_generated generate_${generated_name})
  27. endforeach()
  28. endif()
  29. endfunction()
  30. function(serenity_lib target_name fs_name)
  31. serenity_install_headers(${target_name})
  32. serenity_install_sources()
  33. add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES})
  34. set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
  35. set_target_properties(${target_name} PROPERTIES VERSION "serenity")
  36. install(TARGETS ${target_name} DESTINATION usr/lib OPTIONAL)
  37. set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
  38. serenity_generated_sources(${target_name})
  39. endfunction()
  40. function(serenity_libc target_name fs_name)
  41. serenity_install_headers("")
  42. serenity_install_sources()
  43. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib -fpic")
  44. add_library(${target_name} SHARED ${SOURCES})
  45. install(TARGETS ${target_name} DESTINATION usr/lib)
  46. set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
  47. # Avoid creating a dependency cycle between system libraries and the C++ standard library. This is necessary
  48. # to ensure that initialization functions will be called in the right order (libc++ must come after LibPthread).
  49. if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  50. target_link_options(${target_name} PRIVATE -static-libstdc++)
  51. elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang$")
  52. target_link_libraries(${target_name} clang_rt.builtins)
  53. # FIXME: Implement -static-libstdc++ in the next toolchain update.
  54. target_link_options(${target_name} PRIVATE -nostdlib++ -Wl,-Bstatic -lc++ -Wl,-Bdynamic)
  55. target_link_options(${target_name} PRIVATE -Wl,--no-dependent-libraries)
  56. endif()
  57. target_link_directories(LibC PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
  58. serenity_generated_sources(${target_name})
  59. endfunction()
  60. function(serenity_libc_static target_name fs_name)
  61. serenity_install_headers("")
  62. serenity_install_sources("Userland/Libraries/LibC")
  63. add_library(${target_name} ${SOURCES})
  64. set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
  65. install(TARGETS ${target_name} ARCHIVE DESTINATION usr/lib OPTIONAL)
  66. set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
  67. target_link_directories(${target_name} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
  68. serenity_generated_sources(${target_name})
  69. endfunction()
  70. function(serenity_bin target_name)
  71. serenity_install_sources()
  72. add_executable(${target_name} ${SOURCES})
  73. set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
  74. install(TARGETS ${target_name} RUNTIME DESTINATION bin OPTIONAL)
  75. serenity_generated_sources(${target_name})
  76. endfunction()
  77. function(serenity_test test_src sub_dir)
  78. cmake_parse_arguments(PARSE_ARGV 2 SERENITY_TEST "MAIN_ALREADY_DEFINED" "CUSTOM_MAIN" "LIBS")
  79. set(TEST_SOURCES ${test_src})
  80. if ("${SERENITY_TEST_CUSTOM_MAIN}" STREQUAL "")
  81. set(SERENITY_TEST_CUSTOM_MAIN "$<TARGET_OBJECTS:LibTestMain>")
  82. endif()
  83. if (NOT ${SERENITY_TEST_MAIN_ALREADY_DEFINED})
  84. list(PREPEND TEST_SOURCES "${SERENITY_TEST_CUSTOM_MAIN}")
  85. endif()
  86. get_filename_component(test_name ${test_src} NAME_WE)
  87. add_executable(${test_name} ${TEST_SOURCES})
  88. add_dependencies(ComponentTests ${test_name})
  89. set_target_properties(${test_name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
  90. target_link_libraries(${test_name} LibTest LibCore)
  91. foreach(lib ${SERENITY_TEST_LIBS})
  92. target_link_libraries(${test_name} ${lib})
  93. endforeach()
  94. install(TARGETS ${test_name} RUNTIME DESTINATION usr/Tests/${sub_dir} OPTIONAL)
  95. endfunction()
  96. function(serenity_testjs_test test_src sub_dir)
  97. cmake_parse_arguments(PARSE_ARGV 2 SERENITY_TEST "" "CUSTOM_MAIN" "LIBS")
  98. if ("${SERENITY_TEST_CUSTOM_MAIN}" STREQUAL "")
  99. set(SERENITY_TEST_CUSTOM_MAIN "$<TARGET_OBJECTS:JavaScriptTestRunnerMain>")
  100. endif()
  101. list(APPEND SERENITY_TEST_LIBS LibJS LibCore)
  102. serenity_test(${test_src} ${sub_dir}
  103. CUSTOM_MAIN "${SERENITY_TEST_CUSTOM_MAIN}"
  104. LIBS ${SERENITY_TEST_LIBS})
  105. endfunction()
  106. function(serenity_app target_name)
  107. cmake_parse_arguments(PARSE_ARGV 1 SERENITY_APP "" "ICON" "")
  108. serenity_bin("${target_name}")
  109. set(small_icon "${SerenityOS_SOURCE_DIR}/Base/res/icons/16x16/${SERENITY_APP_ICON}.png")
  110. set(medium_icon "${SerenityOS_SOURCE_DIR}/Base/res/icons/32x32/${SERENITY_APP_ICON}.png")
  111. if (EXISTS "${small_icon}")
  112. embed_resource("${target_name}" serenity_icon_s "${small_icon}")
  113. else()
  114. message(FATAL_ERROR "Missing small app icon: ${small_icon}")
  115. endif()
  116. if (EXISTS "${medium_icon}")
  117. embed_resource("${target_name}" serenity_icon_m "${medium_icon}")
  118. else()
  119. # These icons are designed small only for use in applets, and thus are exempt.
  120. list(APPEND allowed_missing_medium_icons "audio-volume-high")
  121. list(APPEND allowed_missing_medium_icons "edit-copy")
  122. if (NOT ${SERENITY_APP_ICON} IN_LIST allowed_missing_medium_icons)
  123. message(FATAL_ERROR "Missing medium app icon: ${medium_icon}")
  124. endif()
  125. endif()
  126. endfunction()
  127. function(embed_resource target section file)
  128. get_filename_component(asm_file "${file}" NAME)
  129. set(asm_file "${CMAKE_CURRENT_BINARY_DIR}/${target}-${section}.s")
  130. get_filename_component(input_file "${file}" ABSOLUTE)
  131. file(SIZE "${input_file}" file_size)
  132. add_custom_command(
  133. OUTPUT "${asm_file}"
  134. COMMAND "${SerenityOS_SOURCE_DIR}/Meta/generate-embedded-resource-assembly.sh" "${asm_file}" "${section}" "${input_file}" "${file_size}"
  135. DEPENDS "${input_file}" "${SerenityOS_SOURCE_DIR}/Meta/generate-embedded-resource-assembly.sh"
  136. COMMENT "Generating ${asm_file}"
  137. )
  138. target_sources("${target}" PRIVATE "${asm_file}")
  139. endfunction()
  140. function(link_with_unicode_data target)
  141. if (DEFINED UNICODE_DATA_SOURCES)
  142. target_link_libraries("${target}" LibUnicodeData)
  143. endif()
  144. endfunction()