diff --git a/redo/rules/build_executable.py b/redo/rules/build_executable.py index 7061f33..b8e2bad 100644 --- a/redo/rules/build_executable.py +++ b/redo/rules/build_executable.py @@ -207,7 +207,7 @@ def _build(self, redo_1, redo_2, redo_3): source_dir = os.path.dirname(source_to_compile) # Find any C objects that need to be linked against so that we can - # tell GPRbuild to link with them. + # tell gprbuild to link with them. with c_source_database() as db: c_objects = db.get_all_objects(build_target) existing_c_objects = [ofile for ofile in c_objects if os.path.isfile(ofile)] @@ -215,6 +215,26 @@ def _build(self, redo_1, redo_2, redo_3): set([redo_arg.get_src_dir(obj) for obj in existing_c_objects]) ) + # Gprbuild will try to link to all C/C++ objects that it finds source + # files for in directories in c_source_path. However, we often only want to link + # with some of these files, not all. In order to tell gprbuild to not + # link with everything we need to create a list of files for it to + # exclude. + existing_c_basenames = [os.path.basename(os.path.splitext(ofile)[0]) for ofile in existing_c_objects] + source_extensions = ['.h', '.c', '.cpp', '.hpp', '.s', '.S'] + c_source_exclude = [] + + # Iterate over each directory in the C source path list + for directory in c_source_path: + # Walk the directory and find all files + for root, _, files in os.walk(directory): + for file in files: + # Check if the file has one of the supported extensions + basename, fext = os.path.splitext(file) + if fext in source_extensions and \ + basename not in existing_c_basenames: + c_source_exclude.append(os.path.basename(file)) + # Sym link any c objects into the executable object directory, since # these would not have gotten symlinked like all the ada objects # above. @@ -261,6 +281,8 @@ def _build(self, redo_1, redo_2, redo_3): + " -XSOURCE_DIRS=" + source_dir + (("," + ",".join(c_source_path)) if c_source_path else "") + + " -XEXCLUDED_SOURCE_FILES=" + + ",".join(c_source_exclude) + ((" " + gprbuild_flags.strip()) if gprbuild_flags else "") + direct ) diff --git a/redo/targets/gpr/a_adamant.gpr b/redo/targets/gpr/a_adamant.gpr index cc19d2b..6df6773 100644 --- a/redo/targets/gpr/a_adamant.gpr +++ b/redo/targets/gpr/a_adamant.gpr @@ -4,6 +4,7 @@ abstract project a_adamant is -- Adamant build system and GPRBuild. ADAMANT_DIR := external("ADAMANT_DIR", ""); SOURCE_DIRS := external_as_list("SOURCE_DIRS", ","); + EXCLUDED_SOURCE_FILES := external_as_list("EXCLUDED_SOURCE_FILES", ","); OBJECT_DIR := external("OBJECT_DIR", ""); EXEC_DIR := external("EXEC_DIR", ""); CHECK_STYLE := external("CHECK_STYLE", "False"); diff --git a/redo/targets/gpr/linux_analyze.gpr b/redo/targets/gpr/linux_analyze.gpr index 01c2b68..c860223 100644 --- a/redo/targets/gpr/linux_analyze.gpr +++ b/redo/targets/gpr/linux_analyze.gpr @@ -7,6 +7,7 @@ project linux_analyze extends all "a_linux_debug_base.gpr" is -- to GPRBuild. ----------------------------------------------- for Source_Dirs use a_adamant.SOURCE_DIRS; + for Excluded_Source_Files use a_adamant.EXCLUDED_SOURCE_FILES; for Object_Dir use a_adamant.OBJECT_DIR; for Exec_Dir use a_adamant.EXEC_DIR; diff --git a/redo/targets/gpr/linux_coverage.gpr b/redo/targets/gpr/linux_coverage.gpr index f9b8a07..cf1793e 100644 --- a/redo/targets/gpr/linux_coverage.gpr +++ b/redo/targets/gpr/linux_coverage.gpr @@ -10,6 +10,7 @@ project linux_coverage extends all "a_linux_debug_base.gpr" is -- to GPRBuild. ----------------------------------------------- for Source_Dirs use a_adamant.SOURCE_DIRS; + for Excluded_Source_Files use a_adamant.EXCLUDED_SOURCE_FILES; for Object_Dir use a_adamant.OBJECT_DIR; for Exec_Dir use a_adamant.EXEC_DIR; diff --git a/redo/targets/gpr/linux_debug.gpr b/redo/targets/gpr/linux_debug.gpr index 63fd36c..0f5456e 100644 --- a/redo/targets/gpr/linux_debug.gpr +++ b/redo/targets/gpr/linux_debug.gpr @@ -7,6 +7,7 @@ project linux_debug extends all "a_linux_debug_base.gpr" is -- to GPRBuild. ----------------------------------------------- for Source_Dirs use a_adamant.SOURCE_DIRS; + for Excluded_Source_Files use a_adamant.EXCLUDED_SOURCE_FILES; for Object_Dir use a_adamant.OBJECT_DIR; for Exec_Dir use a_adamant.EXEC_DIR; diff --git a/redo/targets/gpr/linux_test.gpr b/redo/targets/gpr/linux_test.gpr index eaae25b..96c87c6 100644 --- a/redo/targets/gpr/linux_test.gpr +++ b/redo/targets/gpr/linux_test.gpr @@ -10,6 +10,7 @@ project linux_test extends all "a_linux_debug_base.gpr" is -- to GPRBuild. ----------------------------------------------- for Source_Dirs use a_adamant.SOURCE_DIRS; + for Excluded_Source_Files use a_adamant.EXCLUDED_SOURCE_FILES; for Object_Dir use a_adamant.OBJECT_DIR; for Exec_Dir use a_adamant.EXEC_DIR;