| 1 | if not have_ga |
| 2 | if get_option('guest_agent_msi').enabled() |
| 3 | error('Guest agent MSI requested, but the guest agent is not being built') |
| 4 | endif |
| 5 | have_qga_vss = false |
| 6 | subdir_done() |
| 7 | endif |
| 8 | |
| 9 | have_qga_vss = get_option('qga_vss') \ |
| 10 | .require(host_os == 'windows', |
| 11 | error_message: 'VSS support requires Windows') \ |
| 12 | .require('cpp' in all_languages, |
| 13 | error_message: 'VSS support requires a C++ compiler') \ |
| 14 | .require(have_vss, error_message: '''VSS support requires VSS headers. |
| 15 | If your Visual Studio installation doesn't have the VSS headers, |
| 16 | Please download and install Microsoft VSS SDK: |
| 17 | http://www.microsoft.com/en-us/download/details.aspx?id=23490 |
| 18 | On POSIX-systems, MinGW should provide headers in >=10.0 releases. |
| 19 | you can extract the SDK headers by: |
| 20 | $ scripts/extract-vsssdk-headers setup.exe |
| 21 | The headers are extracted in the directory 'inc/win2003'. |
| 22 | Then run configure with: --extra-cxxflags="-isystem /path/to/vss/inc/win2003"''') \ |
| 23 | .require(midl.found() or widl.found(), |
| 24 | error_message: 'VSS support requires midl or widl') \ |
| 25 | .require(not get_option('prefer_static'), |
| 26 | error_message: 'VSS support requires dynamic linking with GLib') \ |
| 27 | .allowed() |
| 28 | |
| 29 | all_qga = [] |
| 30 | |
| 31 | qga_qapi_outputs = [ |
| 32 | 'qga-qapi-commands.c', |
| 33 | 'qga-qapi-commands.h', |
| 34 | 'qga-qapi-emit-events.c', |
| 35 | 'qga-qapi-emit-events.h', |
| 36 | 'qga-qapi-events.c', |
| 37 | 'qga-qapi-events.h', |
| 38 | 'qga-qapi-init-commands.c', |
| 39 | 'qga-qapi-init-commands.h', |
| 40 | 'qga-qapi-introspect.c', |
| 41 | 'qga-qapi-introspect.h', |
| 42 | 'qga-qapi-types.c', |
| 43 | 'qga-qapi-types.h', |
| 44 | 'qga-qapi-visit.c', |
| 45 | 'qga-qapi-visit.h', |
| 46 | ] |
| 47 | |
| 48 | # Problem: to generate trace events, we'd have to add the .trace-events |
| 49 | # file to qapi_trace_events like we do in qapi/meson.build. Since |
| 50 | # qapi_trace_events is used by trace/meson.build, we'd have to move |
| 51 | # subdir('qga') above subdir('trace') in the top-level meson.build. |
| 52 | # Can't, because it would break the dependency of qga on qemuutil (which |
| 53 | # depends on trace_ss). Not worth solving now; simply suppress trace |
| 54 | # event generation instead. |
| 55 | qga_qapi_files = custom_target('QGA QAPI files', |
| 56 | output: qga_qapi_outputs, |
| 57 | input: 'qapi-schema.json', |
| 58 | command: [ qapi_gen, '-o', 'qga', '-p', 'qga-', '@INPUT0@', |
| 59 | '--suppress-tracing' ], |
| 60 | depend_files: qapi_gen_depends) |
| 61 | |
| 62 | qga_ss = ss.source_set() |
| 63 | qga_ss.add(qga_qapi_files.to_list()) |
| 64 | qga_ss.add(files( |
| 65 | 'commands.c', |
| 66 | 'guest-agent-command-state.c', |
| 67 | 'main.c', |
| 68 | 'cutils.c', |
| 69 | 'commands-common-ssh.c' |
| 70 | )) |
| 71 | if host_os == 'windows' |
| 72 | qga_ss.add(files( |
| 73 | 'channel-win32.c', |
| 74 | 'commands-win32.c', |
| 75 | 'service-win32.c', |
| 76 | 'vss-win32.c', |
| 77 | 'commands-windows-ssh.c' |
| 78 | )) |
| 79 | else |
| 80 | qga_ss.add(files( |
| 81 | 'channel-posix.c', |
| 82 | 'commands-posix.c', |
| 83 | 'commands-posix-ssh.c', |
| 84 | )) |
| 85 | if host_os == 'linux' |
| 86 | qga_ss.add(files('commands-linux.c')) |
| 87 | elif host_os in bsd_oses |
| 88 | qga_ss.add(files('commands-bsd.c')) |
| 89 | endif |
| 90 | endif |
| 91 | |
| 92 | qga_ss = qga_ss.apply({}) |
| 93 | |
| 94 | gen_tlb = [] |
| 95 | qga_libs = [] |
| 96 | if host_os == 'windows' |
| 97 | qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32', '-lwininet', '-liphlpapi', '-lnetapi32', |
| 98 | '-lsetupapi', '-lcfgmgr32', '-luserenv', '-lpdh' ] |
| 99 | if have_qga_vss |
| 100 | qga_libs += ['-lole32', '-loleaut32', '-lshlwapi', '-Wl,--enable-stdcall-fixup'] |
| 101 | subdir('vss-win32') |
| 102 | endif |
| 103 | endif |
| 104 | |
| 105 | qga_objs = [] |
| 106 | if host_os == 'windows' |
| 107 | windmc = find_program('windmc', 'mc', required: true) |
| 108 | |
| 109 | msgrc = custom_target('messages-win32.rc', |
| 110 | input: 'messages-win32.mc', |
| 111 | output: ['messages-win32.rc', 'MSG00409.bin', 'messages-win32.h'], |
| 112 | command: [windmc, '-h', '@OUTDIR@', '-r', '@OUTDIR@', '@INPUT@']) |
| 113 | |
| 114 | windows = import('windows') |
| 115 | msgobj = windows.compile_resources(msgrc[0]) |
| 116 | |
| 117 | qga_objs = [msgobj] |
| 118 | endif |
| 119 | |
| 120 | qga = executable('qemu-ga', qga_ss.sources() + qga_objs, |
| 121 | link_args: qga_libs, |
| 122 | dependencies: [qemuutil, libudev], |
| 123 | install: true) |
| 124 | all_qga += qga |
| 125 | |
| 126 | if host_os == 'windows' |
| 127 | qemu_ga_msi_arch = { |
| 128 | 'x86': ['-D', 'Arch=32'], |
| 129 | 'x86_64': ['-a', 'x64', '-D', 'Arch=64'] |
| 130 | } |
| 131 | wixl = not_found |
| 132 | if cpu in qemu_ga_msi_arch |
| 133 | wixl = find_program('wixl', required: get_option('guest_agent_msi')) |
| 134 | elif get_option('guest_agent_msi').enabled() |
| 135 | error('CPU not supported for building guest agent installation package') |
| 136 | endif |
| 137 | |
| 138 | if wixl.found() |
| 139 | deps = [gen_tlb, qga] |
| 140 | qemu_ga_msi_vss = [] |
| 141 | if have_qga_vss |
| 142 | qemu_ga_msi_vss = ['-D', 'InstallVss'] |
| 143 | deps += qga_vss |
| 144 | endif |
| 145 | if glib.version().version_compare('<2.73.2') |
| 146 | libpcre = 'libpcre1' |
| 147 | else |
| 148 | libpcre = 'libpcre2' |
| 149 | endif |
| 150 | qga_msi_version = get_option('qemu_ga_version') == '' \ |
| 151 | ? meson.project_version() \ |
| 152 | : get_option('qemu_ga_version') |
| 153 | qga_msi = custom_target('QGA MSI', |
| 154 | input: files('installer/qemu-ga.wxs'), |
| 155 | output: 'qemu-ga-@0@.msi'.format(host_arch), |
| 156 | depends: deps, |
| 157 | command: [ |
| 158 | wixl, '-o', '@OUTPUT0@', '@INPUT0@', |
| 159 | qemu_ga_msi_arch[cpu], |
| 160 | qemu_ga_msi_vss, |
| 161 | '-D', 'BUILD_DIR=' + meson.project_build_root(), |
| 162 | '-D', 'BIN_DIR=' + glib_pc.get_variable('bindir'), |
| 163 | '-D', 'QEMU_GA_VERSION=' + qga_msi_version, |
| 164 | '-D', 'QEMU_GA_MANUFACTURER=' + get_option('qemu_ga_manufacturer'), |
| 165 | '-D', 'QEMU_GA_DISTRO=' + get_option('qemu_ga_distro'), |
| 166 | '-D', 'LIBPCRE=' + libpcre, |
| 167 | ]) |
| 168 | all_qga += [qga_msi] |
| 169 | alias_target('msi', qga_msi) |
| 170 | endif |
| 171 | else |
| 172 | if get_option('guest_agent_msi').enabled() |
| 173 | error('MSI guest agent package is available only for MinGW Windows cross-compilation') |
| 174 | endif |
| 175 | install_emptydir(get_option('localstatedir') / 'run') |
| 176 | endif |
| 177 | |
| 178 | alias_target('qemu-ga', all_qga) |
| 179 | |
| 180 | test_env = environment() |
| 181 | test_env.set('G_TEST_SRCDIR', meson.current_source_dir()) |
| 182 | test_env.set('G_TEST_BUILDDIR', meson.current_build_dir()) |
| 183 | |
| 184 | # disable qga-ssh-test with fuzzing: glib's G_TEST_OPTION_ISOLATE_DIRS triggers |
| 185 | # the leak detector in build-oss-fuzz Gitlab CI test. we should re-enable |
| 186 | # this when an alternative is implemented or when the underlying glib |
| 187 | # issue is identified/fix |
| 188 | if host_os != 'windows' and not get_option('fuzzing') |
| 189 | srcs = [files('commands-common-ssh.c', 'commands-posix-ssh.c')] |
| 190 | i = 0 |
| 191 | foreach output: qga_qapi_outputs |
| 192 | if output.startswith('qga-qapi-types') or output.startswith('qga-qapi-visit') |
| 193 | srcs += qga_qapi_files[i] |
| 194 | endif |
| 195 | i = i + 1 |
| 196 | endforeach |
| 197 | qga_ssh_test = executable('qga-ssh-test', srcs, |
| 198 | dependencies: [qemuutil], |
| 199 | c_args: ['-DQGA_BUILD_UNIT_TEST']) |
| 200 | |
| 201 | test('qga-ssh-test', |
| 202 | qga_ssh_test, |
| 203 | env: test_env, |
| 204 | suite: ['unit', 'qga']) |
| 205 | endif |