[cmake-developers] [CMake] add_custom_command() OUTPUT does not accept generator expressions, why?
Yves Frederix
yves.frederix+cmake at gmail.com
Wed Apr 6 04:51:11 EDT 2016
Hi Brad,
Thanks for the pointers. I played with this a bit over the last week,
mainly to get familiar with the CMake internals, and it seems that
there are some things that might need discussion before getting to a
solution. Note that all my experiments were done using the VS
generator.
What we basically want to be able to do is something like:
# Create any library.
add_library(test_lib STATIC existing_file.cpp)
# Generate a file in the same directory as the test_lib library was created.
add_custom_target(test_target ALL SOURCES
$<TARGET_FILE_DIR:test_lib>/generated_file.cpp)
add_custom_command(
OUTPUT $<TARGET_FILE_DIR:test_lib>/generated_file.cpp
COMMAND cmake -E touch "$<TARGET_FILE_DIR:test_lib>/generated_file.cpp"
)
Without generator expressions, this works nicely. However, if CMake
were to correctly interpret generator expressions in OUTPUT, then the
corresponding source file would be
$<TARGET_FILE_DIR:test_lib>/generated_file.cpp in add_custom_target,
which in turn, for a multiconfig generator would contain the
configuration in its path. So, basically, a prerequisite for the above
to work is that CMake behaves nicely for the following as well:
add_library(test_lib STATIC existing_file_$<CONFIG>.cpp)
At this moment CMake supports generator expressions in the source
list, so this "should" work. It does not in practice, however:
CMake Error in CMakeLists.txt:
Target "test_target" has source files which vary by configuration. This is
not supported by the "Visual Studio 14 2015" generator.
Intuitively I understand why this is not supported (different
configurations share the same project file in VS, so which source file
would the project point to?) Is this also a technical limitation
though? Or do VS project files (and other multiconfig generator
project files such as xcode) support this setup but was it merely not
implemented yet?
Yves
On Thu, Mar 31, 2016 at 3:39 PM, Brad King <brad.king at kitware.com> wrote:
> On 03/31/2016 07:26 AM, Yves Frederix wrote:
>>> If anyone is interested in trying to implement generator expressions
>>> for custom command outputs, I can provide more details to get started.
>>
>> I am interested in having a go at this. I recently ran into this issue
>> at work as well and actually tried some things already. However, I
>> realized it was not that straightforward (not even talking about doing
>> it 'right' here ;)). Any pointers are welcome!
>
> Thanks!
>
> The main challenge is shown in the cmTargetTraceDependencies::FollowName
> method where it calls cmMakefile::GetSourceFileWithOutput. This logic
> is done without knowledge of the current configuration. Therefore we
> cannot expand generator expressions of the available outputs because
> they may contain $<CONFIG>. Some table of pre-expanded per-config
> outputs mapping back to their cmSourceFile instances may need to be
> built. Achieving this may even require adding a generate-time
> companion of cmSourceFile that knows its configuration. It will need
> to be investigated further.
>
> cmTargetTraceDependencies::CheckCustomCommand currently has a loop
> over all configurations to generate the union of dependencies. This
> is used to allow generator expressions in the DEPENDS option.
> The cmTargetTraceDependencies logic may need to be refactored to move
> the loop over the configurations out to a higher level. We may need
> to trace dependencies separately for each configuration (for multi-
> config generators).
>
> Also see cmCustomCommandGenerator. The generators will need to
> be adapted to use this to get the custom command outputs with
> generator expressions expanded. They already do for the commands
> and dependencies.
>
> -Brad
More information about the cmake-developers
mailing list