[CMake] call already made makefile

Michael Hertling mhertling at online.de
Sun Nov 7 05:09:47 EST 2010


On 11/06/2010 07:10 PM, Alan W. Irwin wrote:
> On 2010-11-05 22:50-0700 SK wrote:
> 
>> On Fri, Nov 5, 2010 at 1:04 PM, Alan W. Irwin <irwin at beluga.phys.uvic.ca> wrote:
>>> I agree the above idea should work, but dropping add_custom_command
>>> completely and moving the COMMAND to add_custom_target instead (and
>>> dropping all file DEPENDS for the custom target) is even a simpler way
>>> to insure COMMAND gets executed every time the custom target is
>>> built.
>>
>> Yes it always runs, but there is no "output" from add_custom_target.
> 
> True.
> 
>> When the external makefile produces an output needed by some larger
>> dependency chain, then add_custom_command is the only way.
> 
> You may be right for the general case.  However, note that since
> OUTPUT is involved the dependency chain you are talking about must be a
> file dependency chain that occurs as a result of a series of
> add_custom_command or add_custom_target commands.  Note an important
> limitation of such chains is those commands must appear in the same
> CMakeLists.txt file.
> 
> Note also that according to my experiments your general conclusion
> turns out not to be correct for the specific case of external
> libraries.
> 
> To be specific, here are the two different scenarios we are discussing
> for that case.
> 
> I.
> 
> add_custom_command(
>    OUTPUT full_path_to_generated_library dummy
>    COMMAND make
>    WORKING_DIRECTORY full_path to where Makefile is located
>    )
> 
> add_custom_target(
>    extern_lib
>    DEPENDS full_path_to_generated_library
>    )
> 
> add_executable(myexecutable myexcutable.c)
> 
> target_link_libraries(myexecutable full_path_to_generated_library)
> 
> add_dependencies(myexecutable extern_lib)
> 
> II,
> 
> add_custom_target(
>    extern_lib
>    COMMAND make
>    WORKING_DIRECTORY full_path to where Makefile is located
>    )
> 
> add_executable(myexecutable myexcutable.c)
> 
> target_link_libraries(myexecutable full_path_to_generated_library)
> 
> add_dependencies(myexecutable extern_lib)
> 
> where the only difference between I and II is the
> add_custom_command/add_custom_target pair of I is replaced with a
> single add_custom_target with COMMAND specified in II.
> 
> My experiment consisted of touching the actual external library file
> that is referred to for an existing project that used the
> target_link_libraries command. That external library was built
> completely separately (unlike the above two scenarios).  But the
> result of touching that library was that my internal target (a library
> in this case) got relinked.  So in that case, there seemed to be no
> necessity at all that full_path_to_generated_library actually needed
> to appear in an OUTPUT in order for the internal target to be
> relinked. That is why I predict scenario II above should work with no
> problems.
> 
> To explain my reasoning further, With II, every time one of the source
> files of the externally generated library gets changed, then "make
> myexecutable" should rebuild that library through the _target_
> dependency between the myexecutable target and the extern_lib target.
> Because that external library rebuild necessarily changes the file
> full_path_to_generated_library, then myexecutable should be relinked
> because (according to my experiements) target_link_libraries always
> relinks whenever there is a change in the library file that is
> referred to _regardless of the source of the change to that file_.
> 
> Of course, although the above logic seems compelling, it needs to be
> verified by examples.  I am not in a good position to do that, but I
> assume from your posts about the specific external library case you do
> have an example of scenario I that does work properly for external
> libraries or can soon put one together.  If you make the trivial
> change to scenario II, does that example continue to work properly as
> predicted by the above logic?

IMO, the question anything boils down to is: Do you need the output of
a command as an input to ADD_{LIBRARY,EXECUTABLE}() or after a DEPENDS
clause within the same CMakeLists.txt? If you do you must use a custom
command because a custom target is, say, output-less, as SK has stated
correctly. Moreover, you must possibly take further measures to ensure
that the command runs when necessary, e.g. by an accompanying custom
target or a never existing dummy output.

If you do not need the command's output explicitly as an input or a
prerequisite you might get by with a sole custom target. In the above-
mentioned example, you do get by because the output is mentioned only
in TARGET_LINK_LIBRARIES() which results in a file-level dependency of
the link line on that output and no more; in particular, this wouldn't
enable a custom command. Here, in addition, you can afford to have the
custom target build each time as the foreign make command is supposed
to do nothing when there is nothing to do. A different configuration,
e.g. an expensive custom target or further dependencies of the output
in question, would probably require a different approach.

Regards,

Michael


More information about the CMake mailing list