crystal-lang / shards

Dependency manager for the Crystal language
Other
758 stars 99 forks source link

FR: Option for out-of-source builds #585

Open stellarpower opened 1 year ago

stellarpower commented 1 year ago

The way shards manages directories by default is quite nice (i.e. bin, lib, src. and the YAML at the root), in that it is consistent, easy to follow, the project is self-contained, etc. At the same time, from experience, in-source builds do have the potential to create mess, make version control harder, and cause more risks for accidentally destroying source code when cleaning builds. IMO there is something to be said for keeping your clean, version-controlled code away form all of the mess of building for the machine you are sitting on, and I recently got a but stumped when I had failed to realise a stale lib folder was being copied into my docker image and then causing problems I couldn't reproduce either inside or outside the container.

I'd like to propose the option of performing an out-of-source build with shards, so that users may choose freely which pattern is best for them. There are upsides and downsides to both, so I won't argue either way, but I think the ability to choose would be a good option to have. The intermingling of object code and source code always comes at a tradeoff against the self-contained nature of building in the same location, and I think there are probably as many people who think it's easier to ignore build files in their code and have one directory as there are who want to include only code and cache builds elsewhere.

Given that one way shards really excels is its simplicity and uniform nature that Just Works :TM:, I think possibly adding an option similar to how cmake works might be a way of achieving this. I.e., we assume that the CWD is implicitly always the build directory, and for an out-of-source build we simply point shards to the normal location of our source tree.

So shards build --root /path/to/code would install libraries to ./lib, output binaries to ./bin, and e.g. could symlink to src/ and shards.yml that live within /path/to/code/. Without this option it behaves as it does presently; this feature shouldn't introduce any breaking changes but be optional for users. A few other steps may be required also - (i.e. most projects place their assets in src/ but there could be other files we need). Presumably the lock file would be in the build directory too.

Thanks

straight-shoota commented 1 year ago

The location where dependencies are placed can be configured via environment variable SHARDS_INSTALL_PATH. I figure that should cover the bulk of it.

The output dir of shards build can also be configured via SHARDS_BIN_PATH.

Shards itself does not bother about the src directory.

It might be convenient to combine this into an option as proposed. But I figure it would make more sense to just compose these path overrides based on a common directory, and keep the actual source folder as shards' working directory. That's cleaner and less fragile than symlinking stuff from the source directory.

Blacksmoke16 commented 1 year ago

The output dir of shards build can also be configured via SHARDS_BIN_PATH.

Oh, wouldn't that essentially solve https://github.com/crystal-lang/shards/issues/518 then?

russdill commented 1 year ago

This is complicated by attempting to link to compiled C object files or libraries. Especially with object files, there doesn't appear to be a way to specify the path other than as an absolute path or path relative to the .cr file.

stellarpower commented 1 year ago

I see, that doesn't help things.