CMake: Relink on File Change
~ 3 Minute Read.
In the last blog post (“WebXR in C++”) there was
a minor inconvenience left in the cmake example.
If you change the library_webxr.js
, it will not relink and therefore your output
.js
accompanying the WASM would not get regenerated.
I thought — “Hey, let’s fix that real quick and then write about that!”. Two hours later I found a solution for you:
Generate a dummy .cpp
file for the library whenever library_webxr.js changes
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/webxr.cpp COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/webxr.cpp DEPENDS library_webxr.js)
Using that file, you can create empty library. This will cause it to be recompiled
when library_webxr.js changes. Transitively anything that links to it will be relinked.
I’m also adding library_webxr.js
and webxr.h
here so that they show up in IDEs:
add_library(webxr STATIC webxr.h library_webxr.js ${CMAKE_CURRENT_BINARY_DIR}/webxr.cpp) target_include_directories(webxr PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
Finally, adding the linker flag:
# "link" the webxr javascript library when linking to webxr # Next release of CMake will contain "INTERFACE_LINK_OPTIONS"! if(NOT CMAKE_VERSION VERSION_LESS 3.12.0) set_property(TARGET webxr APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS " --js-library ${CMAKE_CURRENT_SOURCE_DIR}/library_webxr.js") else() # *UGLY HACK* to get --js-library into the link parameters. May only work if webxr # target is linked last, so be aware of that or use cmake >= 3.12.0 # Also, note that there is no whitespace prefix as in the above. set_property(TARGET webxr APPEND_STRING PROPERTY INTERFACE_LINK_LIBRARIES "--js-library ${CMAKE_CURRENT_SOURCE_DIR}/library_webxr.js") endif()
Now you can link the target webxr
to your own target that depends on it and should
be relinked with changes to the javascript file:
target_link_libraries(your-target PRIVATE webxr)
Note that the webxr
target in this case may need to be linked last, because of the
ugly workaround for CMake not supporting INTERFACE_LINK_OPTIONS
(which was added two
weeks ago in this commit)
until the soon to be released version 3.12.0.
A safer option would be to just add the linker flags to the depending target manually. See
the previous blog post for more details.
Found solution in 120 minutes, written in 20 minutes, edited in 5 minutes.