Roy T.
Roy T.

Reputation: 9638

Trigger build when non-source files change

Using CMAKE I added a custom command top copy LUA files from the source directory to the output directory when they are changed. However this command is only fired when Visual Studio decided to build a project (even though I used PRE_BUILD for the custom command). Visual Studio only decides to build when a source file (c++ in this case) changes so when I only change LUA files they are not added to the output directory.

Now in Visual Studio I can change the 'Item Type' in the property pages of the LUA files from 'Does not participate in build' to 'Text'. In that case Visual Studio does trigger a build when only the LUA files change. So how do I make sure that CMAKE assigns the correct Item Type to LUA files? (Or are there other solutions?)

The relevant parts of CMakeLists.txt

SET(LUA_Sources
  "lua/initialization.lua")

SOURCE_GROUP("lua" FILES ${LUA_Sources})

ADD_LIBRARY(engine 
  ${LUA_Sources})

foreach(LuaFile ${LUA_Sources})
  ADD_CUSTOM_COMMAND(
    TARGET engine
    PRE_BUILD
    COMMAND ${CMAKE_COMMAND}
    ARGS    -E 
      copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${LuaFile} ${EXECUTABLE_OUTPUT_PATH}/Debug/${LuaFile})
endforeach()

===========================

For reference the solution, closely inspired by Angew was

SET(LUA_Sources
  "lua/initialization.lua")

SOURCE_GROUP("lua" FILES ${LUA_Sources})

set(LUA_Outputs "")
foreach(LuaFile ${LUA_Sources})
  list(APPEND LUA_Outputs ${EXECUTABLE_OUTPUT_PATH}/Debug/${LuaFile})   
endforeach()

add_custom_target(
  lua ALL
  DEPENDS ${LUA_Outputs}
  COMMENT "Copying LUA files"
  VERBATIM
)

foreach(LuaFile ${LUA_Sources})
  ADD_CUSTOM_COMMAND(
    TARGET lua
    COMMAND ${CMAKE_COMMAND}
    ARGS    -E 
      copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${LuaFile} 
endforeach()

I had to switch things around a bit because else the files would not always be copied if they were newer. Probably because of the OUTPUT directive in ADD_CUSTOM_COMMAND instead of the TARGET directive that I use now.

Upvotes: 4

Views: 1106

Answers (1)

If the CMakeList excerpt is complete and the engine target is only supposed to serve as a placeholder to copy the Lua sources, then you're approaching the problem the wrong way. You should use a custom command + custom target combination instead, like this:

set(LUA_Sources
  "lua/initialization.lua")

source_group("lua" FILES ${LUA_Sources})

set(LUA_Outputs "")
foreach(LuaFile ${LUA_Sources})
  add_custom_command(
    OUTPUT ${EXECUTABLE_OUTPUT_PATH}/Debug/${LuaFile}
    COMMAND ${CMAKE_COMMAND}
    ARGS -E copy_if_different
      ${CMAKE_CURRENT_SOURCE_DIR}/${LuaFile}
      ${EXECUTABLE_OUTPUT_PATH}/Debug/${LuaFile}
  )
  list(APPEND LUA_Outputs ${EXECUTABLE_OUTPUT_PATH}/Debug/${LuaFile})
endforeach()

add_custom_target(
  engine ALL
  DEPENDS ${LUA_Outputs}
  COMMENT "Copying LUA files"
  VERBATIM
)

This CMakeList creates a custom command to copy each LUA file, and then a custom target which will drive those custom commands by depending on their outputs. Now dependency tracking will work fine.

Upvotes: 4

Related Questions