diff --git a/CI/build/arduino-cli.py b/CI/build/arduino-cli.py
index 039da29e0b..f6307d5c99 100644
--- a/CI/build/arduino-cli.py
+++ b/CI/build/arduino-cli.py
@@ -38,7 +38,7 @@
 bin_dir = "binaries"
 
 # Default
-sketch_default = os.path.join(script_path, "examples", "BareMinimum", "BareMinimum.ino")
+sketch_default = os.path.join(script_path, "examples", "BareMinimum")
 exclude_file_default = os.path.join("conf", "exclude_list.txt")
 cores_config_file_default = os.path.join("conf", "cores_config.json")
 cores_config_file_ci = os.path.join("conf", "cores_config_ci.json")
@@ -351,11 +351,20 @@ def manage_inos():
     # Only one sketch
     elif args.ino:
         if os.path.exists(args.ino):
-            sketch_list.append(args.ino)
+            # Store only the path
+            if os.path.isfile(args.ino):
+                sketch_list.append(os.path.dirname(args.ino))
+            else:
+                sketch_list.append(args.ino)
         else:
             for path in sketches_path_list:
-                if os.path.exists(os.path.join(path, args.ino)):
-                    sketch_list.append(os.path.join(path, args.ino))
+                fp = os.path.join(path, args.ino)
+                if os.path.exists(fp):
+                    # Store only the path
+                    if os.path.isfile(fp):
+                        sketch_list.append(os.path.dirname(fp))
+                    else:
+                        sketch_list.append(fp)
                     break
             else:
                 print("Sketch {} path does not exist!".format(args.ino))
@@ -368,11 +377,20 @@ def manage_inos():
                 if line.rstrip():
                     ino = line.rstrip()
                     if os.path.exists(ino):
-                        sketch_list.append(ino)
+                        # Store only the path
+                        if os.path.isfile(ino):
+                            sketch_list.append(os.path.dirname(ino))
+                        else:
+                            sketch_list.append(ino)
                     else:
                         for path in sketches_path_list:
-                            if os.path.exists(os.path.join(path, ino)):
-                                sketch_list.append(os.path.join(path, ino))
+                            fp = os.path.join(path, ino)
+                            if os.path.exists(fp):
+                                # Store only the path
+                                if os.path.isfile(fp):
+                                    sketch_list.append(os.path.dirname(fp))
+                                else:
+                                    sketch_list.append(fp)
                                 break
                         else:
                             print("Ignore {} as it does not exist.".format(ino))
@@ -384,17 +402,10 @@ def manage_inos():
         quit()
 
 
-# Find all .ino files
+# Find all .ino files and save directory
 def find_inos():
-    # Path list order is important to avoid duplicated sketch name.
-    # Last one found will be kept.
-    # So sketches_path_list must take this in account, the last path
-    # should be the one with higher priority.
-
+    global sketch_list
     # key: path, value: name
-    ordered_path = collections.OrderedDict()
-    # key: name, value: path
-    ordered_name = collections.OrderedDict()
     if args.sketches:
         arg_sketch_pattern = re.compile(args.sketches, re.IGNORECASE)
     for path in sketches_path_list:
@@ -404,23 +415,8 @@ def find_inos():
                     if args.sketches:
                         if arg_sketch_pattern.search(os.path.join(root, file)) is None:
                             continue
-                    if root in ordered_path:
-                        # If several sketch are in the same path
-                        # Check which one to kept
-                        # Commonly, example structure is:
-                        # dirname/dirname.ino
-                        if (
-                            os.path.basename(root)
-                            == os.path.splitext(ordered_path[root])[0]
-                        ):
-                            continue
-                    ordered_path[root] = file
-    # Remove duplicated sketch name
-    for path, name in ordered_path.items():
-        ordered_name[name] = path
-    for name, path in ordered_name.items():
-        sketch_list.append(os.path.join(path, name))
-    sketch_list.sort()
+                    sketch_list.append(root)
+    sketch_list = sorted(set(sketch_list))
 
 
 # Return a list of all board using the arduino-cli for the specified architecture
@@ -871,7 +867,7 @@ def build(build_conf):
 
 g1 = parser.add_mutually_exclusive_group()
 g1.add_argument("--bin", help="save binaries", action="store_true")
-g1.add_argument("--ci", help="Custom configuration for CI build", action="store_true")
+g1.add_argument("--ci", help="custom configuration for CI build", action="store_true")
 
 # Sketch options
 sketchg0 = parser.add_argument_group(
@@ -880,7 +876,7 @@ def build(build_conf):
 
 sketchg1 = sketchg0.add_mutually_exclusive_group()
 sketchg1.add_argument(
-    "-i", "--ino", metavar="<shetch filepath>", help="single ino file to build"
+    "-i", "--ino", metavar="<shetch filepath>", help="single sketch file to build"
 )
 sketchg1.add_argument(
     "-f",
@@ -898,7 +894,7 @@ def build(build_conf):
     "-e",
     "--exclude",
     metavar="<excluded sketches list filepath>",
-    help="file containing pattern of sketches to ignore.\
+    help="file containing sketches pattern to ignore.\
     Default path : "
     + os.path.join(script_path, exclude_file_default),
 )
diff --git a/CI/build/conf/cores_config.json b/CI/build/conf/cores_config.json
index 8e152b82eb..1b3bab337b 100644
--- a/CI/build/conf/cores_config.json
+++ b/CI/build/conf/cores_config.json
@@ -23,7 +23,7 @@
       ],
       "sketches": [
         {
-          "pattern": "^((?!BareMinimum.ino).)*$",
+          "pattern": "^((?!BareMinimum).)*$",
           "applicable": false,
           "boards": [ "DEMO_F030F4", "DEMO_F030F4_16M", "DEMO_F030F4_HSI", "RHF76_052" ]
         },
@@ -33,22 +33,22 @@
           "boards": [ "DISCO_L475VG_IOT" ]
         },
         {
-          "pattern": "SPBTLE_BeaconDemo.ino|SPBTLE_SensorDemo.ino|BTLE_sensors_TimeOfFlight_demo.ino",
+          "pattern": "SPBTLE_BeaconDemo|SPBTLE_SensorDemo|BTLE_sensors_TimeOfFlight_demo",
           "applicable": true,
           "boards": [ "DISCO_L475VG_IOT" ]
         },
         {
-          "pattern": "STM32Ethernet|Ethernet_MQTT_Adafruit.io.ino|Hello_stm32",
+          "pattern": "STM32Ethernet|Ethernet_MQTT_Adafruit.io|Hello_stm32",
           "applicable": true,
           "boards": [ "NUCLEO_F429ZI", "DISCO_F746NG" ]
         },
         {
-          "pattern": "ISM43362-M3G-L44|WiFi_MQTT_Adafruit.io.ino|mqtt_B-L475E-IOT01A.ino",
+          "pattern": "ISM43362-M3G-L44|WiFi_MQTT_Adafruit.io|mqtt_B-L475E-IOT01A",
           "applicable": true,
           "boards": [ "DISCO_L475VG_IOT" ]
         },
         {
-          "pattern": "ExternalWakeup.ino|BleSensors_SensiBLE|NucleoCar",
+          "pattern": "ExternalWakeup|BleSensors_SensiBLE|NucleoCar",
           "applicable": false,
           "boards": [
             "AFROFLIGHT_F103CB",
@@ -110,7 +110,7 @@
           ]
         },
         {
-          "pattern": "Blink(WithoutDelay)?.ino",
+          "pattern": "Blink(WithoutDelay)?",
           "applicable": false,
           "boards": [ "EEXTR_F030_V1", "MALYANM200_F103CB", "PRNTR_V2" ]
         },
@@ -148,7 +148,7 @@
           "options": "usb=HID"
         },
         {
-          "pattern": "X_NUCLEO_IDB05A1_HelloWorld.ino",
+          "pattern": "X_NUCLEO_IDB05A1_HelloWorld",
           "applicable": false,
           "boards": [
             "AFROFLIGHT_F103CB",
@@ -184,7 +184,7 @@
           ]
         },
         {
-          "pattern": "X_NUCLEO_NFC03A1_HelloWorld.ino",
+          "pattern": "X_NUCLEO_NFC03A1_HelloWorld",
           "applicable": false,
           "boards": [
             "DISCO_F030R8",
@@ -215,7 +215,7 @@
           ]
         },
         {
-          "pattern": "StringComparisonOperators.ino",
+          "pattern": "StringComparisonOperators",
           "applicable": false,
           "boards": [
             "ARMED_V1",
@@ -229,7 +229,7 @@
           ]
         },
         {
-          "pattern": "ADXL3xx.ino",
+          "pattern": "ADXL3xx",
           "applicable": false,
           "boards": [
             "ARMED_V1",
@@ -240,7 +240,7 @@
           ]
         },
         {
-          "pattern": "SerialLoop.ino|Tests_basic_functions.ino",
+          "pattern": "SerialLoop|Tests_basic_functions",
           "applicable": false,
           "boards": [ "BLUEPILL_F103C6", "NUCLEO_L031K6", "Wraith32_V1" ]
         },
diff --git a/platform.txt b/platform.txt
index 25dc8544dd..3674dfe7d2 100644
--- a/platform.txt
+++ b/platform.txt
@@ -133,16 +133,14 @@ recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.f
 ## Create output (.bin file)
 recipe.objcopy.bin.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"
 
-## Save bin
-recipe.output.tmp_file={build.project_name}.bin
-recipe.output.save_file={build.project_name}.{build.variant}.bin
-
 ## Create output (.hex file)
 recipe.objcopy.hex.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
 
-## Save hex
-recipe.output.tmp_file={build.project_name}.hex
-recipe.output.save_file={build.project_name}.{build.variant}.hex
+build.preferred_out_format=bin
+
+## Save binary
+recipe.output.tmp_file={build.project_name}.{build.preferred_out_format}
+recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_out_format}
 
 ## Compute size
 recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"