|
| 1 | +abstract type AbstractBuildToolchain{C} end |
| 2 | + |
| 3 | +struct CMake{C} <: AbstractBuildToolchain{C} end |
| 4 | +struct Meson{C} <: AbstractBuildToolchain{C} end |
| 5 | + |
| 6 | +c_compiler(::AbstractBuildToolchain{:clang}) = "clang" |
| 7 | +cxx_compiler(::AbstractBuildToolchain{:clang}) = "clang++" |
| 8 | +c_compiler(::AbstractBuildToolchain{:gcc}) = "gcc" |
| 9 | +cxx_compiler(::AbstractBuildToolchain{:gcc}) = "g++" |
| 10 | +fortran_compiler(::AbstractBuildToolchain) = "gfortran" |
| 11 | + |
| 12 | +function cmake_arch(p::AbstractPlatform) |
| 13 | + if arch(p) == "powerpc64le" |
| 14 | + return "ppc64le" |
| 15 | + else |
| 16 | + return arch(p) |
| 17 | + end |
| 18 | +end |
| 19 | + |
| 20 | +function cmake_os(p::AbstractPlatform) |
| 21 | + if Sys.islinux(p) |
| 22 | + return "Linux" |
| 23 | + elseif Sys.isfreebsd(p) |
| 24 | + return "FreeBSD" |
| 25 | + elseif Sys.isapple(p) |
| 26 | + return "Darwin" |
| 27 | + elseif Sys.iswindows(p) |
| 28 | + return "Windows" |
| 29 | + end |
| 30 | +end |
| 31 | + |
| 32 | +function toolchain_file(bt::CMake, p::AbstractPlatform) |
| 33 | + target = triplet(p) |
| 34 | + aatarget = aatriplet(p) |
| 35 | + |
| 36 | + if Sys.isapple(p) |
| 37 | + darwin_ver = something(os_version(p), v"14.5.0") |
| 38 | + maj_ver = darwin_ver.major |
| 39 | + min_ver = darwin_ver.minor |
| 40 | + return """ |
| 41 | + # CMake toolchain file for $(c_compiler(bt)) running on $(target) |
| 42 | + set(CMAKE_SYSTEM_NAME $(cmake_os(p))) |
| 43 | + set(CMAKE_SYSTEM_PROCESSOR $(cmake_arch(p))) |
| 44 | + set(CMAKE_SYSTEM_VERSION $(maj_ver).$(min_ver)) |
| 45 | + set(DARWIN_MAJOR_VERSION $(maj_ver)) |
| 46 | + set(DARWIN_MINOR_VERSION $(min_ver)) |
| 47 | +
|
| 48 | + # Enable rpath support |
| 49 | + set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") |
| 50 | +
|
| 51 | + set(CMAKE_SYSROOT /opt/$(aatarget)/$(aatarget)/sys-root) |
| 52 | + set(CMAKE_SYSTEM_FRAMEWORK_PATH |
| 53 | + \${CMAKE_SYSROOT}/System/Library/Frameworks |
| 54 | + \${CMAKE_SYSROOT}/System/Library/PrivateFrameworks |
| 55 | + ) |
| 56 | + set(CMAKE_INSTALL_PREFIX \$ENV{prefix}) |
| 57 | +
|
| 58 | + set(CMAKE_C_COMPILER /opt/bin/$(target)/$(c_compiler(bt))) |
| 59 | + set(CMAKE_CXX_COMPILER /opt/bin/$(target)/$(cxx_compiler(bt))) |
| 60 | + set(CMAKE_Fortran_COMPILER /opt/bin/$(target)/$(fortran_compiler(bt))) |
| 61 | +
|
| 62 | + set(CMAKE_LINKER /opt/bin/$(target)/$(aatarget)-ld) |
| 63 | + set(CMAKE_OBJCOPY /opt/bin/$(target)/$(aatarget)-objcopy) |
| 64 | +
|
| 65 | + set(CMAKE_AR /opt/bin/$(target)/$(aatarget)-ar) |
| 66 | + set(CMAKE_NM /opt/bin/$(target)/$(aatarget)-nm) |
| 67 | + set(CMAKE_RANLIB /opt/bin/$(target)/$(aatarget)-ranlib) |
| 68 | +
|
| 69 | + if( \$ENV{CC} MATCHES ccache ) |
| 70 | + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) |
| 71 | + endif() |
| 72 | + """ |
| 73 | + else |
| 74 | + return """ |
| 75 | + # CMake toolchain file for $(c_compiler(bt)) running on $(target) |
| 76 | + set(CMAKE_SYSTEM_NAME $(cmake_os(p))) |
| 77 | + set(CMAKE_SYSTEM_PROCESSOR $(cmake_arch(p))) |
| 78 | +
|
| 79 | + set(CMAKE_SYSROOT /opt/$(aatarget)/$(aatarget)/sys-root/) |
| 80 | + set(CMAKE_INSTALL_PREFIX \$ENV{prefix}) |
| 81 | +
|
| 82 | + set(CMAKE_C_COMPILER /opt/bin/$(target)/$(c_compiler(bt))) |
| 83 | + set(CMAKE_CXX_COMPILER /opt/bin/$(target)/$(cxx_compiler(bt))) |
| 84 | + set(CMAKE_Fortran_COMPILER /opt/bin/$(target)/$(fortran_compiler(bt))) |
| 85 | +
|
| 86 | + set(CMAKE_LINKER /opt/bin/$(target)/$(aatarget)-ld) |
| 87 | + set(CMAKE_OBJCOPY /opt/bin/$(target)/$(aatarget)-objcopy) |
| 88 | +
|
| 89 | + set(CMAKE_AR /opt/bin/$(target)/$(aatarget)-ar) |
| 90 | + set(CMAKE_NM /opt/bin/$(target)/$(aatarget)-nm) |
| 91 | + set(CMAKE_RANLIB /opt/bin/$(target)/$(aatarget)-ranlib) |
| 92 | +
|
| 93 | + if( \$ENV{CC} MATCHES ccache ) |
| 94 | + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) |
| 95 | + endif() |
| 96 | + """ |
| 97 | + end |
| 98 | +end |
| 99 | + |
| 100 | +function meson_c_link_args(p::AbstractPlatform) |
| 101 | + if arch(p) == "powerpc64le" && Sys.islinux(p) |
| 102 | + return "'-Wl,-rpath-link,/workspace/destdir/lib64'" |
| 103 | + else |
| 104 | + return "" |
| 105 | + end |
| 106 | +end |
| 107 | +meson_cxx_link_args(p::AbstractPlatform) = meson_c_link_args(p) |
| 108 | +meson_fortran_link_args(p::AbstractPlatform) = meson_c_link_args(p) |
| 109 | + |
| 110 | +# We can run native programs only on |
| 111 | +# * i686-linux-gnu |
| 112 | +# * x86_64-linux-gnu |
| 113 | +# * x86_64-linux-musl |
| 114 | +function meson_is_foreign(p::AbstractPlatform) |
| 115 | + if Sys.islinux(p) && proc_family(p) == "intel" && (libc(p) == "glibc" || (libc(p) == "musl" && arch(p) == "x86_64")) |
| 116 | + # Better to explicitly return the string we expect rather than |
| 117 | + # relying on the representation of the boolean values (even though |
| 118 | + # the result is the same) |
| 119 | + return "false" |
| 120 | + else |
| 121 | + return "true" |
| 122 | + end |
| 123 | +end |
| 124 | + |
| 125 | +# https://mesonbuild.com/Reference-tables.html#operating-system-names |
| 126 | +meson_system(p::AbstractPlatform) = lowercase(cmake_os(p)) |
| 127 | + |
| 128 | +# https://github.com/mesonbuild/meson/blob/6e39dcad2fbd8d1c739e262b0e7b7d901cf1ce08/mesonbuild/environment.py#L412-L440 |
| 129 | +meson_cpu(p::AbstractPlatform) = cmake_arch(p) |
| 130 | + |
| 131 | +# https://mesonbuild.com/Reference-tables.html#cpu-families |
| 132 | +function meson_cpu_family(p::AbstractPlatform) |
| 133 | + if arch(p) == "powerpc64le" |
| 134 | + return "ppc64" |
| 135 | + elseif arch(p) == "i686" |
| 136 | + return "x86" |
| 137 | + elseif arch(p) == "x86_64" |
| 138 | + return "x86_64" |
| 139 | + elseif arch(p) == "aarch64" |
| 140 | + return "aarch64" |
| 141 | + elseif startswith(arch(p), "arm") |
| 142 | + return "arm" |
| 143 | + end |
| 144 | +end |
| 145 | + |
| 146 | +function toolchain_file(bt::Meson, p::AbstractPlatform) |
| 147 | + target = triplet(p) |
| 148 | + aatarget = aatriplet(p) |
| 149 | + |
| 150 | + return """ |
| 151 | + [binaries] |
| 152 | + c = '/opt/bin/$(target)/$(aatarget)-$(c_compiler(bt))' |
| 153 | + cpp = '/opt/bin/$(target)/$(aatarget)-$(c_compiler(bt))' |
| 154 | + fortran = '/opt/bin/$(target)/$(aatarget)-$(fortran_compiler(bt))' |
| 155 | + objc = '/opt/bin/$(target)/$(aatarget)-objc' |
| 156 | + ar = '/opt/bin/$(target)/$(aatarget)-ar' |
| 157 | + ld = '/opt/bin/$(target)/$(aatarget)-ld' |
| 158 | + nm = '/opt/bin/$(target)/$(aatarget)-nm' |
| 159 | + strip = '/opt/bin/$(target)/$(aatarget)-strip' |
| 160 | + pkgconfig = '/usr/bin/pkg-config' |
| 161 | +
|
| 162 | + [properties] |
| 163 | + c_args = [] |
| 164 | + cpp_args = [] |
| 165 | + fortran_args = [] |
| 166 | + c_link_args = [$(meson_c_link_args(p))] |
| 167 | + cpp_link_args = [$(meson_cxx_link_args(p))] |
| 168 | + fortran_link_args = [$(meson_fortran_link_args(p))] |
| 169 | + needs_exe_wrapper = $(meson_is_foreign(p)) |
| 170 | +
|
| 171 | + [build_machine] |
| 172 | + system = 'linux' |
| 173 | + cpu_family = 'x86_64' |
| 174 | + cpu = 'x86_64' |
| 175 | + endian = 'little' |
| 176 | +
|
| 177 | + [host_machine] |
| 178 | + system = '$(meson_system(p))' |
| 179 | + cpu_family = '$(meson_cpu_family(p))' |
| 180 | + cpu = '$(meson_cpu(p))' |
| 181 | + endian = 'little' |
| 182 | +
|
| 183 | + [paths] |
| 184 | + prefix = '/workspace/destdir' |
| 185 | + """ |
| 186 | +end |
| 187 | + |
| 188 | +function generate_toolchain_files!(platform::AbstractPlatform; |
| 189 | + toolchains_path::AbstractString, |
| 190 | + host_platform::AbstractPlatform = default_host_platform, |
| 191 | + ) |
| 192 | + |
| 193 | + # Generate the files fot bot the host and the target platforms |
| 194 | + for p in unique((platform, host_platform)) |
| 195 | + dir = joinpath(toolchains_path, triplet(p)) |
| 196 | + mkpath(dir) |
| 197 | + |
| 198 | + write(joinpath(dir, "$(aatriplet(p))_clang.cmake"), toolchain_file(CMake{:clang}(), p)) |
| 199 | + write(joinpath(dir, "$(aatriplet(p))_gcc.cmake"), toolchain_file(CMake{:gcc}(), p)) |
| 200 | + write(joinpath(dir, "$(aatriplet(p))_clang.meson"), toolchain_file(Meson{:clang}(), p)) |
| 201 | + write(joinpath(dir, "$(aatriplet(p))_gcc.meson"), toolchain_file(Meson{:gcc}(), p)) |
| 202 | + |
| 203 | + # On FreeBSD and MacOS we actually want to default to clang, otherwise gcc |
| 204 | + if Sys.isbsd(p) |
| 205 | + symlink("$(aatriplet(p))_clang.cmake", joinpath(dir, "$(aatriplet(p)).cmake")) |
| 206 | + symlink("$(aatriplet(p))_clang.meson", joinpath(dir, "$(aatriplet(p)).meson")) |
| 207 | + else |
| 208 | + symlink("$(aatriplet(p))_gcc.cmake", joinpath(dir, "$(aatriplet(p)).cmake")) |
| 209 | + symlink("$(aatriplet(p))_gcc.meson", joinpath(dir, "$(aatriplet(p)).meson")) |
| 210 | + end |
| 211 | + end |
| 212 | +end |
0 commit comments