foundry: bug (config): file paths not resolved if submodule specifies root path remappings
Component
Forge
Describe the feature you would like
Steps to reproduce:
- Clone this repo and run
forge install - Run
forge build, it fails with the below error - In
lib/forge-test-my-dep, openfoundry.tomland comment out the remappings - Run
forge build, it passes
[⠊] Compiling...
Error:
Failed to resolve file: "/Users/mds/Documents/projects/forge-test-my-proj/lib/forge-test-my-dep/script/BaseScript.sol": No such file or directory (os error 2).
--> "/Users/mds/Documents/projects/forge-test-my-proj/script/Counter.s.sol"
"script/BaseScript.sol"
Check configured remappings.
Additional context
No response
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 7
- Comments: 24 (11 by maintainers)
Commits related to this issue
- Commented out remapping section in foundry config due to https://github.com/foundry-rs/foundry/issues/3440 — committed to elenadimitrova/rollcall by elenadimitrova 2 years ago
- Adding remapping to avoid the foundry bug: https://github.com/foundry-rs/foundry/issues/3440. — committed to jayden-sudo/SoulWalletCore by jayden-sudo 6 months ago
- Merge pull request #16 from jayden-sudo/develop Adding remapping to avoid the foundry bug: https://github.com/foundry-rs/foundry/issues/3440 — committed to SoulWallet/soulwallet-core by jayden-sudo 6 months ago
The fundamental issue is that using a solidity project as a dependency does not mean using its build artifacts, it means using its source code, and therefore its source files, while being built, must resolve their dependencies based on that project’s own dependencies. When this is combined with the fact that many projects have similar dependencies (e.g., on openzep), import resolution conflicts become likely. We can look to other languages for inspiration so as not to reinvent the wheel (e.g., c’s include file search paths, rust toml’s [patch…], etc.
It seems that a necessary/baseline feature would be for solc to be able to resolve imports based on the context of the instant file being parsed. I think this may NOT be a current feature of solc. What I mean by this is that the imports for a file in a/b/c/d should be resolved based on the fact that that file is in a/b/c/d not based on the fact that the file is in a. Then, if a dev wants to globally override what
lib/openzepmeans, there would be some mechanism to explicitly override that resolution everywhere (.e.g., like the toml [patch] or a command line argument to NOT use local context for certain prefixes).The additional problem here is that what a dev has chosen to specify in the import statement, in the source files of a project, plays a big role. As noted in other comments, whether they’ve chosen to use relative import paths in the source and whether those relative import paths state simply
lib/or../[whatever]/libcan matter.At least some of the above I think can be achieved even without explicit compiler support by re-writing of files, and by clever use or remappings. E.g., all dependencies (recursively) could have the imports that match their locally specified remappings re-written to
import "dep1/lib/...";and the remappings specified to the top level compiler would then contains adep1/libremapping. This would mean foundry is essentially pre-processing the source files and compiling the pre-processed output, not the original files.pre-processing of solidity is another topic. I almost always find it necessary to use a (custom) python based pre-processor to generate deployment vs dev versions of solidity files for anything but trivial projects. E.g., to strip out console2.log() calls, and/or restructure source files so that contracts deployed to public chains, vs those deployed to anvil or hardhat nodes for testing, are lean and clean.
The solidity language devs, IMHO, are not spending enough effort on these issues and need to do an iteration on some of the language features that relate to devops.
Just bumped into this issue while installing @mds1’s library solidity-generators.
I also have absolute import paths, and I want to counter @mattsse’s suggestion from above that we should simply use relative paths.
Relative paths can get really ugly and hard to maintain in complex projects; several Foundry users use absolute paths because of the aforementioned reason.
For future reference: when @mattsse said this:
He was referring to set one or more of the following remappings in your project:
You only have to do this for those remappings that are overwritten by your dependencies.
@PaulRBerg 🤝🤝🤝 Absolutely agree on this.
@mattsse, I can’t really help atm with the MR, but many devs that come from TypeScript environment are used to path aliases and I cannot find any con in using them in the smart contracts as well. Huge smart contract repos are seeking for usable remappings inside themselves.