-
Notifications
You must be signed in to change notification settings - Fork 211
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
Read compiler configurations from toml #1347
Read compiler configurations from toml #1347
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Gave it a first review round. Looks quite good already
examples/solana/solana_config.toml
Outdated
llvm-IR_optimization_level = "default" # Set llvm optimizer level. Valid options are "none", "less", "default", "aggressive" | ||
|
||
[compiler-output] | ||
#verbose = false # show debug messages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think all of them need to be commented out
llvm-IR_optimization_level = "default" # Set llvm optimizer level. Valid options are "none", "less", "default", "aggressive" | ||
|
||
[compiler-output] | ||
#verbose = false # show debug messages |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
src/bin/cli/mod.rs
Outdated
@@ -35,6 +36,18 @@ pub enum Commands { | |||
|
|||
#[command(about = "Generate Solidity interface files from Anchor IDL files")] | |||
Idl(IdlCommand), | |||
|
|||
#[command(about = "Create a new project with a ready example")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[command(about = "Create a new project with a ready example")] | |
#[command(about = "Create a new Solang project")] |
src/bin/cli/mod.rs
Outdated
#[arg(name = "TARGETNAME",required= true, long = "target", value_parser = ["solana", "substrate", "evm"], help = "Target to build for [possible values: solana, substrate]", num_args = 1, hide_possible_values = true)] | ||
pub target_name: String, | ||
|
||
#[arg(name = "INPUT", help = "project name", num_args = 1, value_parser = ValueParser::os_string())] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[arg(name = "INPUT", help = "project name", num_args = 1, value_parser = ValueParser::os_string())] | |
#[arg(name = "INPUT", help = "Name of the project", num_args = 1, value_parser = ValueParser::os_string())] |
src/bin/cli/mod.rs
Outdated
pub struct Compile { | ||
#[arg(name = "CONFFILE", help = "Take arguments from configuration file", long = "configuration-file", exclusive = true, value_parser = ValueParser::os_string(), required_unless_present = "INPUT", num_args = 0..=1, default_missing_value = "Solang.toml")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's better to no use a capital S in the default file
#[arg(name = "CONFFILE", help = "Take arguments from configuration file", long = "configuration-file", exclusive = true, value_parser = ValueParser::os_string(), required_unless_present = "INPUT", num_args = 0..=1, default_missing_value = "Solang.toml")] | |
#[arg(name = "CONFFILE", help = "Take arguments from configuration file", long = "configuration-file", exclusive = true, value_parser = ValueParser::os_string(), required_unless_present = "INPUT", num_args = 0..=1, default_missing_value = "solang.toml")] |
src/bin/cli/mod.rs
Outdated
pub struct Compile { | ||
#[arg(name = "CONFFILE", help = "Take arguments from configuration file", long = "configuration-file", exclusive = true, value_parser = ValueParser::os_string(), required_unless_present = "INPUT", num_args = 0..=1, default_missing_value = "Solang.toml")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can just name this flag --config
(or config-file
) to keep it shorter?
src/bin/cli/mod.rs
Outdated
"ast-dot"|"cfg"|"llvm-ir"|"llvm-bc" |"object"| "asm" => { | ||
Ok(Some(value)) | ||
}, | ||
_ => {Err(serde::de::Error::custom("Invalid option for `emit`. Valid options are: `ast-dot`, `cfg`, `llvm-ir`, `llvm-bc`, `object`, `asm`"))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not seem to be formatted correctly
src/bin/cli/mod.rs
Outdated
let name = if let Some(name) = &target_arg.name { | ||
name | ||
} else { | ||
eprintln!("error: must specifiy target name"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eprintln!("error: must specifiy target name"); | |
eprintln!("error: compilation target not specified"); |
src/bin/cli/mod.rs
Outdated
} | ||
|
||
pub(crate) fn target_arg(target_arg: &TargetArg) -> Target { | ||
if target_arg.name.as_str() == "solana" || target_arg.name.as_str() == "evm" { | ||
let name = if let Some(name) = &target_arg.name { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest calling this variable target_name
.
src/bin/cli/mod.rs
Outdated
} | ||
} | ||
|
||
fn emit_de<'de, D>(deserializer: D) -> Result<Option<String>, D::Error> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function deserves a better name.
fn default_true() -> bool { | ||
true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per this PR iddm/serde-aux#23, you don't need this function. You could just write default_true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for some reason, bool_true
doesn't work
src/bin/cli/test.rs
Outdated
package_toml = r#" | ||
contracts = ["flipper"] # Contracts to include from the compiled files | ||
import_path = ["path1", "path2"] | ||
import_map = ["map1=path", "map2=path2"] # Maps to import. Define as : import_paths = ["map=path/to/map", "map2=path/to/map2", ..]"#; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other commands like target, optimizations and emit could also be tested.
} | ||
|
||
#[derive(Args)] | ||
pub struct New { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This struct deserves a better name. New
is too generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree on this one, I don't see how this could not be very obvious that it's the struct for the new
subcommand, given the struct is in the cli
module. Additionally I think it's confusing if the struct name diverges from the subcommand name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense here, but fn new(args: New)
in line 70 from src/bin/solang.rs
deserves either another name or a doc comment. I suggested a new name here because of this awkward construct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm yeah that's a good point, the new
function should definitively be renamed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be called init
, just like git init
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cargo allows cargo init
and cargo new
. git new
does not exist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But there is cargo contract new
https://github.com/paritytech/cargo-contract#cargo-contract-new-my_contract
Signed-off-by: salaheldinsoliman <[email protected]>
ee1978c
to
a3ef22e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work, thanks! ❤️
Can you please add a short section in the docs about this?
What readers might be curios about is what the default values look like. E.g. if you have an empty TOML or empty sections in the TOML.
Also my gut feeling is that many users want to depend on some openzepplin contracts, would be nice if the docs would show how to use importmaps in the TOML file.
Cargo.toml
Outdated
@@ -60,6 +60,7 @@ scale-info = "2.4" | |||
petgraph = "0.6.3" | |||
wasmparser = "0.106.0" | |||
wasm-encoder = "0.28" | |||
toml = "0.7.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.7.4 is the latest. It might be better to use "0.7"
because we are unlikely to care about the patch level
examples/solana/solana_config.toml
Outdated
input_files = ["flipper.sol"] # Files to be compiled. You can define multiple files as : input_files = ["file1", "file2", ..] | ||
contracts = ["flipper"] # Contracts to include from the compiled files | ||
import_path = [] | ||
import_map = [] # Maps to import. Define as : import_paths = ["map=path/to/map", "map2=path/to/map2", ..] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an unnatural way of specifying a map in toml. How about
[package]
[import_map]
map1 = "path/to/map"
map2 = "path/to/other/map"
} | ||
|
||
#[derive(Args)] | ||
pub struct New { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be called init
, just like git init
?
} | ||
|
||
#[derive(Args)] | ||
pub struct New { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cargo allows cargo init
and cargo new
. git new
does not exist
Signed-off-by: salaheldinsoliman <[email protected]>
Signed-off-by: salaheldinsoliman <[email protected]>
Signed-off-by: salaheldinsoliman <[email protected]>
src/bin/cli/mod.rs
Outdated
@@ -127,10 +261,22 @@ pub struct TargetArg { | |||
pub value_length: Option<u64>, | |||
} | |||
|
|||
#[derive(Args, Deserialize, Debug, PartialEq)] | |||
pub struct CompileTargetArg { | |||
#[arg(name = "TARGET", required_unless_present = "CONFFILE" ,long = "target", value_parser = ["solana", "substrate", "evm"], help = "Target to build for [possible values: solana, substrate]", num_args = 1, hide_possible_values = true)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason we need required_unless_present = "CONFFILE"
here?
src/bin/cli/mod.rs
Outdated
#[derive(Args)] | ||
#[derive(Args, Deserialize, Debug, PartialEq)] | ||
pub struct CompilePackage { | ||
#[arg(name = "INPUT", help = "Solidity input files",value_parser = ValueParser::path_buf(), num_args = 1.., required_unless_present = "CONFFILE")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as my comment above. Then, given a solang.toml
file is present, we can just do solang compile
(akin to how you can just cargo build
in Rust projects). Which I'd find really neat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good pointer, Thanks
Signed-off-by: salaheldinsoliman <[email protected]>
Signed-off-by: salaheldinsoliman <[email protected]>
Signed-off-by: salaheldinsoliman <[email protected]>
docs/running.rst
Outdated
solang new --target solana my_project | ||
|
||
Start a new Solang project with an example `flipper.sol <https://github.com/hyperledger/solang/blob/main/examples/solana/flipper.sol>`_ contract, | ||
next to an example configuration file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
next to an example configuration file. | |
and a default configuration file. |
docs/running.rst
Outdated
Starting a new project | ||
______________________________ | ||
|
||
|
||
solang new --target solana my_project | ||
|
||
Start a new Solang project with an example `flipper.sol <https://github.com/hyperledger/solang/blob/main/examples/solana/flipper.sol>`_ contract, | ||
next to an example configuration file. | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Paragraph needs to explain the user in more detail what exactly a "Solang project" is (that it creates a new directory with a default config file is just the product of this command, but we also need to explain the purpose of these Projects)
llvm-IR-optimization-level = "default" # Set llvm optimizer level. Valid options are "none", "less", "default", "aggressive" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FIY I just merged #1365, could you include that here too?
src/bin/solang.rs
Outdated
match create_dir(&dir_path) { | ||
Ok(_) => (), | ||
Err(error) => { | ||
eprintln!("couldn't create project directory, reason: {error}"); | ||
exit(1) | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
match create_dir(&dir_path) { | |
Ok(_) => (), | |
Err(error) => { | |
eprintln!("couldn't create project directory, reason: {error}"); | |
exit(1) | |
} | |
}; | |
if let Err(error) = create_dir(&dir_path) { | |
eprintln!("couldn't create project directory, reason: {error}"); | |
exit(1); | |
} |
src/bin/cli/mod.rs
Outdated
|
||
impl PackageTrait for CompilePackage { | ||
fn get_input(&self) -> &Vec<PathBuf> { | ||
match &self.input { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use map_err
instead of the match here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think .expect()
would look better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Panicking is not the same as std::process::exit(1)
. While technically the result is almost the same (I'm not sure whether we care about the different exit code). An unwrap or expect implies that this is a situation we do not anticipate for, and if it should ever happen regardless there's nothing to do about it. Here we can terminate in a more graceful way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but a map_err would imply converting the Option<> to a Result<> beforehand. I think an if let Some()
would suffice, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I didn't pay attention close enough, sorry. Yes you could return inside the if let
and exit afterwards. Or leave it like it is, it's not terribly important
@@ -218,10 +449,50 @@ pub(crate) fn target_arg(target_arg: &TargetArg) -> Target { | |||
target | |||
} | |||
|
|||
pub fn imports_arg(package: &Package) -> FileResolver { | |||
pub trait PackageTrait { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a comment explaining the trait and what it's used for
docs/running.rst
Outdated
name = "solana" # Target name | ||
|
||
|
||
Fields that are not explicitly present in the .toml file are defaulted. If any other argument is provided in the command line, for example, ``solang compile --config-file --target substrate``, the argument will be overridden. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fields that are not explicitly present in the .toml file are defaulted. If any other argument is provided in the command line, for example, ``solang compile --config-file --target substrate``, the argument will be overridden. | |
Fields not explicitly present in the .toml acquire the compiler's default value. If any other argument is provided in the command line, for example, ``solang compile --config-file --target substrate``, the argument will be overridden. |
docs/running.rst
Outdated
name = "solana" # Target name | ||
|
||
|
||
Fields that are not explicitly present in the .toml file are defaulted. If any other argument is provided in the command line, for example, ``solang compile --config-file --target substrate``, the argument will be overridden. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I need to specify the .toml
file I am referring to when I run solang compile --config-file
? What happens when I have more than one .toml
file in my repository?
If you are creating a .toml
with a reserved name, that should be noted in the documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default one is solang.toml
, but if a special name is used, it will be taken instead.
|
||
/// Constructor that initializes the `bool` value to the given `init_value`. | ||
@payer(payer) | ||
constructor(address payer, bool initvalue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constructor(address payer, bool initvalue) { | |
constructor(bool initvalue) { |
There is no need to pass the payer as an argument.
Signed-off-by: salaheldinsoliman <[email protected]>
strength-reduce = true | ||
vector-to-slice = true | ||
common-subexpression-elimination = true | ||
llvm-IR-optimization-level = "default" # Set llvm optimizer level. Valid options are "none", "less", "default", "aggressive" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not apply to llvm-IR only, also to target specific machine code. This should be called llvm-optimization-level
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Co-authored-by: Lucas Steuernagel <[email protected]> Signed-off-by: Cyrill Leutwiler <[email protected]>
1- Implement taking solang's configurations from toml file.
solang compile --configuration-file
.2- Implement solang new. a command that creates a new directory with a flipper example as well as the corresponding toml file.
solang new --target substrate
.