master
cmake 104 lines 4.11 KB
Raw
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()