fbt: source collection improvements (#3181)
* fbt: reduced amount of redundant compilation units * fbt: added GatherSources() method which can reject source paths starting with "!" in sources list; optimized apps' source lists * docs: updated on path exclusion for `sources` * apps: examples: fixed example_advanced_plugins source list * docs: more details on `sources`; apps: narrower sources lists
This commit is contained in:
		
							parent
							
								
									bf8984a225
								
							
						
					
					
						commit
						7bd3bd7ea4
					
				@ -5,6 +5,7 @@ App(
 | 
				
			|||||||
    entry_point="example_plugins_app",
 | 
					    entry_point="example_plugins_app",
 | 
				
			||||||
    stack_size=2 * 1024,
 | 
					    stack_size=2 * 1024,
 | 
				
			||||||
    fap_category="Examples",
 | 
					    fap_category="Examples",
 | 
				
			||||||
 | 
					    sources=["*.c", "!plugin*.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -21,6 +22,7 @@ App(
 | 
				
			|||||||
    apptype=FlipperAppType.PLUGIN,
 | 
					    apptype=FlipperAppType.PLUGIN,
 | 
				
			||||||
    entry_point="example_plugin1_ep",
 | 
					    entry_point="example_plugin1_ep",
 | 
				
			||||||
    requires=["example_plugins", "example_plugins_multi"],
 | 
					    requires=["example_plugins", "example_plugins_multi"],
 | 
				
			||||||
 | 
					    sources=["plugin1.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -28,4 +30,5 @@ App(
 | 
				
			|||||||
    apptype=FlipperAppType.PLUGIN,
 | 
					    apptype=FlipperAppType.PLUGIN,
 | 
				
			||||||
    entry_point="example_plugin2_ep",
 | 
					    entry_point="example_plugin2_ep",
 | 
				
			||||||
    requires=["example_plugins_multi"],
 | 
					    requires=["example_plugins_multi"],
 | 
				
			||||||
 | 
					    sources=["plugin2.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ App(
 | 
				
			|||||||
    entry_point="example_advanced_plugins_app",
 | 
					    entry_point="example_advanced_plugins_app",
 | 
				
			||||||
    stack_size=2 * 1024,
 | 
					    stack_size=2 * 1024,
 | 
				
			||||||
    fap_category="Examples",
 | 
					    fap_category="Examples",
 | 
				
			||||||
 | 
					    sources=["*.c*", "!plugin*.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
 | 
				
			|||||||
@ -17,5 +17,6 @@ App(
 | 
				
			|||||||
    apptype=FlipperAppType.STARTUP,
 | 
					    apptype=FlipperAppType.STARTUP,
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    entry_point="ibutton_on_system_start",
 | 
					    entry_point="ibutton_on_system_start",
 | 
				
			||||||
 | 
					    sources=["ibutton_cli.c"],
 | 
				
			||||||
    order=60,
 | 
					    order=60,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@ App(
 | 
				
			|||||||
    icon="A_Infrared_14",
 | 
					    icon="A_Infrared_14",
 | 
				
			||||||
    stack_size=3 * 1024,
 | 
					    stack_size=3 * 1024,
 | 
				
			||||||
    order=40,
 | 
					    order=40,
 | 
				
			||||||
 | 
					    sources=["*.c", "!infrared_cli.c"],
 | 
				
			||||||
    resources="resources",
 | 
					    resources="resources",
 | 
				
			||||||
    fap_libs=["assets"],
 | 
					    fap_libs=["assets"],
 | 
				
			||||||
    fap_icon="icon.png",
 | 
					    fap_icon="icon.png",
 | 
				
			||||||
@ -18,5 +19,10 @@ App(
 | 
				
			|||||||
    apptype=FlipperAppType.STARTUP,
 | 
					    apptype=FlipperAppType.STARTUP,
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    entry_point="infrared_on_system_start",
 | 
					    entry_point="infrared_on_system_start",
 | 
				
			||||||
 | 
					    sources=[
 | 
				
			||||||
 | 
					        "infrared_cli.c",
 | 
				
			||||||
 | 
					        "infrared_brute_force.c",
 | 
				
			||||||
 | 
					        "infrared_signal.c",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    order=20,
 | 
					    order=20,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -17,5 +17,6 @@ App(
 | 
				
			|||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    apptype=FlipperAppType.STARTUP,
 | 
					    apptype=FlipperAppType.STARTUP,
 | 
				
			||||||
    entry_point="lfrfid_on_system_start",
 | 
					    entry_point="lfrfid_on_system_start",
 | 
				
			||||||
 | 
					    sources=["lfrfid_cli.c"],
 | 
				
			||||||
    order=50,
 | 
					    order=50,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,11 @@ App(
 | 
				
			|||||||
    stack_size=5 * 1024,
 | 
					    stack_size=5 * 1024,
 | 
				
			||||||
    order=30,
 | 
					    order=30,
 | 
				
			||||||
    resources="resources",
 | 
					    resources="resources",
 | 
				
			||||||
 | 
					    sources=[
 | 
				
			||||||
 | 
					        "*.c",
 | 
				
			||||||
 | 
					        "!plugins",
 | 
				
			||||||
 | 
					        "!nfc_cli.c",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    fap_libs=["assets"],
 | 
					    fap_libs=["assets"],
 | 
				
			||||||
    fap_icon="icon.png",
 | 
					    fap_icon="icon.png",
 | 
				
			||||||
    fap_category="NFC",
 | 
					    fap_category="NFC",
 | 
				
			||||||
@ -21,6 +26,7 @@ App(
 | 
				
			|||||||
    entry_point="all_in_one_plugin_ep",
 | 
					    entry_point="all_in_one_plugin_ep",
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    requires=["nfc"],
 | 
					    requires=["nfc"],
 | 
				
			||||||
 | 
					    sources=["plugins/supported_cards/all_in_one.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -29,6 +35,7 @@ App(
 | 
				
			|||||||
    entry_point="opal_plugin_ep",
 | 
					    entry_point="opal_plugin_ep",
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    requires=["nfc"],
 | 
					    requires=["nfc"],
 | 
				
			||||||
 | 
					    sources=["plugins/supported_cards/opal.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -37,6 +44,7 @@ App(
 | 
				
			|||||||
    entry_point="myki_plugin_ep",
 | 
					    entry_point="myki_plugin_ep",
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    requires=["nfc"],
 | 
					    requires=["nfc"],
 | 
				
			||||||
 | 
					    sources=["plugins/supported_cards/myki.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -45,6 +53,7 @@ App(
 | 
				
			|||||||
    entry_point="troika_plugin_ep",
 | 
					    entry_point="troika_plugin_ep",
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    requires=["nfc"],
 | 
					    requires=["nfc"],
 | 
				
			||||||
 | 
					    sources=["plugins/supported_cards/troika.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -53,6 +62,7 @@ App(
 | 
				
			|||||||
    entry_point="plantain_plugin_ep",
 | 
					    entry_point="plantain_plugin_ep",
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    requires=["nfc"],
 | 
					    requires=["nfc"],
 | 
				
			||||||
 | 
					    sources=["plugins/supported_cards/plantain.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -61,6 +71,7 @@ App(
 | 
				
			|||||||
    entry_point="two_cities_plugin_ep",
 | 
					    entry_point="two_cities_plugin_ep",
 | 
				
			||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    requires=["nfc"],
 | 
					    requires=["nfc"],
 | 
				
			||||||
 | 
					    sources=["plugins/supported_cards/two_cities.c"],
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
App(
 | 
					App(
 | 
				
			||||||
@ -68,5 +79,6 @@ App(
 | 
				
			|||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    apptype=FlipperAppType.STARTUP,
 | 
					    apptype=FlipperAppType.STARTUP,
 | 
				
			||||||
    entry_point="nfc_on_system_start",
 | 
					    entry_point="nfc_on_system_start",
 | 
				
			||||||
 | 
					    sources=["nfc_cli.c"],
 | 
				
			||||||
    order=30,
 | 
					    order=30,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,11 @@ App(
 | 
				
			|||||||
    icon="A_Sub1ghz_14",
 | 
					    icon="A_Sub1ghz_14",
 | 
				
			||||||
    stack_size=3 * 1024,
 | 
					    stack_size=3 * 1024,
 | 
				
			||||||
    order=10,
 | 
					    order=10,
 | 
				
			||||||
 | 
					    sources=[
 | 
				
			||||||
 | 
					        "*.c",
 | 
				
			||||||
 | 
					        "!subghz_cli.c",
 | 
				
			||||||
 | 
					        "!helpers/subghz_chat.c",
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    resources="resources",
 | 
					    resources="resources",
 | 
				
			||||||
    fap_libs=["assets", "hwdrivers"],
 | 
					    fap_libs=["assets", "hwdrivers"],
 | 
				
			||||||
    fap_icon="icon.png",
 | 
					    fap_icon="icon.png",
 | 
				
			||||||
@ -18,5 +23,6 @@ App(
 | 
				
			|||||||
    targets=["f7"],
 | 
					    targets=["f7"],
 | 
				
			||||||
    apptype=FlipperAppType.STARTUP,
 | 
					    apptype=FlipperAppType.STARTUP,
 | 
				
			||||||
    entry_point="subghz_on_system_start",
 | 
					    entry_point="subghz_on_system_start",
 | 
				
			||||||
 | 
					    sources=["subghz_cli.c", "helpers/subghz_chat.c"],
 | 
				
			||||||
    order=40,
 | 
					    order=40,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -47,7 +47,7 @@ Only two parameters are mandatory: **_appid_** and **_apptype_**. Others are opt
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
The following parameters are used only for [FAPs](./AppsOnSDCard.md):
 | 
					The following parameters are used only for [FAPs](./AppsOnSDCard.md):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **sources**: list of strings, file name masks used for gathering sources within the app folder. The default value of `["*.c*"]` includes C and C++ source files. Applications cannot use the `"lib"` folder for their own source code, as it is reserved for **fap_private_libs**.
 | 
					- **sources**: list of strings, file name masks used for gathering sources within the app folder. The default value of `["*.c*"]` includes C and C++ source files. Applications cannot use the `"lib"` folder for their own source code, as it is reserved for **fap_private_libs**. Paths starting with `"!"` are excluded from the list of sources. They can also include wildcard characters and directory names. For example, a value of `["*.c*", "!plugins"]` will include all C and C++ source files in the app folder except those in the `plugins` (and `lib`) folders. Paths with no wildcards (`*, ?`) are treated as full literal paths for both inclusion and exclusion.
 | 
				
			||||||
- **fap_version**: string, application version. The default value is "0.1". You can also use a tuple of 2 numbers in the form of (x,y) to specify the version. It is also possible to add more dot-separated parts to the version, like patch number, but only major and minor version numbers are stored in the built .fap.
 | 
					- **fap_version**: string, application version. The default value is "0.1". You can also use a tuple of 2 numbers in the form of (x,y) to specify the version. It is also possible to add more dot-separated parts to the version, like patch number, but only major and minor version numbers are stored in the built .fap.
 | 
				
			||||||
- **fap_icon**: name of a `.png` file, 1-bit color depth, 10x10px, to be embedded within `.fap` file.
 | 
					- **fap_icon**: name of a `.png` file, 1-bit color depth, 10x10px, to be embedded within `.fap` file.
 | 
				
			||||||
- **fap_libs**: list of extra libraries to link the application against. Provides access to extra functions that are not exported as a part of main firmware at the expense of increased `.fap` file size and RAM consumption.
 | 
					- **fap_libs**: list of extra libraries to link the application against. Provides access to extra functions that are not exported as a part of main firmware at the expense of increased `.fap` file size and RAM consumption.
 | 
				
			||||||
 | 
				
			|||||||
@ -197,7 +197,7 @@ sources = [apps_c]
 | 
				
			|||||||
# Gather sources only from app folders in current configuration
 | 
					# Gather sources only from app folders in current configuration
 | 
				
			||||||
sources.extend(
 | 
					sources.extend(
 | 
				
			||||||
    itertools.chain.from_iterable(
 | 
					    itertools.chain.from_iterable(
 | 
				
			||||||
        fwenv.GlobRecursive(source_type, appdir.relpath, exclude=["lib"])
 | 
					        fwenv.GatherSources([source_type, "!lib"], appdir.relpath)
 | 
				
			||||||
        for appdir, source_type in fwenv["APPBUILD"].get_builtin_app_folders()
 | 
					        for appdir, source_type in fwenv["APPBUILD"].get_builtin_app_folders()
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -147,16 +147,10 @@ class AppBuilder:
 | 
				
			|||||||
            CPPPATH=[self.app_work_dir, self.app._appdir],
 | 
					            CPPPATH=[self.app_work_dir, self.app._appdir],
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        app_sources = list(
 | 
					        app_sources = self.app_env.GatherSources(
 | 
				
			||||||
            itertools.chain.from_iterable(
 | 
					            [self.app.sources, "!lib"], self.app_work_dir
 | 
				
			||||||
                self.app_env.GlobRecursive(
 | 
					 | 
				
			||||||
                    source_type,
 | 
					 | 
				
			||||||
                    self.app_work_dir,
 | 
					 | 
				
			||||||
                    exclude="lib",
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                for source_type in self.app.sources
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not app_sources:
 | 
					        if not app_sources:
 | 
				
			||||||
            raise UserError(f"No source files found for {self.app.appid}")
 | 
					            raise UserError(f"No source files found for {self.app.appid}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
 | 
					import itertools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import SCons
 | 
					import SCons
 | 
				
			||||||
from fbt.util import GLOB_FILE_EXCLUSION
 | 
					from fbt.util import GLOB_FILE_EXCLUSION
 | 
				
			||||||
from SCons.Script import Flatten
 | 
					 | 
				
			||||||
from SCons.Node.FS import has_glob_magic
 | 
					from SCons.Node.FS import has_glob_magic
 | 
				
			||||||
 | 
					from SCons.Script import Flatten
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def GlobRecursive(env, pattern, node=".", exclude=[]):
 | 
					def GlobRecursive(env, pattern, node=".", exclude=[]):
 | 
				
			||||||
@ -23,12 +25,35 @@ def GlobRecursive(env, pattern, node=".", exclude=[]):
 | 
				
			|||||||
    # Otherwise, just assume that file at path exists
 | 
					    # Otherwise, just assume that file at path exists
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        results.append(node.File(pattern))
 | 
					        results.append(node.File(pattern))
 | 
				
			||||||
 | 
					    ## Debug
 | 
				
			||||||
    # print(f"Glob result for {pattern} from {node}: {results}")
 | 
					    # print(f"Glob result for {pattern} from {node}: {results}")
 | 
				
			||||||
    return results
 | 
					    return results
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def GatherSources(env, sources_list, node="."):
 | 
				
			||||||
 | 
					    sources_list = list(set(Flatten(sources_list)))
 | 
				
			||||||
 | 
					    include_sources = list(filter(lambda x: not x.startswith("!"), sources_list))
 | 
				
			||||||
 | 
					    exclude_sources = list(x[1:] for x in sources_list if x.startswith("!"))
 | 
				
			||||||
 | 
					    gathered_sources = list(
 | 
				
			||||||
 | 
					        itertools.chain.from_iterable(
 | 
				
			||||||
 | 
					            env.GlobRecursive(
 | 
				
			||||||
 | 
					                source_type,
 | 
				
			||||||
 | 
					                node,
 | 
				
			||||||
 | 
					                exclude=exclude_sources,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            for source_type in include_sources
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    ## Debug
 | 
				
			||||||
 | 
					    # print(
 | 
				
			||||||
 | 
					    #     f"Gathered sources for {sources_list} from {node}: {list(f.path for f in gathered_sources)}"
 | 
				
			||||||
 | 
					    # )
 | 
				
			||||||
 | 
					    return gathered_sources
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate(env):
 | 
					def generate(env):
 | 
				
			||||||
    env.AddMethod(GlobRecursive)
 | 
					    env.AddMethod(GlobRecursive)
 | 
				
			||||||
 | 
					    env.AddMethod(GatherSources)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def exists(env):
 | 
					def exists(env):
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user