'Copying only files which have another file as a sibling [based on extension]?

I am trying to use ANT to copy some files of a C++ build into another directory.

The output of the build looks like this:

/Build
   /LibA
      LibA.lib
      LibA.pdb
   /LibB
      LibB.lib
      LibB.pdb
   /ProjA
      myexe.exe
      myexe.pdb
   /Foo
      foo.exe
      foo.pdb
   /...

Now, I would like to copy all *.exe files and their *.pdb files to another directory (but not the *.pdb files of the libs).

I tried with:

<copy todir="outdir">
   <fileset dir="Build">
      <include name="**/*.exe" />
      <include name="**/*.pdb" />
   </fileset>
</copy>

However, then I will also get the *.pdb files inside the LibA, LibB, ... folders.

Is there any way I can only copy the pdb-files which have an *.exe-file in the same directory as their sibling?
Unfortunately, the folders are not named in any way that would allow using wildcards based on the folder name.

Of course, I could list each file individually, such as:

<include name="ProjA/*.pdb" />
<include name="Foo/*.pdb" />
<!-- ... -->

However, I am thinking that maybe there is an elegant way where I can specify "copy all *.exe files and all *.pdb files which have an *.exe file next to them".

ant


Solution 1:[1]

You could use the <present> selector to find the "sibling" files, something like this:

<copy todir="outdir">
  <fileset dir="Build" includes="**/*.pdb">
    <present targetdir="Build">
      <mapper type="glob" from="*.pdb" to="*.exe" />
    </present>
  </fileset>
  <fileset dir="Build" includes="**/*.exe" />
  <flattenmapper />
</copy>

This will only copy the .pdb files with matching .exe files.

To keep it simple, use a separate fileset for the exe files.

The flatten mapper is only needed if you want to copy just the files ignoring the directory structure in the source.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 martin clayton