Why does CMake make a distinction between a “target” and a “command”?

前端 未结 2 1238
悲哀的现实
悲哀的现实 2021-01-30 08:07

In CMake semantics there is some sort of distinction between \"targets\" and commands\" that is baffling me. In Makefiles, there is no such distinction:

targetn         


        
2条回答
  •  隐瞒了意图╮
    2021-01-30 09:06

    add_custom_command adds a callable function that can have defined outputs (using the OUTPUT and BYPRODUCTS arguments). It can also have dependencies that will be run before the function is called.

    Notice that it does NOT do things that you may think it does due to strange documentation (the makefile examples are very misleading). In particular, it does not have any guarantees about numbers of times it executes. For example, imagine this:

    add_custom_command(OUTPUT /tmp/touched COMMAND echo touch COMMAND touch /tmp/touched)
    add_custom_target(touched-one ALL DEPENDS /tmp/touched)
    add_custom_target(touched-two ALL DEPENDS /tmp/touched)
    

    How many times will "touch" be printed? You don't know, since it's not specified anywhere; make -j2 will print it twice, probably, but it's timing-dependent:

    Scanning dependencies of target touched-two
    Scanning dependencies of target touched-one
    [ 50%] Generating touched
    touch
    [100%] Generating touched
    touch
    [100%] Built target touched-two
    [100%] Built target touched-one
    

    But Ninja will only print it once, probably:

    # rm -rf * && cmake -GNinja ../c ; cmake --build . -- -j 5
    [1/1] Generating touched
    touch
    

    Usually, you'll do an add_custom_command to do some work and that defines an OUTPUT, and then you'll have an add_custom_target that depends on the output of the custom command. Anyone who wants the output depends on the target, and that does give you the guarantees you want.

    Caveat: see this bug for an great example of why building cross-platform metabuild tools is REALLY HARD.

提交回复
热议问题