如何为 macOS 编译支持 SPICE 的 QEMU

How to compile QEMU with SPICE support for macOS

为了在某种程度上接近 Parallels Desktop for Mac 提供的体验,我想 运行 一个 Windows 10 虚拟机,它具有 QXL 图形驱动程序和 SPICE 支持macOS 主机。不幸的是,Homebrew nor on MacPorts 上的 QEMU 二进制文件都不提供 SPICE 支持。

QEMU 需要 spice-protocol 和 spice-server 库来编译 SPICE 支持。在 macOS 下 spice-protocol package is available for macOS, I can't seem to find a precompiled package of spice-server. As I tried to compile spice-0.14.2 我遇到了以下错误:

/Library/Developer/CommandLineTools/usr/bin/make  all-recursiveMaking all in .
  CC       red-stream.lo
  CC       red-worker.lo
red-worker.c:1164:40: error: too many arguments to function call, expected 1, have 2
    pthread_setname_np(worker->thread, "SPICE Worker");
    ~~~~~~~~~~~~~~~~~~                 ^~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/pthread.h:512:1: note: 'pthread_setname_np' declared here
__API_AVAILABLE(macos(10.6), ios(3.2))
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/Availability.h:496:162: note: expanded from macro '__API_AVAILABLE'
  ...__API_AVAILABLE6, __API_AVAILABLE5, __API_AVAILABLE4, __API_AVAILABLE3, __API_AVAILABLE2, __API_AVAILABLE1, 0)(__VA_ARGS__)
                                                                             ^
1 error generated.

经过一些研究,在 macOS 上似乎 pthread_setname_np 只能用于更改调用线程的名称。

据我所知,这仅用于调试目的,您可以在为 macOS 编译时安全地注释掉该行。 (您也可以使用条件编译,但如果您只是想编译支持 SPICE 的 QEMU,则没有理由这样做。)


编辑 server/red-worker.c 并注释掉以下行:

pthread_setname_np(worker->thread, "SPICE Worker");

(我用的是nano,你可以用CTRL + W搜索pthread_setname_np(。)


为 macOS(自 0.14.3 起)编译 SPICE 服务器所需的其他更改

  1. 如果在运行./autogen.sh时出现如下错误:

    configure: error: Package requirements (openssl >= 1.0.0) were not met:
    
    No package 'openssl' found
    

    然后设置如下环境变量:

    export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
    export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
    export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
    
  2. server/red-stream.cserver/tests/test-websocket.c 顶部附近的某处添加以下行:

    #define MSG_NOSIGNAL 0x2000 /* don't raise SIGPIPE */
    
  3. server/tools/reds_stat.c中替换下面一行:

    reds_stat = mremap(reds_stat, shm_old_size, shm_size, MREMAP_MAYMOVE);
    

    与:

    munmap(reds_stat, shm_old_size);
    reds_stat = mmap(0, shm_old_size, PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0);
    
  4. 如果我什么都没忘记,所有其他错误都可以是 "solved",方法是从 Makefile 中删除所有出现的 -Werror