[Cmake] ADD_CUSTOM_COMMAND etc

Andy Cedilnik andy.cedilnik at kitware.com
Thu Apr 10 08:15:29 EDT 2003


Hi Neil,

I just tried this:

PROJECT(Test)

SET (LATEX_COMPILE latex)

SET(DOC_ROOT ${Test_SOURCE_DIR}/Documentation)

ADD_CUSTOM_TARGET (LaTeXDocument ALL)
ADD_CUSTOM_COMMAND(
    SOURCE    ${DOC_ROOT}/junk.tex
    COMMAND   ${LATEX_COMPILE}
    ARGS      ${DOC_ROOT}/junk.tex
    TARGET    LaTeXDocument
    OUTPUTS   ${Test_BINARY_DIR}/junk.dvi
)
ADD_CUSTOM_COMMAND(
    SOURCE    LaTeXDocument
    TARGET    LaTeXDocument
    DEPENDS   ${Test_BINARY_DIR}/junk.dvi
)

And it works fine.

So, to translate to Makefile, here is what it does:

the custom target
all: LaTeXDocument

LaTeXDocument:
  # do nothing ( no command )

The second custom command adds this to the custom target:

all: LaTeXDocument

LaTeXDocument:
${Test_BINARY_DIR}/junk.dvi
  # still nothing ( no command in custom target nor
  # custom command)

Now we add the first custom command:

all: LaTeXDocument

LaTeXDocument:
${Test_BINARY_DIR}/junk.dvi
  # still nothing ( no command in custom target nor
  # custom command)

${Test_BINARY_DIR}/junk.dvi: ${DOC_ROOT}/junk.tex
  ${LATEX_COMPILE} ${DOC_ROOT}/junk.tex

So, custom command in general does this:

<OUTPUTS>: <SOURCE> <DEPENDS>
  <COMMAND> <ARGS>

The special case is when SOURCE is the same as TARGET. This means append
the rule to the target. So, as you see, the dependencies are appended to
the list of target dependencies and commands are appended to the list of
commands. For example:

ADD_CUSTOM_TARGET(foo ALL)
ADD_CUSTOM_COMMAND(SOURCE foo
 TARGET foo
 COMMAND echo 
 ARGS "Whatever")

Would be:

all: foo

foo: 
  echo "Whatever"

I hope that makes sense.

On Wed, 2003-04-09 at 22:32, Neil Killeen wrote:
> This example still produces no actual custom command code
> in the resultant Makefile and so running it does nothing.  I have attached
> my exact CMakeLists.txt  file and the resultant Makefile
> To be clear, I am using CMake V 1.6

Make sure all parentheses are correct.

> I don't understand this statement.  Isn't the first CUSTOM_COMMAND
> self contained ?   I would expect that the outcome was the junk.dvi
> file.  Why do I need the second one to drive the first one ?
> Why is there a dependency on junk.dvi ?  That is what I
> am trying to make, not what I am looking for a dependency on

You need a starting rule. The target LaTeXDocument will always get
executed. But it can depend on something which is conditional. So, in
this case LaTeXDocument will depend on junk.dvi, which would mean that
every time LaTeXDocument is executed, it will verify that junk.dvi is up
to date.

> The line
> >     SOURCE    LaTeXDocument
> is confusing to me.  Isn't LaTeXDocument just a label for
> the custom command so that you can associate it with the
> ADD_CUSTOM_TARGET ?     You said that the SOURCE file was
> just checked to be valid before it was used, not the label.

This is exception in custom command. If SOURCE is same as TARGET, it
will append rule to the target. Look example up.

> 3. I was planning a simple copy for files that are HTML source.  Thus
> SET (HTML_COMPILE cp)
> SET(DOC_ROOT ${MITK_SOURCE_DIR}/Documentation}
> 
> ADD_CUSTOM_TARGET (HTMLDocument ALL)
> ADD_CUSTOM_COMMAND(
>     SOURCE    ${DOC_ROOT}/junk.html
>     COMMAND   ${HTML_COMPILE}
>     ARGS      ${DOC_ROOT}/junk.html ${MITK_BINARY_DIR}/junk.html
>     TARGET    HTMLDocument
>     OUTPUTS   ${MITK_BINARY_DIR}/junk.html
> )

First of all, if you want to copy files platform independently, use
cmake for that:

ADD_CUSTOM_COMMAND(
    SOURCE    ${DOC_ROOT}/junk.html
    COMMAND   ${CMAKE_COMMAND}
    ARGS      -E copy ${DOC_ROOT}/junk.html ${MITK_BINARY_DIR}/junk.html
    TARGET    HTMLDocument
    OUTPUTS   ${MITK_BINARY_DIR}/junk.html
)

But now you need that second custom command to drive this one. At this
point nothing needs ${MITK_BINARY_DIR}/junk.html, so this rule will
never happen. Except if you type make ${MITK_BINARY_DIR}/junk.html I
guess. 

Add second custom comman:

ADD_CUSTOM_COMMAND(
    SOURCE    HTMLDocument
    TARGET    HTMLDocument
    DEPENDS   ${MITK_BINARY_DIR}/junk.html
)

And it will work.

> Since the output file is now in the ARGS List, what is the role
> of the OUTPUTS variable here ?

CMake does not know what arguments are. For example, back to latex, how
could CMake know what latex produces? What if you use some shell script?
The OUTPUTS here is a hint to CMake so that it knows how to properly
setup dependencies.

> AGain I suppose I need your second ADD_CUSTOM_COMMAND to drive
> this one.
> My mind is clearly not yet mapped to the way CMake requires.  :-(

I think once you get this working and maybe another thing, you will
completely understand how this works.

Good luck.

			Andy




More information about the CMake mailing list