Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

cmake - How to always run command when building regardless of any dependency?

I want to run a cmake command that parses the whole source tree, so I can't list all possible dependencies in cmake's add_custom_command/add_custom_target commands.

Is it possible to tell cmake just to run a command without any conditions? I tried all solutions found on the net (including SO) but they all assume that the command is dependent on few known files being up to date.

I found a solution but it does not work reliably:

cmake_minimum_required(VERSION 2.6)

project(main)

add_custom_command(
   OUTPUT file1
   COMMAND echo touching file1
   COMMAND touch file1
   DEPENDS file2)
add_custom_target(dep ALL DEPENDS file1 file2)

# this command re-touches file2 after dep target is "built"
# and thus forces its rebuild
ADD_CUSTOM_COMMAND(TARGET dep
          POST_BUILD
          COMMAND echo touching file2
          COMMAND touch file2
)

and this is output:

queen3@queen3-home:~/testlib$ make
[100%] Generating file1
touching file1
touching file2
[100%] Built target dep
queen3@queen3-home:~/testlib$ make
[100%] Generating file1
touching file1
touching file2
[100%] Built target dep
queen3@queen3-home:~/testlib$ make
touching file2
[100%] Built target dep
queen3@queen3-home:~/testlib$ 

As you can see, on third run it did not generate file1, even though file2 was touched previously. Sometimes it happens every 2nd run, sometimes every 3rd, sometimes every 4th. Is it a bug? Is there another way to run a command without any dependency in cmake?

Strange but if I add TWO commands to re-touch file2, i.e. just copy-paste the post-build command, it works reliably. Or maybe it will fail every 1000th run, I'm not sure yet ;-)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

While I'm not at all pleased with this solution, posting since I stumbled on this page and didn't see it mentioned.

You can add a custom target that references a missing file,

eg:

add_custom_target(
    my_custom_target_that_always_runs ALL
    DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/__header.h
)

add_custom_command(
    OUTPUT
        ${CMAKE_CURRENT_BINARY_DIR}/__header.h  # fake! ensure we run!
        ${CMAKE_CURRENT_BINARY_DIR}/header.h    # real header, we write.
    # this command must generate: ${CMAKE_CURRENT_BINARY_DIR}/header.h
    COMMAND some_command
)

This will keep running the custom command because __header.h is not found.

See a working example where this is used.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...