xref: /llvm-project/llvm/cmake/modules/CrossCompile.cmake (revision 6655c53ff02f0ffca0fcaa3261e14c2a6417d3da)
1include(AddLLVM)
2include(LLVMExternalProjectUtils)
3
4
5function(llvm_create_cross_target project_name target_name toolchain buildtype)
6
7  if(NOT DEFINED ${project_name}_${target_name}_BUILD)
8    set(${project_name}_${target_name}_BUILD
9      "${CMAKE_CURRENT_BINARY_DIR}/${target_name}")
10    set(${project_name}_${target_name}_BUILD
11      ${${project_name}_${target_name}_BUILD} PARENT_SCOPE)
12    message(STATUS "Setting native build dir to " ${${project_name}_${target_name}_BUILD})
13  endif(NOT DEFINED ${project_name}_${target_name}_BUILD)
14
15  if(NOT DEFINED ${project_name}_${target_name}_STAMP)
16    set(${project_name}_${target_name}_STAMP
17      "${CMAKE_CURRENT_BINARY_DIR}/${target_name}-stamps")
18    set(${project_name}_${target_name}_STAMP
19      ${${project_name}_${target_name}_STAMP} PARENT_SCOPE)
20    message(STATUS "Setting native stamp dir to " ${${project_name}_${target_name}_STAMP})
21  endif(NOT DEFINED ${project_name}_${target_name}_STAMP)
22
23  if (EXISTS ${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake)
24    set(CROSS_TOOLCHAIN_FLAGS_INIT
25      -DCMAKE_TOOLCHAIN_FILE=\"${LLVM_MAIN_SRC_DIR}/cmake/platforms/${toolchain}.cmake\")
26  elseif (NOT CMAKE_CROSSCOMPILING)
27    set(CROSS_TOOLCHAIN_FLAGS_INIT
28      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
29      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
30      )
31  endif()
32  set(CROSS_TOOLCHAIN_FLAGS_${target_name} ${CROSS_TOOLCHAIN_FLAGS_INIT}
33    CACHE STRING "Toolchain configuration for ${target_name}")
34
35  # project specific version of the flags up above
36  set(CROSS_TOOLCHAIN_FLAGS_${project_name}_${target_name} ""
37    CACHE STRING "Toolchain configuration for ${project_name}_${target_name}")
38
39  if (buildtype)
40    set(build_type_flags "-DCMAKE_BUILD_TYPE=${buildtype}")
41  endif()
42  if (LLVM_USE_LINKER AND NOT CMAKE_CROSSCOMPILING)
43    set(linker_flag "-DLLVM_USE_LINKER=${LLVM_USE_LINKER}")
44  endif()
45  if (LLVM_EXTERNAL_CLANG_SOURCE_DIR)
46    # Propagate LLVM_EXTERNAL_CLANG_SOURCE_DIR so that clang-tblgen can be built
47    set(external_clang_dir "-DLLVM_EXTERNAL_CLANG_SOURCE_DIR=${LLVM_EXTERNAL_CLANG_SOURCE_DIR}")
48  endif()
49
50  add_custom_command(OUTPUT ${${project_name}_${target_name}_BUILD}
51    COMMAND ${CMAKE_COMMAND} -E make_directory ${${project_name}_${target_name}_BUILD}
52    COMMENT "Creating ${${project_name}_${target_name}_BUILD}...")
53
54  add_custom_target(CREATE_${project_name}_${target_name}
55    DEPENDS ${${project_name}_${target_name}_BUILD})
56  get_subproject_title(subproject_title)
57  set_target_properties(CREATE_${project_name}_${target_name} PROPERTIES FOLDER "${subproject_title}/Native")
58
59  # Escape semicolons in the targets list so that cmake doesn't expand
60  # them to spaces.
61  string(REPLACE ";" "$<SEMICOLON>" targets_to_build_arg
62         "${LLVM_TARGETS_TO_BUILD}")
63  string(REPLACE ";" "$<SEMICOLON>" experimental_targets_to_build_arg
64         "${LLVM_EXPERIMENTAL_TARGETS_TO_BUILD}")
65
66  string(REPLACE ";" "$<SEMICOLON>" llvm_enable_projects_arg
67         "${LLVM_ENABLE_PROJECTS}")
68  string(REPLACE ";" "$<SEMICOLON>" llvm_external_projects_arg
69         "${LLVM_EXTERNAL_PROJECTS}")
70  string(REPLACE ";" "$<SEMICOLON>" llvm_enable_runtimes_arg
71         "${LLVM_ENABLE_RUNTIMES}")
72
73  set(external_project_source_dirs)
74  foreach(project ${LLVM_EXTERNAL_PROJECTS})
75    canonicalize_tool_name(${project} name)
76    list(APPEND external_project_source_dirs
77         "-DLLVM_EXTERNAL_${name}_SOURCE_DIR=${LLVM_EXTERNAL_${name}_SOURCE_DIR}")
78  endforeach()
79
80  if(LLVM_LIBC_GPU_BUILD)
81    set(libc_flags -DLLVM_LIBC_GPU_BUILD=ON)
82  endif()
83
84  add_custom_command(OUTPUT ${${project_name}_${target_name}_BUILD}/CMakeCache.txt
85    COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
86        -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}"
87        -DCMAKE_C_COMPILER_LAUNCHER="${CMAKE_C_COMPILER_LAUNCHER}"
88        -DCMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CXX_COMPILER_LAUNCHER}"
89        ${CROSS_TOOLCHAIN_FLAGS_${target_name}} ${CMAKE_CURRENT_SOURCE_DIR}
90        ${CROSS_TOOLCHAIN_FLAGS_${project_name}_${target_name}}
91        -DLLVM_TARGET_IS_CROSSCOMPILE_HOST=TRUE
92        -DLLVM_TARGETS_TO_BUILD="${targets_to_build_arg}"
93        -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="${experimental_targets_to_build_arg}"
94        -DLLVM_DEFAULT_TARGET_TRIPLE="${LLVM_TARGET_TRIPLE}"
95        -DLLVM_TARGET_ARCH="${LLVM_TARGET_ARCH}"
96        -DLLVM_ENABLE_PROJECTS="${llvm_enable_projects_arg}"
97        -DLLVM_EXTERNAL_PROJECTS="${llvm_external_projects_arg}"
98        -DLLVM_ENABLE_RUNTIMES="${llvm_enable_runtimes_arg}"
99        ${external_project_source_dirs}
100        -DLLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN="${LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN}"
101        -DLLVM_INCLUDE_BENCHMARKS=OFF
102        -DLLVM_INCLUDE_TESTS=OFF
103        ${build_type_flags} ${linker_flag} ${external_clang_dir} ${libc_flags}
104        ${ARGN}
105    WORKING_DIRECTORY ${${project_name}_${target_name}_BUILD}
106    DEPENDS CREATE_${project_name}_${target_name}
107    COMMENT "Configuring ${target_name} ${project_name}...")
108
109  add_custom_target(CONFIGURE_${project_name}_${target_name}
110    DEPENDS ${${project_name}_${target_name}_BUILD}/CMakeCache.txt)
111  get_subproject_title(subproject_title)
112  set_target_properties(CONFIGURE_${project_name}_${target_name} PROPERTIES FOLDER "${subproject_title}/Native")
113
114endfunction()
115
116function(get_native_tool_path target output_path_var)
117  if(CMAKE_CONFIGURATION_TYPES)
118    set(output_path "${${PROJECT_NAME}_NATIVE_BUILD}/Release/bin/${target}")
119  else()
120    set(output_path "${${PROJECT_NAME}_NATIVE_BUILD}/bin/${target}")
121  endif()
122  set(${output_path_var} ${output_path}${LLVM_HOST_EXECUTABLE_SUFFIX} PARENT_SCOPE)
123endfunction()
124
125# Sets up a native build for a tool, used e.g. for cross-compilation and
126# LLVM_OPTIMIZED_TABLEGEN. Always builds in Release.
127# - target: The target to build natively
128# - output_path_var: A variable name which receives the path to the built target
129# - DEPENDS: Any additional dependencies for the target
130function(build_native_tool target output_path_var)
131  cmake_parse_arguments(ARG "" "" "DEPENDS" ${ARGN})
132
133  get_native_tool_path(${target} output_path)
134
135  # Make chain of preceding actions
136  if(CMAKE_GENERATOR MATCHES "Visual Studio")
137    get_property(host_targets GLOBAL PROPERTY ${PROJECT_NAME}_HOST_TARGETS)
138    set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_HOST_TARGETS ${output_path})
139  endif()
140
141  llvm_ExternalProject_BuildCmd(build_cmd ${target}
142                                ${${PROJECT_NAME}_NATIVE_BUILD}
143                                ${${PROJECT_NAME}_NATIVE_STAMP}
144                                CONFIGURATION Release)
145  add_custom_command(OUTPUT "${output_path}"
146                     COMMAND ${build_cmd}
147                     DEPENDS CONFIGURE_${PROJECT_NAME}_NATIVE ${ARG_DEPENDS} ${host_targets}
148                     WORKING_DIRECTORY "${${PROJECT_NAME}_NATIVE_BUILD}"
149                     COMMENT "Building native ${target}..."
150                     USES_TERMINAL
151                     VERBATIM)
152  set(${output_path_var} "${output_path}" PARENT_SCOPE)
153endfunction()
154