[CMake] custom target like add_executable

Bill Newcomb bnewcomb at nvidia.com
Thu Feb 5 16:12:57 EST 2015


I was missing the dependency of foo.sha1 on foo, but adding it doesn't
change the behavior in this example--it is still regenerated after every
make.  But now I think I see why.

Commenting out first one, then the other of my add_custom_*, I start 
to see why this is the case--add_custom_output doesn't do anything 
at all if the OUTPUT isn't used by something else, and add_custom_target
targets are ALWAYS out of date.

If I delete the following lines from CMakeFiles/foo.sha1.dir/build.make,
it works exactly like I'd want it to:

--- b/CMakeFiles/foo.sha1.dir/build.make        2015-02-05 12:27:58.169468000 -0800
+++ b.good/CMakeFiles/foo.sha1.dir/build.make   2015-02-05 12:26:24.804643000 -0800
@@ -52,10 +52,7 @@  
        @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --blue --bold "Generating foo.sha1"
        openssl sha1 -out /home/bnewcomb/tmp/cmake-tests/test-fail/b/foo.sha1 /home/bnewcomb/tmp/cmake-tests/test-fail/foo
   
-foo.sha1: CMakeFiles/foo.sha1
-foo.sha1: foo.sha1
 foo.sha1: CMakeFiles/foo.sha1.dir/build.make  
-.PHONY : foo.sha1
   
 # Rule to build all files generated by this target.
 CMakeFiles/foo.sha1.dir/build: foo.sha1

I have been using the workaround you suggested below as a stopgap, but it
has the drawback of being non-obvious to users that in order to generate 
the file named foo.sha1 from the command line they need to type 
'make target_foo.sha1' instead of 'make foo.sha1'.

The following (anti-)pattern actually does what I want, although it's
a gratuitous hack:


add_custom_target(target_foo.sha1 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1)                                                     
add_custom_target(foo.sha1 ALL)
add_dependencies(foo.sha1 target_foo.sha1)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1
    COMMAND openssl sha1 -out ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1 ${CMAKE_CURRENT_SOURCE_DIR}/foo
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/foo
    )


Mostly, I wanted to figure out if this were possible with existing 
cmake, and my curiosity is satisfied.

Thanks,
B.


On 02/05/2015 11:37 AM, Alan W. Irwin wrote:
> On 2015-02-05 10:14-0800 Bill Newcomb wrote:
> 
>> A contrived example:
>>
>> $ ls ..
>> b  CMakeLists.txt  foo
>>
>> $ cat ../CMakeLists.txt
>> cmake_minimum_required(VERSION 3.1)
>>
>> add_custom_target(foo.sha1 ALL DEPENDS 
>> ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1)
>>
>> add_custom_command(
>>    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1
>>    COMMAND openssl sha1 -out ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1 
>> ${CMAKE_CURRENT_SOURCE_DIR}/foo
>>    )
>>
> 
> Hi Bill:
> 
> I am virtually positive that target name = filename as in the above
> example will cause circular dependencies (as you have observed) since
> for at least the default "Unix Makefiles" generator target names are 
> usually identified with the
> corresponding filename which name clashes in this case.  Also, your
> add_custom_command has no DEPENDS so by definition it is always out of
> date and will keep being repeated.  I am not familiar with
> command-line openssl, but I assume ${CMAKE_CURRENT_SOURCE_DIR}/foo is
> the dependency there.
> 
> Therefore, I suggest the following modifications:
> 
> add_custom_command(
>      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1
>      COMMAND openssl sha1 -out ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1 
> ${CMAKE_CURRENT_SOURCE_DIR}/foo
>      DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/foo
>      )
> 
> add_custom_target(target_foo.sha1 ALL DEPENDS 
> ${CMAKE_CURRENT_BINARY_DIR}/foo.sha1)
> 
> (Note, the target name "target_foo.sha1" which no longer corresponds
> to a real file name (i.e., it has the .PHONY attribute in the Makefile 
> similar to the
> "all", "install", "help", etc., targets), and the DEPENDS line on the
> custom command.)
> 
> After running cmake, then
> 
> make VERBOSE=1  (or make VERBOSE=1 target_foo.sha1) should run the 
> openssl command
> 
> Subsequent make commands should not run that openssl command since the
> result foo.sha1 will have a later date than foo.  Subsequently, if you
> touch foo, then any of the above make commands will run that openssl
> command (once) again.
> 
> Alan
> __________________________
> Alan W. Irwin
> 
> Astronomical research affiliation with Department of Physics and Astronomy,
> University of Victoria (astrowww.phys.uvic.ca).
> 
> Programming affiliations with the FreeEOS equation-of-state
> implementation for stellar interiors (freeeos.sf.net); the Time
> Ephemerides project (timeephem.sf.net); PLplot scientific plotting
> software package (plplot.sf.net); the libLASi project
> (unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
> and the Linux Brochure Project (lbproject.sf.net).
> __________________________
> 
> Linux-powered Science
> __________________________

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------


More information about the CMake mailing list