Search code examples
c++cmakevulkancmakelists-options

CMake not including Vulkan header when building Walnut


I'm trying to build this project: https://github.com/Mr-Precise/Walnut-cmake

I'm using Unix Makefiles as a generator and MinGW

This is the error im getting after using make:

D:/Projekty/C++/Walnut-cmake/Walnut/src/Walnut/Application.h:11:10: fatal error: vulkan/vulkan.h: No such file or directory    
11 | #include "vulkan/vulkan.h"       
   |          ^~~~~~~~~~~~~~~~~ compilation terminated.

Although Vulkan is properly installed and added to project

This is my CMakeLists.txt for this file:

cmake_minimum_required(VERSION 3.0.0)
project(Walnut CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Vulkan REQUIRED)
message(STATUS "Found Vulkan: ${Vulkan_LIBRARIES}")
message(STATUS "Vulkan include dirs: ${Vulkan_INCLUDE_DIRS}")
find_package(OpenGL REQUIRED)

include_directories(${PROJECT_NAME} PRIVATE src/Walnut/ImGui ${Vulkan_INCLUDE_DIRS})

\#print all include dirs for this project
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "include dir='${dir}'")
endforeach()

file(GLOB_RECURSE ${PROJECT_NAME}\_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/**.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/**.h
)

add_library(${PROJECT_NAME} ${${PROJECT_NAME}\_SRC})
target_link_libraries(${PROJECT_NAME} PRIVATE ${Vulkan_LIBRARIES})

As you can see I included messages that procude this output:

-- Found Vulkan: C:/VulkanSDK/1.3.268.0/Lib/vulkan-1.lib
-- Vulkan include dirs: C:/VulkanSDK/1.3.268.0/Include

-- include dir='D:/Projekty/C++/Walnut-cmake/Walnut/src'
-- include dir='D:/Projekty/C++/Walnut-cmake/vendor/stb_image'
-- include dir='D:/Projekty/C++/Walnut-cmake/vendor/imgui'
-- include dir='D:/Projekty/C++/Walnut-cmake/vendor/glfw/include'
-- include dir='D:/Projekty/C++/Walnut-cmake/Walnut/Walnut'
-- include dir='D:/Projekty/C++/Walnut-cmake/Walnut/PRIVATE'
-- include dir='D:/Projekty/C++/Walnut-cmake/Walnut/src/Walnut/ImGui'
-- include dir='C:/VulkanSDK/1.3.268.0/Include'`

Which indicates that vulkan is found and the include folder is properly selected. Then it prints out all include dirs and we can see that Vulkan's include directory is present.

I had vulkanSDK installed on D:/ partition before. After installing it in default directory which is C:/... it still doesn't work.

Even after manually typing the path to vulkan.h which was D:\Vulkan... or C:\Vulkan... it still didn't compile. I've tried manually entering the path both in CMakeLists.txt and in .cpp file


Solution

  • Your cmake adds the Vulkan_libraries property but not the actual vulkan target to your library. Additionally, you mark this as a library and presumably you want the header visible to what ever is using it later (ie what ever is trying to transitively include <vulkan/vulkan.h> ) so you probably shouldn't make it PRIVATE unless you make it so that dependencies don't need to know about <vulkan/vulkan.h> from your library.

    This line:

    target_link_libraries(${PROJECT_NAME} PRIVATE ${Vulkan_LIBRARIES})
    

    Should instead be

    target_link_libraries(${PROJECT_NAME} PUBLIC Vulkan::Vulkan)
    

    Based on the information you have given here. PUBLIC makes the transitive dependencies found in the Vulkan::Vulkan target exposed by default in the VulkanSDK visible to other dependencies that depend on your library. It also makes your project library target not just depend on the libraries but also the include directories found in Vulkan::Vulkan target.

    You also mix global and target settings which can cause all sorts of issues that make it hard for us to aid you. But beyond that you're just straight up not using them correctly. This:

    include_directories(${PROJECT_NAME} PRIVATE src/Walnut/ImGui ${Vulkan_INCLUDE_DIRS}
    

    Doesn't work, even as an "old cmake" way of doing things, you aren't using that API right either, I think you meant to say:

    target_include_directories(${PROJECT_NAME} PRIVATE src/Walnut/ImGui ${Vulkan_INCLUDE_DIRS}
    

    which you also don't need to do with using the vulkan target itself, you can just do:

    target_include_directories(${PROJECT_NAME} PRIVATE src/Walnut/ImGui 
    

    But It actually looks like your trying to use something hypothetically provided by a walnut target, which means this whole thing is just wrong. I don't know how to use Walnut, but presumably all you should need to do is something like:

    add_library(${PROJECT_NAME} my_sources...) 
    target_link_libraries(${PROJECT_NAME} public Walnut::Walnut)
    

    Provided Walnut provides the Walnut::Walnut target. In fact, now that I look at your question, I wonder if you even are trying to make a library at all, honestly looks like Walnut is supposed to aid in application development, so I'm guessing you're actually making a main.cpp instead here, in which case

    add_executable(${PROJECT_NAME} main.cpp my_sources...)
    target_link_libraries(${PROJECT_NAME} public Walnut::Walnut)
    

    But this depends on what walnut is and how it works.