diff --git a/bakefile.jar b/bakefile.jar
new file mode 100644
index 0000000..a268f9a
Binary files /dev/null and b/bakefile.jar differ
diff --git a/src/fr/monlouyan/bakefile/BakeCLI.java b/src/fr/monlouyan/bakefile/BakeCLI.java
index e3462ee..34d1981 100644
--- a/src/fr/monlouyan/bakefile/BakeCLI.java
+++ b/src/fr/monlouyan/bakefile/BakeCLI.java
@@ -15,7 +15,7 @@ public class BakeCLI {
     /*
      * Mode debug activé ou non
      */
-    private boolean debug;
+    private static boolean debug;
 
     /*
      * Liste des arguments passés en ligne de commande
@@ -30,7 +30,7 @@ public class BakeCLI {
      * @see Main
      */
     public BakeCLI(String[] args){
-        this.debug = false;
+        debug = false;
         this.targets = new ArrayList<>();
         parseArgs(args);
     }
@@ -54,7 +54,7 @@ public class BakeCLI {
      * Permet de savoir si le mode debug est activé ou non.
      * @return true si le mode debug est activé, false sinon
      */
-    public boolean isDebug(){ return debug; }
+    public static boolean isDebug(){ return debug; }
 
     /**
      * Permet de récupérer les arguments autres que "-d" passés en ligne de commande
diff --git a/src/fr/monlouyan/bakefile/BakeEngine.java b/src/fr/monlouyan/bakefile/BakeEngine.java
index 7751a62..574058b 100644
--- a/src/fr/monlouyan/bakefile/BakeEngine.java
+++ b/src/fr/monlouyan/bakefile/BakeEngine.java
@@ -2,7 +2,6 @@ package fr.monlouyan.bakefile;
 
 import java.util.List;
 
-
 public class BakeEngine {
     private BakeCLI cli;
     private BakefileParser parser;
@@ -12,15 +11,16 @@ public class BakeEngine {
     public BakeEngine(BakeCLI cli) {
         this.cli = cli;
         this.parser = new BakefileParser("Bakefile");
-        this.resolver = new DependencyResolver(cli.isDebug());
-        this.executor = new CommandExecutor(cli.isDebug());
+        this.resolver = new DependencyResolver(BakeCLI.isDebug());
+        this.executor = new CommandExecutor(BakeCLI.isDebug());
     }
     
     public void run() {
-        List<Target> targets = parser.parse();
-        List<Target> targetsToBuild = resolver.resolve(targets, cli.getTargets());
-        for (Target target : targetsToBuild) {
-            executor.execute(target);
+        List<Rule> rules = parser.parse();
+        List<Rule> rulesToBuild = resolver.resolve(rules, cli.getTargets());
+        
+        for (Rule rule : rulesToBuild) {
+            executor.execute(rule);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/fr/monlouyan/bakefile/BakefileParser.java b/src/fr/monlouyan/bakefile/BakefileParser.java
index 07cae52..6202da4 100644
--- a/src/fr/monlouyan/bakefile/BakefileParser.java
+++ b/src/fr/monlouyan/bakefile/BakefileParser.java
@@ -26,8 +26,10 @@ public class BakefileParser {
         this.filename = filename;
     }
 
-    public List<Target> parse() {
-        List<Target> targets = new ArrayList<>();
+    public List<Rule> parse() {
+        List<Rule> rules = new ArrayList<>();
+        Set<String> phonyTargets = new HashSet<>();
+
         if (!Files.exists(Paths.get(filename))) {
             System.out.println("*** No targets specified and no makefile found.  Stop.");
             System.exit(1);
@@ -44,30 +46,29 @@ public class BakefileParser {
                 Matcher commandMatcher = COMMAND_PATTERN.matcher(line);
 
                 if (targetMatcher.matches()) {
-                    // Sauvegarde de la précédente target si elle existe
+                    // Sauvegarde de la règle précédente si elle existe
                     if (currentTarget != null) {
-                        targets.add(new Target(currentTarget, dependencies, String.join(" && ", commands)));
+                        rules.add(new Rule(currentTarget, dependencies, commands, phonyTargets.contains(currentTarget)));
                     }
 
-                    // Nouvelle target détectée
+                    // Nouvelle cible détectée
                     currentTarget = targetMatcher.group(1);
                     dependencies = new ArrayList<>(Arrays.asList(targetMatcher.group(2).trim().split("\\s+")));
                     commands = new ArrayList<>();
-
                 } else if (commandMatcher.matches()) {
-                    // Ligne de commande associée à la dernière target trouvée
+                    // Ligne de commande associée à la dernière cible trouvée
                     commands.add(commandMatcher.group(1));
                 }
             }
 
-            // Ajout de la dernière target après la boucle
+            // Ajout de la dernière règle après la boucle
             if (currentTarget != null) {
-                targets.add(new Target(currentTarget, dependencies, String.join(" && ", commands)));
+                rules.add(new Rule(currentTarget, dependencies, commands, phonyTargets.contains(currentTarget)));
             }
 
         } catch (IOException e) {
             e.printStackTrace();
         }
-        return targets;
+        return rules;
     }
 }
diff --git a/src/fr/monlouyan/bakefile/CommandExecutor.java b/src/fr/monlouyan/bakefile/CommandExecutor.java
index dd37dfc..786ecd3 100644
--- a/src/fr/monlouyan/bakefile/CommandExecutor.java
+++ b/src/fr/monlouyan/bakefile/CommandExecutor.java
@@ -9,20 +9,31 @@ public class CommandExecutor {
         this.debug = debug;
     }
     
-    public void execute(Target target) {
-        if (!target.needsUpdate()){
-            System.out.println("bake: '" + target.getName() + "' is up to date.");
+    public void execute(Rule rule) {
+        if (rule.getCommands().isEmpty()) {
+            System.out.println("bake: Nothing to be done for '" + rule.getName() + "'.");
             return;
-        };
+        }
+
+        if (!rule.needsUpdate()){
+            System.out.println("bake: '" + rule.getName() + "' is up to date.");
+            return;
+        }
+        
         try {
-            System.out.println(target.getCommand());
-            ProcessBuilder pb = new ProcessBuilder("sh", "-c", target.getCommand());
-            Process process = pb.start();
-            int exitCode = process.waitFor();
-            if (debug) System.out.println("Executed: " + target.getCommand() + " with exit code " + exitCode);
-            if (exitCode != 0) System.err.println("Error executing " + target.getName());
+            for (String command : rule.getCommands()) {
+                System.out.println(command); // Affichage de la commande executée
+                ProcessBuilder pb = new ProcessBuilder("sh", "-c", command);
+                Process process = pb.start();
+                int exitCode = process.waitFor();
+                if (debug) System.out.println("Executed: " + command + " with exit code " + exitCode);
+                if (exitCode != 0) {
+                    System.err.println("Error executing " + rule.getName() + "");
+                    break;
+                }
+            }
         } catch (IOException | InterruptedException e) {
             e.printStackTrace();
         }
     }    
-}
\ No newline at end of file
+}
diff --git a/src/fr/monlouyan/bakefile/DependencyResolver.java b/src/fr/monlouyan/bakefile/DependencyResolver.java
index 133d492..8ca21fc 100644
--- a/src/fr/monlouyan/bakefile/DependencyResolver.java
+++ b/src/fr/monlouyan/bakefile/DependencyResolver.java
@@ -10,16 +10,17 @@ public class DependencyResolver {
         this.debug = debug;
     }
 
-    public List<Target> resolve(List<Target> allTargets, List<String> requestedTargets) {
-        List<Target> targetsToBuild = new ArrayList<>();
-        for (Target target : allTargets) {
-            if (requestedTargets.isEmpty() || requestedTargets.contains(target.getName())) {
+    public List<Rule> resolve(List<Rule> allRules, List<String> requestedRules) {
+        List<Rule> rulesToBuild = new ArrayList<>();
+        
+        for (Rule rule : allRules) {
+            if (requestedRules.isEmpty() || requestedRules.contains(rule.getName()) || rule.isPhony()) {
                 if (debug){
-                    System.out.println("Target " + target.getName() + " is requested");
+                    System.out.println("Rule " + rule.getName() + " is requested");
                 }
-                targetsToBuild.add(target);
+                rulesToBuild.add(rule);
             }
         }
-        return targetsToBuild;
+        return rulesToBuild;
     }
 }
\ No newline at end of file
diff --git a/src/fr/monlouyan/bakefile/Rule.java b/src/fr/monlouyan/bakefile/Rule.java
new file mode 100644
index 0000000..c15ab74
--- /dev/null
+++ b/src/fr/monlouyan/bakefile/Rule.java
@@ -0,0 +1,116 @@
+package fr.monlouyan.bakefile;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Représente une règle dans un fichier Bakefile
+ * Dernière modification : 04/02/2025
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI
+ * @version 1.0
+ * @date 04/02/2025
+ */
+public class Rule {
+    /**
+     * Nom de la règle
+     */
+    private String name;
+
+    /**
+     * Liste des dépendances de la règle
+     */
+    private List<String> dependencies;
+
+    /**
+     * Liste des commandes de la règle (actions à exécuter)
+     */
+    private List<String> commands;
+
+    /**
+     * Indique si la règle est une règle phony
+     */
+    private boolean isPhony;
+
+    /**
+     * Constructeur de la classe Rule
+     * @param name Nom de la règle
+     * @param dependencies Liste des dépendances de la règle
+     * @param commands Liste des commandes de la règle à exécuter
+     * @param isPhony Si la règle est une règle phony ou non
+     */
+    public Rule(String name, List<String> dependencies, List<String> commands, boolean isPhony) {
+        this.name = name;
+        this.dependencies = dependencies;
+        this.commands = commands;
+        this.isPhony = isPhony;
+    }
+
+    /**
+     * Permet de récupérer le nom de la règle
+     * @return Le nom de la règle
+     */
+    public String getName() { return name; }
+
+    /**
+     * Permet de récupérer les dépendances de la règle
+     * @return La liste des dépendances de la règle
+     */
+    public List<String> getDependencies() { return dependencies; }
+
+    /**
+     * Permet de récupérer les commandes de la règle
+     * @return La liste des commandes de la règle
+     */
+    public List<String> getCommands() { return commands; }
+
+    /**
+     * Permet de savoir si la règle est une règle phony
+     * @return true si la règle est une règle phony, false sinon
+     */
+    public boolean isPhony() { return isPhony; }
+
+    /**
+     * Permet de savoir si la règle est vide (sans dépendances ni commandes)
+     * @return true si la règle est vide, false sinon
+     */
+    public boolean isEmpty() { return dependencies.isEmpty() && commands.isEmpty(); }
+
+    /**
+     * Détermine si la règle doit être mise à jour.
+     * Une règle doit être mise à jour si l'un de ses fichiers de sortie est plus ancien qu'un de ses fichiers de dépendance.
+     * De plus, les règles phony sont toujours mises à jour.
+     * 
+     * @return true si la règle doit être mise à jour, false sinon.
+     */
+    public boolean needsUpdate() {
+        if (BakeCLI.isDebug()){
+            System.out.println("Debug : Checking if rule " + name + " needs update");
+        }
+
+        if (isPhony) {
+            if (BakeCLI.isDebug()) {
+                System.out.println("Debug : Rule " + name + " is phony, always needs update");
+            }
+            return true; // Les règles phony sont toujours mises à jour
+        }
+    
+        File targetFile = new File(name);
+
+        if (BakeCLI.isDebug()){
+            System.out.println("Debug : Checking if target file " + name + " exist and is up to date");
+        }
+        long targetTimestamp = targetFile.exists() ? TimestampManager.getTimestamp(targetFile) : 0;
+    
+        for (String dependency : dependencies) {
+            File depFile = new File(dependency);
+            if (depFile.exists() && TimestampManager.getTimestamp(depFile) > targetTimestamp) {
+                if (BakeCLI.isDebug()) {
+                    System.out.println("Debug : Dependency " + dependency + " is newer than target file " + name + ", needs update");
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/fr/monlouyan/bakefile/Target.java b/src/fr/monlouyan/bakefile/Target.java
deleted file mode 100644
index 29b32ca..0000000
--- a/src/fr/monlouyan/bakefile/Target.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package fr.monlouyan.bakefile;
-
-import java.io.File;
-import java.util.List;
-
-public class Target {
-    private String name;
-    private List<String> dependencies;
-    private String command;
-    
-    public Target(String name, List<String> dependencies, String command) {
-        this.name = name;
-        this.dependencies = dependencies;
-        this.command = command;
-    }
-    
-    public boolean needsUpdate() {
-        File targetFile = new File(name);
-        if (!targetFile.exists()) return true;
-        long lastModified = targetFile.lastModified();
-        for (String dep : dependencies) {
-            File depFile = new File(dep);
-            if (depFile.exists() && depFile.lastModified() > lastModified) return true;
-        }
-        return false;
-    }
-    
-    public String getCommand() { return command; }
-    public String getName() { return name; }
-}
\ No newline at end of file
diff --git a/src/fr/monlouyan/bakefile/TimestampManager.java b/src/fr/monlouyan/bakefile/TimestampManager.java
new file mode 100644
index 0000000..fc37bda
--- /dev/null
+++ b/src/fr/monlouyan/bakefile/TimestampManager.java
@@ -0,0 +1,39 @@
+package fr.monlouyan.bakefile;
+
+import java.io.File;
+
+/**
+ * Classe utilitaire pour la gestion des timestamps des fichiers.
+ * Dernière modification : 04/02/2025
+ * 
+ * @author Moncef STITI, Yanis HAMOUDI
+ * @version 1.0
+ * @date 04/02/2025
+ */
+public class TimestampManager {
+
+    /**
+     * Récupère le timestamp d'un fichier.
+     * @param filePath Le chemin du fichier.
+     * @return Le timestamp du fichier, ou 0 si le fichier n'existe pas.
+     */
+    public static long getTimestamp(File file) {
+        if (file.exists()) {
+            return file.lastModified(); // Récupère le timestamp du fichier
+        }
+        return 0; // Le fichier n'existe pas
+    }
+    
+    /**
+     * Compare deux fichiers en fonction de leurs timestamps de modification.
+     * 
+     * @param file1 Premier fichier
+     * @param file2 Deuxième fichier
+     * @return 1 si file1 est plus récent, -1 si file2 est plus récent, 0 s'ils ont le même timestamp
+     */
+    public static int compareTimestamps(File file1, File file2) {
+        long time1 = getTimestamp(file1);
+        long time2 = getTimestamp(file2);
+        return Long.compare(time1, time2);
+    }
+}
diff --git a/tests/bakefile.jar b/tests/bakefile.jar
new file mode 100644
index 0000000..a268f9a
Binary files /dev/null and b/tests/bakefile.jar differ
diff --git a/tests/test-01-depuis-rien/bakefile.jar b/tests/test-01-depuis-rien/bakefile.jar
new file mode 100644
index 0000000..a268f9a
Binary files /dev/null and b/tests/test-01-depuis-rien/bakefile.jar differ
diff --git a/tests/test-02-existe-deja/bakefile.jar b/tests/test-02-existe-deja/bakefile.jar
new file mode 100644
index 0000000..a268f9a
Binary files /dev/null and b/tests/test-02-existe-deja/bakefile.jar differ
diff --git a/tests/test-03-circulaire/Bakefile b/tests/test-03-circulaire/Bakefile
index 369b433..b458a3d 100644
--- a/tests/test-03-circulaire/Bakefile
+++ b/tests/test-03-circulaire/Bakefile
@@ -1,14 +1,11 @@
-main: a.o b.o c.o
-	gcc a.o b.o c.o -o main
+main: a b c
+	gcc a b c -o main
 
-a.o: a.c a.h b.h
-	gcc -Wall -Werror -Wextra -c a.c -o a.o
+a: a.c a.h b.h
+	gcc -Wall -Werror -Wextra -Pendatic -c a.c -o a
 
-b.o: b.c b.h c.h
-	gcc -Wall -Werror -Wextra -c b.c -o b.o
+b: b.c b.h c.h
+	gcc -Wall -Werror -Wextra -Pendatic -c b.c -o b
 
-c.o: c.c c.h a.h
-	gcc -Wall -Werror -Wextra -c c.c -o c.o
-
-clean:
-	rm -f a.o b.o c.o main
+c: c.c c.h a.h
+	gcc -Wall -Werror -Wextra -Pendatic -c c.c -o c
diff --git a/tests/test-03-circulaire/bakefile.jar b/tests/test-03-circulaire/bakefile.jar
new file mode 100644
index 0000000..a268f9a
Binary files /dev/null and b/tests/test-03-circulaire/bakefile.jar differ