Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: sources are checked before running deps #1494

Open
Dom324 opened this issue Feb 4, 2024 · 8 comments
Open

Bug: sources are checked before running deps #1494

Dom324 opened this issue Feb 4, 2024 · 8 comments
Labels
state: needs triage Waiting to be triaged by a maintainer.

Comments

@Dom324
Copy link

Dom324 commented Feb 4, 2024

Hello,
firstly thanks for making such a great tool!
I believe I found a bug where sources are checked before deps complete:

  compile_sources:
    deps: [preprocess_sources]
    sources:
      - "./build/**/*.cc"
    generates:
      - "./build/**/*.o"
    cmds:
      - for: sources
        cmd: '{{.CXX}} {{.CPPFLAGS}} -c -o $(basename {{.ITEM}} .cc).o {{.ITEM}}'

  preprocess_sources:
    sources:
      - "./src/**/*.cc"
    generates:
      - "./build/**/*.cc"
    cmds:
      # Preprocess src/**/*.cc into build/**/*.cc
      - cp src/main.cc build/main.cc     # dummy command

The preprocess_sources task generates sources for compile_sources. But this is the output that I get:

❯ ls build                                                 # empty dir
❯ task compile_sources
task: [preprocess_sources] cp src/main.cc build/main.cc    # compile_sources does not run at all
❯ ls build
main.cc                                                    # no main.o
❯ task -f compile_sources                                  # force run
task: [preprocess_sources] cp src/main.cc build/main.cc
task: [compile_sources] clang++ .....                      # compile_sources is run
❯ ls build
main.cc  main.o                                            # main.o exists

What I believe is happening is:

  1. compile_sources is called
  2. compile_sources checks it's sources, generates checksum
  3. Call dependencies
    3.1 preprocess_sources generates .cc files in build/
  4. compile_sources does not generate .o files in build/, because build/ was empty when sources were checked

Expected behavior:

  1. compile_sources is called
  2. Call dependencies
    2.1 preprocess_sources generates .cc files in build/
  3. compile_sources checks it's sources, generates checksum
  4. compile_sources generates .o files from sources in build/
  • Task version: 3.34.1
  • Operating system: Ubuntu
  • Experiments enabled: No
@task-bot task-bot added the state: needs triage Waiting to be triaged by a maintainer. label Feb 4, 2024
@living42
Copy link

I have the exactly same problem, seens whether a task is up to date is determined before any tasks executes, if its determined after dependency tasks finishs, the problem would be solved.

@trulede
Copy link

trulede commented Mar 29, 2024

The purpose of sources is to prevent unnecessary work, a strategy which would be impossible is deps were always run. Could you rearrange your taskfile this way?

build:
  cmds:
    - task: preprocess_sources
    - task: compile_sources

compile_sources:
    sources:
      - "./build/**/*.cc"
    generates:
      - "./build/**/*.o"
    cmds:
      - for: sources
        cmd: '{{.CXX}} {{.CPPFLAGS}} -c -o $(basename {{.ITEM}} .cc).o {{.ITEM}}'

  preprocess_sources:
    sources:
      - "./src/**/*.cc"
    generates:
      - "./build/**/*.cc"
    cmds:
      # Preprocess src/**/*.cc into build/**/*.cc
      - cp src/main.cc build/main.cc     # dummy command

@Dom324
Copy link
Author

Dom324 commented Mar 30, 2024

Deps would not run always - they have their own sources (different than the main task).
Main task is invoked, calls deps. Depending tasks check their own sources and run if needed. Main task checks it's sources and runs only if needed.

I can rearrange my taskfile as you showed (actually I already did something similar), but I created the ticket because I believe the current behavior is very unintuitive - I spent quite some time debugging it and was very surprised when I finally realized what is going on.

@trulede
Copy link

trulede commented Mar 30, 2024

You are right. From the code it seems that the deps are run first, then the sources are fingerprinted (glob expanded and then checksum'ed), after which the task runs.

If you run
task compile_sources
aa second time, does it skip the dependency preprocess_sources?

@trulede
Copy link

trulede commented Mar 30, 2024

OK, the problem is actually caused by the for which is evaluated when the task is complied, which is before the deps are run. Because there are no sources at that point, there are no commands created by the for.

The rest of the mechanism is actually working as you expect.

@Dom324
Copy link
Author

Dom324 commented Mar 30, 2024

Ah, interesting, I did not think about the for! So it is indeed a bug?
Thanks for the work :)

@trulede
Copy link

trulede commented Mar 31, 2024

It could be fixed by compiling the task a second time, if the sources had changed (which is the case here).

The maintainers might have a better idea though ...

@trulede
Copy link

trulede commented Mar 31, 2024

This task file has a corrected For/Cmd for testing.

version: '3'

tasks:
  compile_sources:
    deps: [preprocess_sources]
    sources:
      - "./build/*.cc"
    generates:
      - "./build/*.o"
    cmds:
      - for: sources
        cmd: 'touch $(dirname {{.ITEM}})/$(basename {{.ITEM}} .cc).o; echo {{.ITEM}}'

  preprocess_sources:
    sources:
      - "./src/*.cc"
    generates:
      - "./build/*.cc"
    cmds:
      - cp src/main.cc build/main.cc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: needs triage Waiting to be triaged by a maintainer.
Projects
None yet
Development

No branches or pull requests

4 participants