Machine bootstrapping tool with a focus on sensible defaults, conventions, and avoidance of vendoring - This is a mirror
at main 6.1 kB view raw
1project('mstrap', 2 'c', 3 meson_version : '>= 0.62.0', 4 license : 'MIT', 5 version : '0.7.2', 6 default_options : [ 7 'buildtype=debugoptimized', 8 'default_library=static' 9 ] 10) 11 12cc = meson.get_compiler('c') 13target_arch = host_machine.cpu_family() 14target_system = host_machine.system() 15target_triple = target_arch + '-unknown-' + target_system 16 17buildtype = get_option('buildtype') 18is_darwin = target_system == 'darwin' 19is_static = get_option('default_library') == 'static' 20is_static_libc = false 21needs_macos_classic_linker = false 22 23if target_system == 'linux' 24 target_cabi = meson.get_external_property('target_triple_suffix', 'gnu') 25 26 target_triple += '-' + target_cabi 27 28 if target_cabi == 'musl' and is_static 29 is_static_libc = true 30 add_global_link_arguments('-static', language : 'c') 31 endif 32elif target_system == 'darwin' 33 macos_abi = meson.get_external_property('macos_version', '12') 34 macos_arch = target_arch == 'aarch64' ? 'arm64' : target_arch 35 36 target_triple = macos_arch + '-apple-macos' + macos_abi 37 add_global_arguments('-target', target_triple, language : 'c', native : false) 38 add_global_link_arguments('-target', target_triple, language : 'c', native : false) 39 40 # Use legacy linker with xcode 15+ 41 xcode_version_output = run_command(find_program('xcodebuild'), '-version', check : true).stdout() 42 xcode_version = xcode_version_output.split('\n').get(0, '').replace('Xcode', '').strip() 43 44 if xcode_version.version_compare('>=15.0') and cc.has_link_argument('-Wl,-ld_classic') 45 needs_macos_classic_linker = true 46 add_global_link_arguments('-Wl,-ld_classic', language : 'c') 47 endif 48endif 49 50crystal = find_program(get_option('crystal'), version : '>= 1.8.0', required : true) 51shards = find_program(get_option('shards'), required : true) 52 53# Basics 54libiconv_dep = dependency('iconv', static : is_static and not is_darwin) 55libm_dep = cc.find_library('m', required : false, static : is_static) 56libpcre2_dep = dependency('libpcre2-8', static : is_static) 57thread_dep = dependency('threads', static : is_static) 58zlib_dep = dependency('zlib', static : is_static and not is_darwin) 59 60# OpenSSL/LibreSSL (for fetching profiles & strap.sh over HTTPS) 61libcrypto_dep = dependency('libcrypto', version : '>= 1.1.1', static : is_static) 62libssl_dep = dependency('libssl', version : '>= 1.1.1', static : is_static) 63 64embedded_openssl = libcrypto_dep.type_name() != 'pkgconfig' 65 66if embedded_openssl 67 pkg = import('pkgconfig') 68 pkg.generate( 69 name : 'libcrypto', 70 description: 'OpenSSL-libcrypto', 71 version : libcrypto_dep.version(), 72 libraries : [libcrypto_dep] 73 ) 74 pkg.generate( 75 name : 'libssl', 76 description: 'OpenSSL-libssl', 77 version : libssl_dep.version(), 78 libraries : [libssl_dep] 79 ) 80endif 81 82# Libevent (required for Crystal runtime < 1.15.0 or platforms not supported by 83# lifetime event loop in Crystal 1.15.0+) 84crystal_requires_libevent = crystal.version().version_compare('< 1.15.0') or \ 85 (target_system != 'linux' and target_system != 'darwin' and target_system != 'freebsd') 86 87libevent_dep = dependency( 88 'libevent', 89 version : '>= 2.1.2', 90 static : is_static, 91 required : false, 92) 93if not libevent_dep.found() and crystal_requires_libevent 94 cmake = import('cmake') 95 libevent_options = cmake.subproject_options() 96 libevent_options.add_cmake_defines({ 97 'EVENT__LIBRARY_TYPE': 'STATIC', 98 'BUILD_SHARED_LIBS': false, 99 'BUILD_SHARED_AND_STATIC_LIBS': false, 100 'CMAKE_C_FLAGS': '-fPIC', 101 'EVENT__DISABLE_OPENSSL': true, 102 'EVENT__DISABLE_BENCHMARK': true, 103 'EVENT__DISABLE_TESTS': true, 104 'EVENT__DISABLE_REGRESS': true, 105 'EVENT__DISABLE_SAMPLES': true, 106 }) 107 libevent_options.set_override_option('werror', 'false') 108 libevent_options.set_override_option('warning_level', '0') 109 libevent_proj = cmake.subproject('libevent', options: libevent_options) 110 libevent_dep = libevent_proj.dependency('event_core_static') 111endif 112 113# libgc (required for Crystal runtime) 114libgc_dep = dependency( 115 'bdw-gc', 116 version : '>= 8.0.4', 117 static : is_static, 118 required : false 119) 120if not libgc_dep.found() 121 cmake = import('cmake') 122 libgc_options = cmake.subproject_options() 123 libgc_options.add_cmake_defines({ 124 'BUILD_SHARED_LIBS': false, 125 'enable_docs': false, 126 'enable_large_config': true, 127 'disable_gc_debug': true, 128 'CMAKE_C_FLAGS': '-fPIC', 129 }) 130 libgc_options.set_override_option('werror', 'false') 131 libgc_options.set_override_option('warning_level', '0') 132 libgc_proj = cmake.subproject('bdwgc', options: libgc_options) 133 libgc_dep = libgc_proj.dependency('gc') 134endif 135 136if run_command(shards, 'check', check : false).returncode() != 0 137 run_command(shards, 'install', '--frozen', check : true) 138endif 139 140crystal_path = run_command( 141 crystal, 'env', 'CRYSTAL_PATH', 142 check : true 143).stdout().strip() 144env = environment({ 145 'CRYSTAL_PATH': crystal_path, 146}) 147env.prepend('CRYSTAL_PATH', join_paths(meson.project_source_root(), 'lib')) 148 149if embedded_openssl 150 env.set('PKG_CONFIG_PATH', join_paths(meson.project_build_root(), 'meson-uninstalled')) 151endif 152 153crystal_build_flags = [ 154 '--error-trace', 155 '--cross-compile', 156 '--target', 157 target_triple, 158] 159 160if buildtype.contains('debug') 161 crystal_build_flags += ['--debug', '--error-trace'] 162else 163 crystal_build_flags += ['--no-debug'] 164endif 165 166if buildtype in ['release', 'debugoptimized'] 167 crystal_build_flags += ['--release'] 168endif 169 170if is_static_libc 171 crystal_build_flags += ['--static'] 172endif 173 174if needs_macos_classic_linker 175 crystal_build_flags += ['--link-flags=-Wl,-ld_classic'] 176endif 177 178mstrap_build_cmd = [crystal, 'build'] + crystal_build_flags + ['-o', 'mstrap', '@INPUT@'] 179 180mstrap_o = custom_target( 181 'mstrap.o', 182 build_always_stale : true, 183 command : mstrap_build_cmd, 184 depend_files : [files('shard.lock')], 185 env : env, 186 input : [files('src/cli.cr')], 187 output : ['mstrap.o'] 188) 189 190executable( 191 'mstrap', 192 mstrap_o, 193 dependencies : [ 194 libcrypto_dep, 195 libevent_dep, 196 libgc_dep, 197 libiconv_dep, 198 libm_dep, 199 libpcre2_dep, 200 libssl_dep, 201 zlib_dep, 202 thread_dep 203 ], 204 install : true 205)