pub struct Makefile(/* private fields */);Expand description
An AST node for $ast
Implementations§
Source§impl Makefile
impl Makefile
Sourcepub fn read_relaxed<R: Read>(r: R) -> Result<Makefile, Error>
pub fn read_relaxed<R: Read>(r: R) -> Result<Makefile, Error>
Read makefile from a reader, but allow syntax errors
Sourcepub fn rules(&self) -> impl Iterator<Item = Rule> + '_
pub fn rules(&self) -> impl Iterator<Item = Rule> + '_
Retrieve the rules in the makefile
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "rule: dependency\n\tcommand\n".parse().unwrap();
assert_eq!(makefile.rules().count(), 1);Sourcepub fn rules_by_target<'a>(
&'a self,
target: &'a str,
) -> impl Iterator<Item = Rule> + 'a
pub fn rules_by_target<'a>( &'a self, target: &'a str, ) -> impl Iterator<Item = Rule> + 'a
Get all rules that have a specific target
Sourcepub fn variable_definitions(&self) -> impl Iterator<Item = VariableDefinition>
pub fn variable_definitions(&self) -> impl Iterator<Item = VariableDefinition>
Get all variable definitions in the makefile
Sourcepub fn conditionals(&self) -> impl Iterator<Item = Conditional> + '_
pub fn conditionals(&self) -> impl Iterator<Item = Conditional> + '_
Get all conditionals in the makefile
Sourcepub fn items(&self) -> impl Iterator<Item = MakefileItem> + '_
pub fn items(&self) -> impl Iterator<Item = MakefileItem> + '_
Get all top-level items (rules, variables, includes, conditionals) in the makefile
§Example
use makefile_lossless::{Makefile, MakefileItem};
let makefile: Makefile = r#"VAR = value
ifdef DEBUG
CFLAGS = -g
endif
rule:
command
"#.parse().unwrap();
let items: Vec<_> = makefile.items().collect();
assert_eq!(items.len(), 3); // VAR, conditional, ruleSourcepub fn find_variable<'a>(
&'a self,
name: &'a str,
) -> impl Iterator<Item = VariableDefinition> + 'a
pub fn find_variable<'a>( &'a self, name: &'a str, ) -> impl Iterator<Item = VariableDefinition> + 'a
Find all variables by name
Returns an iterator over all variable definitions with the given name. Makefiles can have multiple definitions of the same variable.
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "VAR1 = value1\nVAR2 = value2\nVAR1 = value3\n".parse().unwrap();
let vars: Vec<_> = makefile.find_variable("VAR1").collect();
assert_eq!(vars.len(), 2);
assert_eq!(vars[0].raw_value(), Some("value1".to_string()));
assert_eq!(vars[1].raw_value(), Some("value3".to_string()));Sourcepub fn add_rule(&mut self, target: &str) -> Rule
pub fn add_rule(&mut self, target: &str) -> Rule
Add a new rule to the makefile
§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_rule("rule");
assert_eq!(makefile.to_string(), "rule:\n");Sourcepub fn add_conditional(
&mut self,
conditional_type: &str,
condition: &str,
if_body: &str,
else_body: Option<&str>,
) -> Result<Conditional, Error>
pub fn add_conditional( &mut self, conditional_type: &str, condition: &str, if_body: &str, else_body: Option<&str>, ) -> Result<Conditional, Error>
Add a new conditional to the makefile
§Arguments
conditional_type- The type of conditional: “ifdef”, “ifndef”, “ifeq”, or “ifneq”condition- The condition expression (e.g., “DEBUG” for ifdef/ifndef, or “(a,b)” for ifeq/ifneq)if_body- The content of the if branchelse_body- Optional content for the else branch
§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_conditional("ifdef", "DEBUG", "VAR = debug\n", None);
assert!(makefile.to_string().contains("ifdef DEBUG"));Sourcepub fn add_conditional_with_items<I1, I2>(
&mut self,
conditional_type: &str,
condition: &str,
if_items: I1,
else_items: Option<I2>,
) -> Result<Conditional, Error>
pub fn add_conditional_with_items<I1, I2>( &mut self, conditional_type: &str, condition: &str, if_items: I1, else_items: Option<I2>, ) -> Result<Conditional, Error>
Add a new conditional to the makefile with typed items
This is a more type-safe alternative to add_conditional that accepts iterators of
MakefileItem instead of raw strings.
§Arguments
conditional_type- The type of conditional: “ifdef”, “ifndef”, “ifeq”, or “ifneq”condition- The condition expression (e.g., “DEBUG” for ifdef/ifndef, or “(a,b)” for ifeq/ifneq)if_items- Items for the if branchelse_items- Optional items for the else branch
§Example
use makefile_lossless::{Makefile, MakefileItem};
let mut makefile = Makefile::new();
let temp1: Makefile = "CFLAGS = -g\n".parse().unwrap();
let var1 = temp1.variable_definitions().next().unwrap();
let temp2: Makefile = "CFLAGS = -O2\n".parse().unwrap();
let var2 = temp2.variable_definitions().next().unwrap();
makefile.add_conditional_with_items(
"ifdef",
"DEBUG",
vec![MakefileItem::Variable(var1)],
Some(vec![MakefileItem::Variable(var2)])
).unwrap();
assert!(makefile.to_string().contains("ifdef DEBUG"));
assert!(makefile.to_string().contains("CFLAGS = -g"));
assert!(makefile.to_string().contains("CFLAGS = -O2"));Sourcepub fn replace_rule(
&mut self,
index: usize,
new_rule: Rule,
) -> Result<(), Error>
pub fn replace_rule( &mut self, index: usize, new_rule: Rule, ) -> Result<(), Error>
Replace rule at given index with a new rule
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let new_rule: makefile_lossless::Rule = "new_rule:\n\tnew_command\n".parse().unwrap();
makefile.replace_rule(0, new_rule).unwrap();
assert!(makefile.rules().any(|r| r.targets().any(|t| t == "new_rule")));Sourcepub fn remove_rule(&mut self, index: usize) -> Result<Rule, Error>
pub fn remove_rule(&mut self, index: usize) -> Result<Rule, Error>
Remove rule at given index
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let removed = makefile.remove_rule(0).unwrap();
assert_eq!(removed.targets().collect::<Vec<_>>(), vec!["rule1"]);
assert_eq!(makefile.rules().count(), 1);Sourcepub fn insert_rule(&mut self, index: usize, new_rule: Rule) -> Result<(), Error>
pub fn insert_rule(&mut self, index: usize, new_rule: Rule) -> Result<(), Error>
Insert rule at given position
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let new_rule: makefile_lossless::Rule = "inserted_rule:\n\tinserted_command\n".parse().unwrap();
makefile.insert_rule(1, new_rule).unwrap();
let targets: Vec<_> = makefile.rules().flat_map(|r| r.targets().collect::<Vec<_>>()).collect();
assert_eq!(targets, vec!["rule1", "inserted_rule", "rule2"]);Sourcepub fn includes(&self) -> impl Iterator<Item = Include>
pub fn includes(&self) -> impl Iterator<Item = Include>
Get all include directives in the makefile
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "include config.mk\n-include .env\n".parse().unwrap();
let includes = makefile.includes().collect::<Vec<_>>();
assert_eq!(includes.len(), 2);Sourcepub fn included_files(&self) -> impl Iterator<Item = String> + '_
pub fn included_files(&self) -> impl Iterator<Item = String> + '_
Get all included file paths
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "include config.mk\n-include .env\n".parse().unwrap();
let paths = makefile.included_files().collect::<Vec<_>>();
assert_eq!(paths, vec!["config.mk", ".env"]);Sourcepub fn find_rule_by_target(&self, target: &str) -> Option<Rule>
pub fn find_rule_by_target(&self, target: &str) -> Option<Rule>
Find the first rule with a specific target name
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let rule = makefile.find_rule_by_target("rule2");
assert!(rule.is_some());
assert_eq!(rule.unwrap().targets().collect::<Vec<_>>(), vec!["rule2"]);Sourcepub fn find_rules_by_target<'a>(
&'a self,
target: &'a str,
) -> impl Iterator<Item = Rule> + 'a
pub fn find_rules_by_target<'a>( &'a self, target: &'a str, ) -> impl Iterator<Item = Rule> + 'a
Find all rules with a specific target name
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "rule1:\n\tcommand1\nrule1:\n\tcommand2\nrule2:\n\tcommand3\n".parse().unwrap();
let rules: Vec<_> = makefile.find_rules_by_target("rule1").collect();
assert_eq!(rules.len(), 2);Sourcepub fn find_rule_by_target_pattern(&self, target: &str) -> Option<Rule>
pub fn find_rule_by_target_pattern(&self, target: &str) -> Option<Rule>
Find the first rule whose target matches the given pattern
Supports make-style pattern matching where % in a rule’s target acts as a wildcard.
For example, a rule with target %.o will match foo.o, bar.o, etc.
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "%.o: %.c\n\t$(CC) -c $<\n".parse().unwrap();
let rule = makefile.find_rule_by_target_pattern("foo.o");
assert!(rule.is_some());Sourcepub fn find_rules_by_target_pattern<'a>(
&'a self,
target: &'a str,
) -> impl Iterator<Item = Rule> + 'a
pub fn find_rules_by_target_pattern<'a>( &'a self, target: &'a str, ) -> impl Iterator<Item = Rule> + 'a
Find all rules whose targets match the given pattern
Supports make-style pattern matching where % in a rule’s target acts as a wildcard.
For example, a rule with target %.o will match foo.o, bar.o, etc.
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "%.o: %.c\n\t$(CC) -c $<\n%.o: %.s\n\t$(AS) -o $@ $<\n".parse().unwrap();
let rules: Vec<_> = makefile.find_rules_by_target_pattern("foo.o").collect();
assert_eq!(rules.len(), 2);Sourcepub fn add_phony_target(&mut self, target: &str) -> Result<(), Error>
pub fn add_phony_target(&mut self, target: &str) -> Result<(), Error>
Add a target to .PHONY (creates .PHONY rule if it doesn’t exist)
§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_phony_target("clean").unwrap();
assert!(makefile.is_phony("clean"));Sourcepub fn remove_phony_target(&mut self, target: &str) -> Result<bool, Error>
pub fn remove_phony_target(&mut self, target: &str) -> Result<bool, Error>
Remove a target from .PHONY (removes .PHONY rule if it becomes empty)
Returns true if the target was found and removed, false if it wasn’t in .PHONY.
If there are multiple .PHONY rules, it removes the target from the first rule that contains it.
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = ".PHONY: clean test\n".parse().unwrap();
assert!(makefile.remove_phony_target("clean").unwrap());
assert!(!makefile.is_phony("clean"));
assert!(makefile.is_phony("test"));Sourcepub fn is_phony(&self, target: &str) -> bool
pub fn is_phony(&self, target: &str) -> bool
Check if a target is marked as phony
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = ".PHONY: clean test\n".parse().unwrap();
assert!(makefile.is_phony("clean"));
assert!(makefile.is_phony("test"));
assert!(!makefile.is_phony("build"));Sourcepub fn phony_targets(&self) -> impl Iterator<Item = String> + '_
pub fn phony_targets(&self) -> impl Iterator<Item = String> + '_
Get all phony targets
§Example
use makefile_lossless::Makefile;
let makefile: Makefile = ".PHONY: clean test build\n".parse().unwrap();
let phony_targets: Vec<_> = makefile.phony_targets().collect();
assert_eq!(phony_targets, vec!["clean", "test", "build"]);Sourcepub fn add_include(&mut self, path: &str) -> Include
pub fn add_include(&mut self, path: &str) -> Include
Add a new include directive at the beginning of the makefile
§Arguments
path- The file path to include (e.g., “config.mk”)
§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_include("config.mk");
assert_eq!(makefile.included_files().collect::<Vec<_>>(), vec!["config.mk"]);Sourcepub fn insert_include(
&mut self,
index: usize,
path: &str,
) -> Result<Include, Error>
pub fn insert_include( &mut self, index: usize, path: &str, ) -> Result<Include, Error>
Insert an include directive at a specific position
The position is relative to other top-level items (rules, variables, includes, conditionals).
§Arguments
index- The position to insert at (0 = beginning, items().count() = end)path- The file path to include (e.g., “config.mk”)
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "VAR = value\nrule:\n\tcommand\n".parse().unwrap();
makefile.insert_include(1, "config.mk").unwrap();
let items: Vec<_> = makefile.items().collect();
assert_eq!(items.len(), 3); // VAR, include, ruleSourcepub fn insert_include_after(
&mut self,
after: &MakefileItem,
path: &str,
) -> Result<Include, Error>
pub fn insert_include_after( &mut self, after: &MakefileItem, path: &str, ) -> Result<Include, Error>
Insert an include directive after a specific MakefileItem
This is useful when you want to insert an include relative to another item in the makefile.
§Arguments
after- The MakefileItem to insert afterpath- The file path to include (e.g., “config.mk”)
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "VAR1 = value1\nVAR2 = value2\n".parse().unwrap();
let first_var = makefile.items().next().unwrap();
makefile.insert_include_after(&first_var, "config.mk").unwrap();
let paths: Vec<_> = makefile.included_files().collect();
assert_eq!(paths, vec!["config.mk"]);Trait Implementations§
impl Eq for Makefile
impl StructuralPartialEq for Makefile
Auto Trait Implementations§
impl Freeze for Makefile
impl !RefUnwindSafe for Makefile
impl !Send for Makefile
impl !Sync for Makefile
impl Unpin for Makefile
impl !UnwindSafe for Makefile
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)