1

I have two cmake function to check resources/shader files are not found/ modified matching to build.

Check.cmake

function(Check sourcefile destinationfile)
    if(NOT EXISTS ${destinationfile})
        execute_process(COMMAND ${CMAKE_COMMAND}
                -E copy ${sourcefile} ${destinationfile})
    elseif(${sourcefile} IS_NEWER_THAN ${destinationfile})
        execute_process(COMMAND ${MSGMERGE_EXECUTABLE}
                "--update" ${destinationfile} ${sourcefile}
                OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret)

        if(ret) # Have to do this hack as msgmerge prints to stderr.
            message(SEND_ERROR "${error}")
        endif()
    endif()
endfunction()

AddResources.cmake

include(./Check.cmake)

function(AddResources project)
    file(GLOB_RECURSE resources ${PROJECT_SOURCE_DIR}/src/project1/Resources/*)
    file(GLOB_RECURSE shaders ${PROJECT_SOURCE_DIR}/src/project1/Shaders/*)
    foreach( each_file1 ${resources} )
        get_filename_component(targetFile ${each_file1} NAME)
        if(WIN32)
          set(destinationfile "${CMAKE_CURRENT_SOURCE_DIR}/bin/Release/${targetFile}")
          set(destinationfile2 "${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug/${targetFile}")
          set(sourcefile ${each_file1})
          Check(${sourcefile} ${destinationfile})
          Check(${sourcefile} ${destinationfile2})
        else ()
          set(destinationfile "${CMAKE_CURRENT_SOURCE_DIR}/bin/${targetFile}")
          set(sourcefile ${each_file1})
          Check(${sourcefile} ${destinationfile})
        endif()
    endforeach(each_file1)
    foreach( each_file2 ${shaders} )
        get_filename_component(targetFile ${each_file2} NAME)
        if(WIN32)
          set(destinationfile "${CMAKE_CURRENT_SOURCE_DIR}/bin/Release/${targetFile}")
          set(destinationfile2 "${CMAKE_CURRENT_SOURCE_DIR}/bin/Debug/${targetFile}")
          set(sourcefile ${each_file2})
          Check(${sourcefile} ${destinationfile})
          Check(${sourcefile} ${destinationfile2})
        else()
          set(destinationfile "${CMAKE_CURRENT_SOURCE_DIR}/bin/${targetFile}")
          set(sourcefile ${each_file2})
          Check(${sourcefile} ${destinationfile})
        endif()

    endforeach(each_file2)
endfunction()

It is executed AddResources(project1) in the CMakeLists.txt.

AddResources will copy all of resources and shaders to bin folder, but it copies only once(CMake configuration process), not every build-time.

Is there any way to execute CMake function every build-time with argument?

sysexits
  • 11
  • 1
  • 6
  • Do you **need** your `Check` function to be executed at *build* stage, or do you just **want** `destination` file to be updated whenever `source` file is changed? If you want only dependency checking (the second case), it can be done even on *configuration* stage. See, e.g. [this question](http://stackoverflow.com/questions/34799916/cmake-copy-file-from-source-directory-to-binary-directory). BTW, generating files in *source* directory (under `CMAKE_CURRENT_SOURCE_DIR`) normally is not good. Probably, you want to generate them in *build* directory (under `CMAKE_CURRENT_BINARY_DIR`)? – Tsyvarev Jan 17 '16 at 15:49

1 Answers1

0

I think you're looking for add_custom_command

add_custom_command(TARGET target
               PRE_BUILD | PRE_LINK | POST_BUILD
               COMMAND command1 [ARGS] [args1...]
               [COMMAND command2 [ARGS] [args2...] ...]
               [WORKING_DIRECTORY dir]
               [COMMENT comment] [VERBATIM])

This defines a new command that will be associated with building the specified target. When the command will happen is determined by which of the following is specified:
PRE_BUILD - run before all other dependencies
PRE_LINK - run after other dependencies
POST_BUILD - run after the target has been built

Mohammad
  • 1,253
  • 1
  • 10
  • 26
  • Did I use it right? "COMMAND ${CMAKE_COMMAND} -P "${PROJECT_SOURCE_DIR}/AddResources.cmake" project1" It causes error like that `MSB3073 The command "setlocal "...` – sysexits Jan 17 '16 at 06:54
  • Okay. I tested that command in the Mac, there is no errors during compile process, but it doesn't change anything. That's not working – sysexits Jan 17 '16 at 07:14
  • First of all, `AddResources.cmake` just defines a function without doing anything. More importantly I don't think you can use previously declared variables in scripts with `cmake -P` (see http://stackoverflow.com/a/13713505/400303) – Mohammad Jan 17 '16 at 07:25
  • I tried to execute COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/src/project1/Shaders/. ${PROJECT_SOURCE_DIR}/bin/ in the add_custom_command, it doesn't copy files whenever I tried to build in the visual studio. I need to use another functionality in the CMake. – sysexits Jan 17 '16 at 07:29
  • As you recommend, I also tried to put declared variables using -D option, but it is not working, so I did use copy command. – sysexits Jan 17 '16 at 07:35
  • 1
    This solution is working for people (see http://stackoverflow.com/a/6126754/400303). You should debug you script (eg `make VERBOSE=1`) – Mohammad Jan 17 '16 at 07:38