gonzo
gonzo

Reputation: 519

CMake: Source file depends on source file

I am embedding a source file into another source file using inline assembly and .incbin, which is just like I want it. I will not accept the standard objcopy method, which while works is (imho) the lesser method. xxd is also an option, but really only for very small includes. I have a static site builder that takes a lot of resources and packs it into a single program, which is very quick with .incbin.

Unfortunately, adding the JS file to the list of sources is not enough:

ninja explain: output CMakeFiles/jsapp.dir/static_site.c.o older than most recent input static_site.c (1629797306094133842 vs 1629797311521966739)
ninja explain: CMakeFiles/jsapp.dir/static_site.c.o is dirty
ninja explain: jsapp is dirty
[2/2] Linking C executable jsapp

The main C file that embeds the JS is not being rebuilt, but the static site source which is unrelated here is because the timestamp changed.

How can I tell CMake that source.c now depends on some_file.js?

Upvotes: 2

Views: 596

Answers (2)

jiandingzhe
jiandingzhe

Reputation: 2131

I'm recently doing exactly the same work, and I'm redirected to this question from my own duplicate question.

According to CMake official documentation, the OBJECT_DEPENDS property only works on makefile and ninja generators, but would take no effect on IDE generators like Visual Studio and XCode. So I tried another way to do it. In brief:

  • The pure-inline-assembly part is generated to a separate source file (let's say rcs_asm.cpp). Other auxiliary code parts (exists in my situation) is generated to another C++ file (let's say rcs_blob.cpp).
  • The rcs_asm.cpp is manually compiled to object file (let's say rcs_asm.o) with cmake_custom_command which allows you to specify file-level dependency:
add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rcs_asm.o
    MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/rcs_asm.cpp
    DEPENDS ${all_those_input_resource_files}
    COMMAND "${CMAKE_CXX_COMPILER}" -c -o ${CMAKE_CURRENT_BINARY_DIR}/rcs_asm.o ${CMAKE_CURRENT_BINARY_DIR}/rcs_asm.cpp
    VERBATIM)
  • the generated object file and blob C++ file is then compiled into a library:
add_library(rcs_lib STATIC
    ${CMAKE_CURRENT_BINARY_DIR}/rcs_blob.cpp
    ${CMAKE_CURRENT_BINARY_DIR}/rcs_asm.o)

The separation of pure-inline-assembly part make rcs_asm.cpp needs no optimization flags, so you don't need to compile in different build types with their flags accordingly, thus don't need to work with nasty generator expressions.

Upvotes: 0

gonzo
gonzo

Reputation: 519

As per @arrowd 's idea:

set_source_files_properties(main.c OBJECT_DEPENDS
    ${CMAKE_SOURCE_DIR}/my.js
)

Worked beautifully.

Upvotes: 2

Related Questions