MSYS2 CMake 路径前缀是 Windows 格式 (C:/) 但需要 MSYS2/*nix 样式 (/c/) 到 link

MSYS2 CMake path prefix is in Windows format (C:/) but needs MSYS2/*nix style (/c/) to link

从 MSYS2 中的 pacman 安装的 CMake 似乎在库和 header/include 路径前加上 C:/,但实际所需的路径格式是 /c/ 的前缀。我使用了一个正则表达式替换作为一个拼凑,但这不是一个非常优雅的解决方案,我担心这会破坏像 MingW 这样的东西。

CMake 获取的库路径仅供参考:

 C:/msys64/mingw64/include/gtk-3.0;C:/msys64/mingw64/include/cairo;C:/msys64/mingw64/include;C:/msys64/mingw64/include/pango-1.0;C:/msys64/mingw64/include/fribidi;C:/msys64/mingw64/include;C:/msys64/mingw64/include/atk-1.0;C:/msys64/mingw64/include/cairo;C:/msys64/mingw64/include/pixman-1;C:/msys64/mingw64/include;C:/msys64/mingw64/include/freetype2;C:/msys64/mingw64/include;C:/msys64/mingw64/include/harfbuzz;C:/msys64/mingw64/include/libpng16;C:/msys64/mingw64/include/gdk-pixbuf-2.0;C:/msys64/mingw64/include/libpng16;C:/msys64/mingw64/include;C:/msys64/mingw64/lib/libffi-3.2.1/include;C:/msys64/mingw64/include/glib-2.0;C:/msys64/mingw64/lib/glib-2.0/include;C:/msys64/mingw64/include

它需要是:

 /c//msys64/mingw64/include/gtk-3.0;/c//msys64/mingw64/include/cairo;/c//msys64/mingw64/include;/c//msys64/mingw64/include/pango-1.0;/c//msys64/mingw64/include/fribidi;/c//msys64/mingw64/include;/c//msys64/mingw64/include/atk-1.0;/c//msys64/mingw64/include/cairo;/c//msys64/mingw64/include/pixman-1;/c//msys64/mingw64/include;/c//msys64/mingw64/include/freetype2;/c//msys64/mingw64/include;/c//msys64/mingw64/include/harfbuzz;/c//msys64/mingw64/include/libpng16;/c//msys64/mingw64/include/gdk-pixbuf-2.0;/c//msys64/mingw64/include/libpng16;/c//msys64/mingw64/include;/c//msys64/mingw64/lib/libffi-3.2.1/include;/c//msys64/mingw64/include/glib-2.0;/c//msys64/mingw64/lib/glib-2.0/include;/c//msys64/mingw64/include

我一直在寻找解决方案,发现 Windows 的 CMake(不是从 MSYS2 中安装的 CMake)有一个特定于 MSYS 的 makefile 生成器,但必须有一些简单的解决方案才能使用 CMake在 MSYS2 中可用。我无法想象我是唯一遇到此问题的人。有人知道干净的解决方案吗?

更新: 这是没有正则表达式替换 hack 的 CMakeLists.txt。这失败并出现错误

C:/msys64/home/username/sample/src/main.cpp:1:10 fatal error: gtk/gtk.h: No such file or directory
 #include <gtk/gtk.h>

compilation terminated.

制作中


    cmake_minimum_required(VERSION 3.12)

    project(sample CXX)

    # Find GTK+ headers/libs with PkgConfig
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(GTK3 REQUIRED gtk+-3.0)

    include_directories(${GTK3_INCLUDE_DIRS})
    link_directories(${GTK3_LIBRARY_DIRS})

    add_definitions(${GTK3_CFLAGS_OTHER})

    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/natives)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/natives)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

    add_executable(sample src/main.cpp)

    target_link_libraries(sample ${GTK3_LIBRARIES})

对于main.cpp,只需使用默认的 GTK+ hello world


    #include <gtk/gtk.h>

    int
    main (int   argc,
    char *argv[])
    {
      GtkWidget *window;

      gtk_init (&argc, &argv);

      window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

      g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

      gtk_widget_show (window);

      gtk_main ();

      return 0;
    }

为了进行编译,我使用了以下 CMake kludge:


    cmake_minimum_required(VERSION 3.12)

    project(sample CXX)

    # Find GTK+ headers/libs with PkgConfig
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(GTK3 REQUIRED gtk+-3.0)

    # Generated paths starting with "C:" need to be converted to /c/ to work with MSYS2
    # TODO remove this or do it some way better at some point in the future
    if(MSYS OR MINGW)
        string(REGEX REPLACE "C:" "/c/" GTK3_INCLUDE_DIRS "${GTK3_INCLUDE_DIRS}")
    endif(MSYS OR MINGW)

    include_directories(${GTK3_INCLUDE_DIRS})
    link_directories(${GTK3_LIBRARY_DIRS})

    add_definitions(${GTK3_CFLAGS_OTHER})

    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/natives)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/natives)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

    add_executable(sample src/main.cpp)

    target_link_libraries(sample ${GTK3_LIBRARIES})

注意 REGEX REPLACE。

另一件需要注意的事情是我只使用工具,例如 cmake 和 libraries/headers/etc。从 MSYS2 中的 pacman 安装,我更愿意保持这种方式,因为我将基于此推出一些东西作为 Ruby 本机扩展和基于 MSYS2 的 Windows SDK。同时,我相当确定我的拼凑会破坏基于 MingW 的构建(如果我什至需要担心这个?)而且它不是很灵活。

问题与 MingW 包 are/were 移植到 MSYS2 的方式有关。路径采用 "Windows" 格式以实现向后兼容性并保持与 Visual Studio 等系统的兼容性。唯一的答案是像我上面指出的那样进行正则表达式替换,或者像我现在选择做的那样重新编译 MSYS2 中的库。

作为一般准则,MSYS2 中可用的包名称中没有 mingw 前缀的包没有此 "backward compatibility" 问题,据我所知,不需要这样的解决方法。