vector-of-bool / cmrc

A Resource Compiler in a Single CMake Script
MIT License
672 stars 74 forks source link

Undefined reference to get_filesystem() #25

Open william-swy opened 3 years ago

william-swy commented 3 years ago

I seem to have an issue with linking a library that uses cmrc. For example I have a file called foo.cpp in my src dir which has code that calls cmrc::resource_name::filesystem(). When I build this library I have no issues but when I link this library to its respective test file I have linkage issues where there is an error of undefined reference to cmrc::resource_name::filesystem().

vector-of-bool commented 3 years ago

Are you linking the cmrc_add_resource_library() library into the consuming library with PUBLIC?

william-swy commented 3 years ago

I do have a target_link_libraries(foo PUBLIC resource_name).

morgabm commented 2 years ago

I am also facing this issue and would like help resolving.

I am attempting to link my library to the library generated with cmrc_add_resource_library, which seems to work fine until I attempt to build an executable.

CMakeLists.txt for my library

set(RENE_COMPOSITOR_SOURCE
    r_window.h
    r_window.cpp
    r_pipeline.h
    r_pipeline.cpp
)

add_library(rene-compositor STATIC ${RENE_COMPOSITOR_SOURCE})

if (CMAKE_VERSION VERSION_GREATER 3.12)
  set_property(TARGET rene-compositor PROPERTY CXX_STANDARD 20)
endif()

target_include_directories(rene-compositor
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
    PUBLIC ${GLFW_INCLUDE_DIR}
    PUBLIC ${Vulkan_INCLUDE_DIRS}
)

############## Build SHADERS #######################

# Find all vertex and fragment sources within shaders directory
# taken from VBlancos vulkan tutorial
# https://github.com/vblanco20-1/vulkan-guide/blob/all-chapters/CMakeLists.txt
find_program(GLSL_VALIDATOR glslangValidator HINTS 
  ${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE} 
  /usr/bin 
  /usr/local/bin 
  ${VULKAN_SDK_PATH}/Bin
  ${VULKAN_SDK_PATH}/Bin32
  $ENV{VULKAN_SDK}/Bin/ 
  $ENV{VULKAN_SDK}/Bin32/
)

# get all .vert and .frag files in shaders directory
file(GLOB_RECURSE GLSL_SOURCE_FILES
  "${CMAKE_CURRENT_SOURCE_DIR}/shaders/*.frag"
  "${CMAKE_CURRENT_SOURCE_DIR}/shaders/*.vert"
)

foreach(GLSL ${GLSL_SOURCE_FILES})
  get_filename_component(FILE_NAME ${GLSL} NAME)
  set(SPIRV "${CMAKE_CURRENT_SOURCE_DIR}/shaders/${FILE_NAME}.spv")
  add_custom_command(
    OUTPUT ${SPIRV}
    COMMAND ${GLSL_VALIDATOR} -V ${GLSL} -o ${SPIRV}
    DEPENDS ${GLSL})
  list(APPEND SPIRV_BINARY_FILES ${SPIRV})
endforeach(GLSL)

add_custom_target(
    rene-shaders
    DEPENDS ${SPIRV_BINARY_FILES}
)

add_dependencies(rene-compositor rene-shaders)
add_compile_definitions(RENE_SHADER_DIR=${CMAKE_CURRENT_BINARY_DIR}/shaders)

############## Embed SHADERS #######################

cmrc_add_resource_library(reneshaders ALIAS rene::shaders ${SPIRV_BINARY_FILES})

target_link_libraries(rene-compositor PUBLIC ${Vulkan_LIBRARIES} glfw rene::shaders)

CMakeLists.txt for my executable

add_executable(rene-triangles
    triangles.cpp
)

if (CMAKE_VERSION VERSION_GREATER 3.12)
  set_property(TARGET rene-triangles PROPERTY CXX_STANDARD 20)
endif()

target_link_libraries(rene-triangles 
    PRIVATE rene-includes 
    PRIVATE rene-compositor
)

Output from a clean build

>------ Build started: Project: CMakeLists, Configuration: Debug ------
  [1/30] Generating reneshaders resource loader
  [2/30] Generating ../../../../../src/compositor/shaders/simple_shader.vert.spv
  D:/dev/rene/rene/src/compositor/shaders/simple_shader.vert
  [3/30] Generating ../../../../../src/compositor/shaders/simple_shader.frag.spv
  D:/dev/rene/rene/src/compositor/shaders/simple_shader.frag
  [4/30] Generating intermediate file for D:/dev/rene/rene/src/compositor/shaders/simple_shader.vert.spv
  [5/30] Generating intermediate file for D:/dev/rene/rene/src/compositor/shaders/simple_shader.frag.spv
  [6/30] Building CXX object src\compositor\CMakeFiles\reneshaders.dir\__cmrc_reneshaders\intermediate\shaders\simple_shader.vert.spv.cpp.obj
  [7/30] Building CXX object src\compositor\CMakeFiles\reneshaders.dir\__cmrc_reneshaders\intermediate\shaders\simple_shader.frag.spv.cpp.obj
  [8/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\osmesa_context.c.obj
  [9/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\init.c.obj
  [10/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\window.c.obj
  [11/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\context.c.obj
  [12/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\vulkan.c.obj
  [13/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\input.c.obj
  [14/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\monitor.c.obj
  [15/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\win32_thread.c.obj
  [16/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\win32_time.c.obj
  [17/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\win32_init.c.obj
  [18/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\wgl_context.c.obj
  [19/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\win32_monitor.c.obj
  [20/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\egl_context.c.obj
  [21/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\win32_joystick.c.obj
  [22/30] Building C object external\glfw\src\CMakeFiles\glfw.dir\win32_window.c.obj
  [23/30] Linking C static library external\glfw\src\glfw3.lib
  [24/30] Building CXX object src\compositor\CMakeFiles\reneshaders.dir\__cmrc_reneshaders\lib.cpp.obj
  [25/30] Linking CXX static library src\compositor\reneshaders.lib
  [26/30] Building CXX object src\compositor\CMakeFiles\rene-compositor.dir\r_window.cpp.obj
  [27/30] Building CXX object src\compositor\CMakeFiles\rene-compositor.dir\r_pipeline.cpp.obj
  [28/30] Building CXX object src\targets\triangles\CMakeFiles\rene-triangles.dir\triangles.cpp.obj
  [29/30] Linking CXX static library src\compositor\rene-compositor.lib
  [30/30] Linking CXX executable src\targets\triangles\rene-triangles.exe
  FAILED: src/targets/triangles/rene-triangles.exe 
  cmd.exe /C "cd . && "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_exe --intdir=src\targets\triangles\CMakeFiles\rene-triangles.dir --rc=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\rc.exe --mt=C:\PROGRA~2\WI3CF2~1\10\bin\100190~1.0\x64\mt.exe --manifests  -- C:\PROGRA~1\MICROS~3\2022\COMMUN~1\VC\Tools\MSVC\1433~1.316\bin\Hostx64\x64\link.exe /nologo src\targets\triangles\CMakeFiles\rene-triangles.dir\triangles.cpp.obj  /out:src\targets\triangles\rene-triangles.exe /implib:src\targets\triangles\rene-triangles.lib /pdb:src\targets\triangles\rene-triangles.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console  src\compositor\rene-compositor.lib  C:\VulkanSDK\1.3.224.1\Lib\vulkan-1.lib  external\glfw\src\glfw3.lib  src\compositor\reneshaders.lib  kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
  LINK Pass 1: command "C:\PROGRA~1\MICROS~3\2022\COMMUN~1\VC\Tools\MSVC\1433~1.316\bin\Hostx64\x64\link.exe /nologo src\targets\triangles\CMakeFiles\rene-triangles.dir\triangles.cpp.obj /out:src\targets\triangles\rene-triangles.exe /implib:src\targets\triangles\rene-triangles.lib /pdb:src\targets\triangles\rene-triangles.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL /subsystem:console src\compositor\rene-compositor.lib C:\VulkanSDK\1.3.224.1\Lib\vulkan-1.lib external\glfw\src\glfw3.lib src\compositor\reneshaders.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:src\targets\triangles\CMakeFiles\rene-triangles.dir/intermediate.manifest src\targets\triangles\CMakeFiles\rene-triangles.dir/manifest.res" failed (exit code 1120) with the following output:
D:\dev\rene\rene\out\build\x64-debug\rene-compositor.lib(r_pipeline.cpp.obj) : error LNK2019: unresolved external symbol "class cmrc::embedded_filesystem __cdecl cmrc::rene::shaders::get_filesystem(void)" (?get_filesystem@shaders@rene@cmrc@@YA?AVembedded_filesystem@3@XZ) referenced in function "public: __cdecl rene::Pipeline::Pipeline(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??0Pipeline@rene@@QEAA@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z)
D:\dev\rene\rene\out\build\x64-debug\src\targets\triangles\rene-triangles.exe : fatal error LNK1120: 1 unresolved externals
  ninja: build stopped: subcommand failed.
vector-of-bool commented 2 years ago

Sorry for the delay on this. It got lost in my backlog.

It is possible that the namespace generated by the library and the namespace generated by CMRC_DECLARE do not match. The argument to CMRC_DECLARE must exactly match the NAMESPACE given when the library way generated. If no NAMESPACE was specified, it should be just the library's base name (not the ALIAS name)