Как использовать Vulkan с MinGW? (ошибка R_X86_64_32)

Я пытаюсь настроить простую программу для использования Vulkan. Я установил LunarG SDK. У меня есть крошечная программа, которая просто вызывает vkCreateInstance. Я скомпилировал с этой строкой:

g++ -std=c++11 -I/c/VulkanSDK/1.0.3.1/Include -L/c/VulkanSDK/1.0.3.1/Bin main.cpp -lvulkan-1

Я получаю эту ошибку компилятора, используя 64-битный mingw (MSYS2):

 relocation truncated to fit||R_X86_64_32 against symbol `__imp_vkCreateInstance' defined in .idata$5 section in C:\VulkanSDK\1.0.3.1\Bin/vulkan-1.lib(vulkan-1.dll.b)|

Что я делаю? Я ссылаюсь на правильную библиотеку?


person TheBuzzSaw    schedule 20.02.2016    source источник
comment
Как ни странно, clang прекрасно компилируется. Вместо этого он изолирует ошибки при вызове ckCreateInstance.   -  person TheBuzzSaw    schedule 21.02.2016
comment
О, я просто неправильно использовал vkCreateInstance. Теперь программа работает полностью! Итак, clang работает, а GCC (MinGW) — нет. Иди разберись.   -  person TheBuzzSaw    schedule 21.02.2016


Ответы (4)


Я смог скомпилировать простую программу, просто вызвав vkCreateInstance с MinGW-64.

Возможно, ошибка, которую вы получаете, связана с флагом -m64.

Следуйте ниже моей конфигурации:

  • Windows 8.1
  • IDE NetBeans 8.1
  • Вулкан SDK 1.0.3.1
  • gcc версии 5.3.0 (x86_64-posix-seh-rev0, создан проектом MinGW-W64)

С g++:

Скомпилировать:

g++ -m64 -std=c++11 -c -g -I/C/VulkanSDK/1.0.3.1/Include -MMD -MP -MF "build/Debug/MinGW-Windows/main.o.d" -o build/Debug/MinGW-Windows/main.o main.c

Ссылка на сайт:

g++ -m64 -std=c++11 -o dist/Debug/MinGW-Windows/vulkanfirsttest build/Debug/MinGW-Windows/main.o -L/C/VulkanSDK/1.0.3.1/Bin -lvulkan-1

С gcc:

Скомпилировать:

gcc -m64 -c -g -I/C/VulkanSDK/1.0.3.1/Include -std=c11 -MMD -MP -MF "build/Debug/MinGW-Windows/main.o.d" -o build/Debug/MinGW-Windows/main.o main.c

Ссылка на сайт:

gcc -m64 -o dist/Debug/MinGW-Windows/vulkanfirsttest build/Debug/MinGW-Windows/main.o -L/C/VulkanSDK/1.0.3.1/Bin -lvulkan-1

Исходный код:

#include <stdio.h>
#include <stdlib.h>
#include <vulkan/vulkan.h>

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

    VkInstanceCreateInfo vk_info;
    VkInstance inst = 0;
    VkResult res;

    vk_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;

    vk_info.pNext = NULL;

    vk_info.pApplicationInfo = NULL;

    vk_info.enabledLayerCount = 0;

    vk_info.ppEnabledLayerNames = NULL;

    vk_info.enabledExtensionCount = 0;

    vk_info.ppEnabledExtensionNames = NULL;

    res = vkCreateInstance(&vk_info, NULL, &inst);

    if (res != VK_SUCCESS) {
        // Error!
        printf("Error %d\n", res);        
        return 1;
    };

    printf("Device created: %p\n", inst);

    vkDestroyInstance(inst, NULL);
    return (EXIT_SUCCESS);
}

Выход:

Device created: 0000000000534FD0

person Gomiero    schedule 21.02.2016
comment
У меня есть GCC 4.9 на Windows 7. Я поиграю с 5.3 и посмотрю, что произойдет. - person TheBuzzSaw; 21.02.2016
comment
Я обновился до GCC 5.3, и он все исправил. Я понятия не имею, что было не так раньше. - person TheBuzzSaw; 22.02.2016
comment
Странно, но приятно, что это сработало. У меня была аналогичная проблема при использовании gfortran версии 5.1 (в которой есть ошибка), и решение заключалось в том, чтобы обновить ее до версии 5.3 :) - person Gomiero; 22.02.2016
comment
@Gomiero Почему эти флаги -MMD -MP -MF? - person Alex Byrth; 07.04.2016
comment
@AlexByrth Эти флаги (и вся командная строка) генерируются проектом Netbeans. - person Gomiero; 13.04.2016

Вам обоим повезло больше, чем мне, но опять же, я пытался построить пример с кубом. Я продолжал сталкиваться с проблемой усечения при перемещении, и после некоторых копаний мне удалось связать ее со старым отчетом об ошибке/запросом в службу поддержки: https://sourceforge.net/p/mingw-w64/support-requests/19/

Мое решение состояло в том, чтобы использовать dlltool и извлечь символы из vulkan-1.dll (еще одно старое руководство — http://www.mingw.org/wiki/createimportlibraries). Это не работало полностью, так как не могло извлечь никаких символов, поэтому мне пришлось заполнять их вручную (к счастью, gcc выводит 1 строку для каждого неопределенного символа). По сути, вот начало моего файла vulkan-1.def (добавьте свои функции, по одной на строку в конец):

LIBRARY vulkan-1.dll
vkAllocateCommandBuffers
vkAllocateDescriptorSets
vkAllocateMemory
; add functions as needed, one per line

После подготовки этого файла запустите

dlltool -d vulkan-1.def -l libvulkan-1.a

Теперь вы можете использовать -L. -lvulkan-1 и избежать проблем с перемещением. Моя полная командная строка gcc:

gcc -g cube.c -o cube.exe -I /c/VulkanSDK/1.0.8.0/Include/ -D_WIN32 -DVK_USE_PLATFORM_WIN32_KHR -L . -lvulkan-1 -mwindows

И вуаля, куб работает.

Примечание. Мне также нужно было заменить wcstombs_s на wcstombs, чтобы он скомпилировался. Результирующая строка теперь:

numConverted = wcstombs(argv[iii], commandLineArgs[iii], wideCharLen + 1);
person borancar    schedule 16.04.2016

Вместо того, чтобы использовать -lvulkan-1 или решать проблемы с ddltool, вы можете попробовать явно перечислить vulkan-1.dll, и он должен разрешать символы.

gcc -std=c99 -m64 -g -Wall -Ic:\VulkanSDK\1.0.39.1\Include\vulkan vktest.c -o vktest c:\Windows\System32\vulkan-1.dll

person eloj    schedule 03.02.2017

Мне удалось заставить его работать с 64-разрядной версией TDM-GCC, скопировав vulkan-1.dll в текущий каталог и связав его с ним. -m64 не кажется необходимым, но если vulkan-1.dll не находится в текущем рабочем каталоге, ld.exe аварийно завершает работу.

Конфигурация CMake:

...
FIND_PACKAGE(Vulkan REQUIRED)
IF(WIN32 AND NOT MSVC)
    GET_FILENAME_COMPONENT(Vulkan_LIBRARY_DIR ${Vulkan_LIBRARY} DIRECTORY)
    IF(NOT "${Vulkan_LIBRARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
        MESSAGE(WARNING "If linking to Vulkan fails, try copying vulkan-1.dll to the ${CMAKE_BINARY_DIR} and then set Vulkan_LIBRARY to ${CMAKE_BINARY_DIR}/vulkan-1.dll")
    ENDIF(NOT "${Vulkan_LIBRARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
ENDIF(WIN32 AND NOT MSVC)
TARGET_LINK_LIBRARIES(myprogram ${Vulkan_LIBRARY} ... )
...
person Chris    schedule 16.06.2017