ninja-build / ninja

a small build system with a focus on speed
https://ninja-build.org/
Apache License 2.0
10.99k stars 1.58k forks source link

ninja -t clean fails on built directory #1690

Open tomeksowi opened 4 years ago

tomeksowi commented 4 years ago

On macOS the linker doesn't assemble debug info for an executable, you need to call dsymutil for that separately:

rule generatedebug
  command = dsymutil $in

build test.dSYM/: generatedebug test

That builds the test.dSYM directory fine. However, ninja -t clean fails:

$ ninja -t clean
Cleaning... ninja: error: remove(test.dSYM): Directory not empty
0 files.

Is there a way to insert a -r flag for the clean target? Or should the default clean target just work on directories?

jhasse commented 4 years ago

See the discussion in #1334 :)

tomeksowi commented 4 years ago

Thanks:) Not sure about the conclusion of discussion in #1334. The pending patch just ignores the built dir instead of issuing an error. Is this the desired behaviour, or do you want full recursive removal of built dir later on?

jhasse commented 4 years ago

Good question. I'm always a bit scared about full recursive removal of directories. An -r flag sounds like an acceptable solution.

anarazel commented 2 years ago

Good question. I'm always a bit scared about full recursive removal of directories. An -r flag sounds like an acceptable solution.

@jhasse How about doing recursive removal if the output ends with a /, indicating that it's know the output is a directory?

jhasse commented 2 years ago

That sounds a bit too implicit to me.

jtremesay commented 8 months ago

Hi,

I have the same issue when trying to use Ninja for building my static web site (I have strange hobbits…).

The frontend part is handled by vite and I have that in my build.ninja:

rule mkfront
  command = npm run build

build dist/front/: mkfront content/front/ | package.json package-lock.json tsconfig.json vite.config.ts

The site build as expected. But when I try to do a ninja -t clean:

$ ninja -t clean
Cleaning... ninja: error: remove(dist/front): Directory not empty
ninja: error: remove(dist/static): Directory not empty
0 files.
anarazel commented 7 months ago

That sounds a bit too implicit to me.

Other suggestions then?

digit-google commented 7 months ago

Ninja does not support directories as outputs, the main reason being that a directory timestamp doesn't change when the content of one of its files changes (it will only change if you add or remove entries in the directory itself, ignoring file updates, or anything that happens inside sub-directories).

This essentially makes it impossible to guarantee correct incremental builds.

The typical work-around for this is to write commands that create individual zip archives (where the content if first generated into a temporary directory, which is removed after the archive is created). This is a single output file that Ninja can reason about (and will be cleaned with -t clean).

anarazel commented 7 months ago

The typical work-around for this is to write commands that create individual zip archives (where the content if first generated into a temporary directory, which is removed after the archive is created). This is a single output file that Ninja can reason about (and will be cleaned with -t clean).

At least in my case that's not really viable - the output is a large directory of html files that should stay a large directory of html files. There's a stamp file etc for ensuring that dependencies are maintained correctly. The problem is just that ninja -t clean complains. Of course this directory can be 'hidden' from ninja, but that makes things like target names awkward.

digit-google commented 7 months ago

I am not sure I understand your issue then. Can you clarify what you're doing.

If you use a stamp file parallel to the directory, the directory does not have to appear in the Ninja build plan, and Ninja will not complain about it when trying to clean (which will not remove the directory though).

anarazel commented 7 months ago

If you use a stamp file parallel to the directory, the directory does not have to appear in the Ninja build plan, and Ninja will not complain about it when trying to clean (which will not remove the directory though).

I want the directory to appear in the build plan: For one, it allows the target name to properly map to the generated filenames, for another it'd should allow to actually clean the generated files. If I have a target to e.g. generate HTML documentation or code coverage output or whatnot, the output should be cleanable.