| 1 | function(build_linux_objects sources headers) |
| 2 | file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}) |
| 3 | |
| 4 | foreach(e ${sources}) |
| 5 | cmake_path(GET e FILENAME object_name) |
| 6 | set(object "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_PLATFORM}/${CMAKE_BUILD_TYPE}/${object_name}.o") |
| 7 | set(objects ${objects} ${object}) |
| 8 | |
| 9 | if("${e}" MATCHES "^.*\.c$") |
| 10 | set(compiler ${LINUX_CC}) |
| 11 | set(flags ${LINUX_CFLAGS}) |
| 12 | else() |
| 13 | set(compiler ${LINUX_CXX}) |
| 14 | set(flags ${LINUX_CXXFLAGS}) |
| 15 | endif() |
| 16 | |
| 17 | add_custom_command( |
| 18 | OUTPUT ${object} |
| 19 | COMMAND ${compiler} ${flags} ${LINUX_BUILD_TYPE_FLAGS} ${e} -c -o ${object} |
| 20 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} |
| 21 | MAIN_DEPENDENCY ${e} |
| 22 | DEPENDS ${headers} # Every object depends on all headers to trigger a rebuild if a header is changed |
| 23 | VERBATIM |
| 24 | ) |
| 25 | endforeach() |
| 26 | |
| 27 | set(objects ${objects} PARENT_SCOPE) |
| 28 | endfunction() |
| 29 | |
| 30 | function(add_linux_library_impl target sources headers add_sources) |
| 31 | set(ar_output "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${target}.a") |
| 32 | |
| 33 | build_linux_objects("${sources}" "${headers}") |
| 34 | |
| 35 | add_custom_command( |
| 36 | OUTPUT ${ar_output} ${CMAKE_CURRENT_BINARY_DIR}/CmakeFiles/${target} |
| 37 | COMMAND ${LINUX_AR} crus ${ar_output} ${objects} |
| 38 | COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/CmakeFiles/${target}" |
| 39 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} |
| 40 | DEPENDS ${objects} |
| 41 | VERBATIM |
| 42 | ) |
| 43 | |
| 44 | if (${add_sources}) |
| 45 | add_custom_target(${target} DEPENDS ${ar_output} SOURCES ${sources} ${headers}) |
| 46 | else() |
| 47 | add_custom_target(${target} DEPENDS ${ar_output}) |
| 48 | endif() |
| 49 | |
| 50 | set_source_files_properties(${ar_output} PROPERTIES GENERATED TRUE) |
| 51 | endfunction() |
| 52 | |
| 53 | function(add_linux_library target sources headers) |
| 54 | add_linux_library_impl(${target} "${sources}" "${headers}" TRUE) |
| 55 | endfunction() |
| 56 | |
| 57 | function(add_linux_library_no_sources target sources headers) |
| 58 | add_linux_library_impl(${target} "${sources}" "${headers}" FALSE) |
| 59 | endfunction() |
| 60 | |
| 61 | |
| 62 | function(add_linux_executable target sources headers libraries) |
| 63 | set(output "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${target}") |
| 64 | set(output_unstripped "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${target}.unstripped") |
| 65 | |
| 66 | build_linux_objects("${sources}" "${headers}") |
| 67 | |
| 68 | set(libs -lunwind -lc++abi -lc++) |
| 69 | foreach(e ${libraries}) |
| 70 | set(libs ${libs} -l${e}) |
| 71 | |
| 72 | # Note: This makes the assumption that all libraries are static (.a and not .so). |
| 73 | # Executables need to depend on both the target and the underlying library file, so that |
| 74 | # the libraries target get analyzed for changes, and the executable gets linked again if the .a files changed. |
| 75 | list(APPEND lib_targets "lib${e}") |
| 76 | list(APPEND lib_files "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/lib${e}.a") |
| 77 | endforeach() |
| 78 | |
| 79 | if (NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug") |
| 80 | set(stripped_output "${output}") |
| 81 | set(output "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_BUILD_TYPE}/${target}.debug") |
| 82 | add_custom_command( |
| 83 | OUTPUT ${stripped_output} |
| 84 | COMMAND ${LLVM_INSTALL_DIR}/llvm-strip.exe "${output}" -o "${stripped_output}" |
| 85 | COMMAND ${LLVM_INSTALL_DIR}/llvm-objcopy.exe --add-gnu-debuglink "${output}" "${stripped_output}" |
| 86 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} |
| 87 | DEPENDS ${output} |
| 88 | VERBATIM |
| 89 | ) |
| 90 | endif() |
| 91 | |
| 92 | add_custom_command( |
| 93 | OUTPUT ${output} |
| 94 | COMMAND ${LINUX_CXX} -o ${output} ${LINUXSDK_PATH}/lib/crti.o ${LINUXSDK_PATH}/lib/crt1.o ${objects} ${LINUXSDK_PATH}/lib/crtn.o ${LINUX_LDFLAGS} ${libs} |
| 95 | COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_CURRENT_BINARY_DIR}/CmakeFiles/${target}" |
| 96 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} |
| 97 | DEPENDS ${objects} ${lib_files} |
| 98 | VERBATIM |
| 99 | ) |
| 100 | |
| 101 | add_custom_target(${target} DEPENDS ${output} ${stripped_output} SOURCES ${sources} ${headers}) |
| 102 | add_dependencies(${target} ${lib_targets}) |
| 103 | |
| 104 | endfunction() |