Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the ideal way to handle custom file type dependencies in CMake?

Tags:

build

cmake

I'm working on a C++ project where I'm encountering an issue I've also had in the past. Alongside my actual executable, I have shader files that need to be compiled.

Ideally, a file called hello.vert in the source directory would be compiled at build-time to hello.vert.spv in my build output directory.

My Attempt

My current implementation does not work - it seems the output files are not created, and if I replace the COMMAND with something like "echo hi", touch the source files and then build, it does not show any output either. This is essentially what I have created:

add_executable(test test.cpp)

function(build_shader TARGETOBJ SHADERNAME)
    set(FILENAME "${CMAKE_SOURCE_DIR}/${SHADERNAME}")
    set(OUTNAME "${CMAKE_BINARY_DIR}/${SHADERNAME}.spv")
    add_custom_command(OUTPUT ${OUTNAME}
        COMMAND glslc ${FILENAME} -o ${OUTNAME})
    add_custom_target(MAKE_${SHADERNAME} ALL DEPENDS ${FILENAME})
    add_dependencies(${TARGETOBJ} MAKE_${SHADERNAME})
endfunction()

build_shader(test hello.vert)
build_shader(test hello.frag)

In An Ideal World

In plain makefiles, my solution would look like this:

test: hello.vert.spv hello.frag.spv
    ...

%.spv: %
    glslc $< -o $@

In CMake, I haven't been able to find a way to handle certain filetypes in a custom way - this would make the solution as easy as:

add_executable(test test.cpp hello.vert hello.frag)

Is there a sane, reliable way to do this sort of thing?

like image 960
Ethan McTague Avatar asked Oct 22 '25 19:10

Ethan McTague


1 Answers

You meant to:

function(build_shader TARGETOBJ SHADERNAME)
    set(FILENAME "${CMAKE_SOURCE_DIR}/${SHADERNAME}")
    set(OUTNAME "${CMAKE_BINARY_DIR}/${SHADERNAME}.spv")
    add_custom_command(OUTPUT ${OUTNAME}
        COMMAND glslc ${FILENAME} -o ${OUTNAME}
        DEPENDS ${FILENAME})
    add_custom_target(MAKE_${SHADERNAME} ALL DEPENDS ${OUTNAME})
    add_dependencies(${TARGETOBJ} MAKE_${SHADERNAME})
endfunction()

The target depends on OUTNAME. OUTNAME depends on FILENAME.

like image 113
KamilCuk Avatar answered Oct 25 '25 20:10

KamilCuk