Copy Task fails to copy on the first run

I have a strange problem. I have tried phrasing what I trying to do in a couple of slightly different ways but it fails to work as I expect it to.

I have a native project that has x86 and x64 targetPlatforms set. When I run the install task I want to run a pre-step that will copy over the additional files and resources needed by one of the Prebuilt Dependencies (CEF3 in this case).

The task itself runs because I see it in the output but on the first run of the install task (any of these actually) it fails to copy the files. When I rerun the install task where most of the steps are UP-TO-DATE the files are actually getting copied into the install output directory.

Here is the task I am creating (I create one for each platform / configuration and hook it into the install’s task as dependency since there are also prebuilt dll’s not only shared resources):

// Copy over CEF3 additional dependencies and resources
tasks.withType(InstallExecutable) { installTask -> 

  def taskName = "copyCef" + ( - "install" - "Executable") + "Data"
  def cefDir = "../dependencies/cef/lib"

  //def arch = <- this returns 'targetPlatform' why? It should return something like 'x86' 'x64' right?
  //def outputDir = installTask.destinationDir.getAbsolutePath(); <- destinationDir is null why?
  task(taskName, type: Copy) {

      def arch = name.contains("X86") ? "x86" : "x64"
      def configuration = name.contains("Debug") ? "debug" : "release"

      def libDir = "${cefDir}/${arch}/${configuration}"
      def resDir = "${cefDir}/resources"

      from("${cefDir}/${arch}/${configuration}") {
        include "*.bin" 
        include "wow_helper.exe" 
        include "widevinecdmadapter.dll" 
        include "d3dcompiler_43.dll" 
        include "d3dcompiler_47.dll"  
      from "${cefDir}/resources"
      into {
        def outputDir = file("build/install/editor/${arch}/${configuration}/lib");
    installTask.dependsOn name

    // Moving the task later in the chain does not help
    def exeTask = - "install"
    exeTask = exeTask[0].toLowerCase() + exeTask.substring(1)
    dependsOn exeTask

Thing to note: the last lines were added to move the task to later stage when the ‘exe’ is built I thought maybe that was the problem but nope. Also the commented lines are suspicious - usually this worked when I tried to access the installTask destinationDir but for some reason it was null I guess because InstallTask was not yet configured? Is there a way to defer configuration of this task but keep the execution before install task?

I investigated a little bit more and it seems that it is not the problem that the output directory is not there because when its created but empty it still doesn’t copy the files over.

It only does so when the initial exe is actually there with all the dependency dll’s and this task is up to date like so:

:editor:linkEditorX64ReleaseExecutable UP-TO-DATE
:editor:editorX64ReleaseExecutable UP-TO-DATE

But the task copyCef*** is always triggered just sometimes without any effect.

Any ideas? Anyone?

Edit: I am starting to think this is due to the fact that when the create executable task is not up to date it nukes the whole directory before it creates new install.

Can anyone help with this problem?

I need to hook into Install task because Visual Studio plugin that generates the project in a way that when running the debugger it runs the install task and I need files, librares and other resources for the debugged app to function.

The problem is that the install task when executed removes the directory when it’s not up-to-date therefore it removes the files I just copied to the directory.

What I need is to be able to run install task and be sure that all the files that are needed for the created exe to be there in the install task output directory.

EDIT: I made it working using finalizedBy instead of injecting the dependsOn to the install task. Is this feasible solution?

Hi Adrian,

Yep, the install task wipes out it’s output directory when executed.

Adding a task that writes to the output of another task is, in general, not a good idea.
Even if that task is not wiping out it’s outputs, overlapping outputs make it more difficult for the up-to-date checks to save you time.

Using finalizedBy in your case sounds good!