ceedling 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/GIT_COMMIT_SHA +1 -1
- data/README.md +11 -9
- data/Rakefile +2 -1
- data/assets/features/ceedling +1 -1
- data/assets/fixtures/test_source_file_duplicate_basenames/test_calc_typo.c +14 -0
- data/assets/fixtures/tests_with_duplicate_test_names/test_foo.c +21 -0
- data/bin/actionator.rb +6 -12
- data/bin/app_cfg.rb +14 -1
- data/bin/ceedling +13 -3
- data/bin/cli.rb +25 -6
- data/bin/cli_handler.rb +113 -73
- data/bin/cli_helper.rb +51 -78
- data/bin/installation_selector.rb +81 -0
- data/bin/launchinator.rb +69 -0
- data/bin/mixin_resolvinator.rb +26 -36
- data/bin/objects.yml +13 -0
- data/bin/path_validator.rb +25 -29
- data/bin/versionator.rb +47 -48
- data/ceedling.gemspec +19 -15
- data/docs/BreakingChanges.md +70 -1
- data/docs/Changelog.md +74 -3
- data/docs/KnownIssues.md +90 -4
- data/docs/ReleaseNotes.md +13 -0
- data/lib/ceedling/build_log_writer.rb +33 -0
- data/lib/ceedling/config/build_root_policy.rb +70 -0
- data/lib/ceedling/config/configurator.rb +14 -16
- data/lib/ceedling/config/configurator_builder.rb +58 -28
- data/lib/ceedling/config/configurator_paths_validator.rb +179 -0
- data/lib/ceedling/config/configurator_plugins.rb +1 -1
- data/lib/ceedling/config/configurator_setup.rb +15 -28
- data/lib/ceedling/config/configurator_validator.rb +1 -110
- data/lib/ceedling/defaults.rb +4 -4
- data/lib/ceedling/dependencies/README.md +18 -16
- data/lib/ceedling/dependencies/dependency_cache_store.rb +20 -3
- data/lib/ceedling/dependencies/dependency_hasher.rb +35 -1
- data/lib/ceedling/filename_extension.rb +7 -1
- data/lib/ceedling/filesystem/FILE_TREE.md +253 -0
- data/lib/ceedling/filesystem/PATH_HANDLING.md +304 -0
- data/lib/ceedling/filesystem/README.md +41 -0
- data/lib/ceedling/filesystem/build_subpath.rb +102 -0
- data/lib/ceedling/filesystem/destination_collision.rb +25 -0
- data/lib/ceedling/{file_finder.rb → filesystem/file_finder.rb} +159 -104
- data/lib/ceedling/{file_finder_helper.rb → filesystem/file_finder_helper.rb} +36 -31
- data/lib/ceedling/filesystem/file_path_collection_utils.rb +183 -0
- data/lib/ceedling/{file_path_utils.rb → filesystem/file_path_utils.rb} +108 -97
- data/lib/ceedling/{file_system_wrapper.rb → filesystem/file_system_wrapper.rb} +6 -5
- data/lib/ceedling/filesystem/file_tree.rb +241 -0
- data/lib/ceedling/{file_wrapper.rb → filesystem/file_wrapper.rb} +45 -38
- data/lib/ceedling/filesystem/path_exclusions.rb +30 -0
- data/lib/ceedling/{path_matcher.rb → filesystem/path_matcher.rb} +27 -23
- data/lib/ceedling/{path_mirror.rb → filesystem/path_mirror.rb} +19 -18
- data/lib/ceedling/filesystem/path_spellings.rb +55 -0
- data/lib/ceedling/filesystem/project_paths.rb +184 -0
- data/lib/ceedling/filesystem/working_dir.rb +40 -0
- data/lib/ceedling/generators/generator.rb +5 -6
- data/lib/ceedling/generators/generator_partials.rb +1 -1
- data/lib/ceedling/generators/generator_test_results_backtrace.rb +7 -7
- data/lib/ceedling/handoff.rb +121 -0
- data/lib/ceedling/includes/include_factory.rb +3 -3
- data/lib/ceedling/includes/include_pathinator.rb +67 -10
- data/lib/ceedling/includes/includes.rb +1 -1
- data/lib/ceedling/installation.rb +92 -0
- data/lib/ceedling/library_resolver.rb +99 -0
- data/lib/ceedling/objects.yml +23 -2
- data/lib/ceedling/partials/partializer.rb +4 -4
- data/lib/ceedling/partials/partializer_config.rb +3 -1
- data/lib/ceedling/plugins/report_log_writer_plugin.rb +3 -5
- data/lib/ceedling/preprocess/preprocessinator_file_assembler.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_includes_handler.rb +1 -1
- data/lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb +1 -1
- data/lib/ceedling/rake_app/rakefile_component_resolver.rb +10 -17
- data/lib/ceedling/rakefile.rb +15 -1
- data/lib/ceedling/rakefiles/base/tasks_base.rake +1 -1
- data/lib/ceedling/rakefiles/release/rules_release.rake +4 -7
- data/lib/ceedling/release_invoker/release_build_executor.rb +33 -44
- data/lib/ceedling/release_invoker/release_build_planner.rb +14 -6
- data/lib/ceedling/reportinator.rb +3 -4
- data/lib/ceedling/setupinator.rb +94 -90
- data/lib/ceedling/test_context_extractor.rb +5 -1
- data/lib/ceedling/test_invoker/PIPELINE.md +9 -7
- data/lib/ceedling/test_invoker/mock_locator.rb +60 -2
- data/lib/ceedling/test_invoker/partials_manager.rb +12 -0
- data/lib/ceedling/test_invoker/standin_headerinator.rb +22 -13
- data/lib/ceedling/test_invoker/test_build_executor.rb +24 -40
- data/lib/ceedling/test_invoker/test_build_planner.rb +37 -18
- data/lib/ceedling/test_invoker/test_build_setup.rb +17 -12
- data/lib/ceedling/test_invoker/test_build_validations.rb +16 -31
- data/lib/ceedling/test_invoker/test_file_preprocessinator.rb +1 -1
- data/lib/ceedling/test_invoker/test_invoker.rb +6 -1
- data/lib/ceedling/test_invoker/test_pipeline_helpers.rb +1 -1
- data/lib/ceedling/test_invoker/test_source_file_directive_resolver.rb +40 -20
- data/lib/ceedling/tool_executor.rb +9 -3
- data/lib/ceedling/yaml_wrapper.rb +3 -2
- data/lib/version.rb +1 -1
- data/plugins/bullseye/config/defaults_bullseye.rb +1 -1
- data/plugins/bullseye/lib/bullseye.rb +9 -7
- data/plugins/cppcheck/config/defaults_cppcheck.rb +1 -1
- data/plugins/dependencies/config/defaults.yml +6 -6
- data/plugins/dependencies/dependencies.rake +4 -1
- data/plugins/dependencies/lib/dependencies.rb +18 -8
- data/plugins/dependencies/lib/dependency_spec.rb +17 -5
- data/plugins/fff/lib/fff.rb +45 -39
- data/plugins/fff/spec/fff_cmock_wrapper_spec.rb +128 -0
- data/plugins/gcov/config/defaults_gcov.rb +1 -1
- data/plugins/gcov/lib/console_reportinator.rb +4 -18
- data/plugins/gcov/lib/gcov.rb +9 -2
- data/plugins/gcov/lib/gcovr_reportinator.rb +8 -40
- data/plugins/gcov/lib/gcovr_thresholds.rb +74 -0
- data/plugins/gcov/lib/reportgenerator_reportinator.rb +1 -1
- data/plugins/module_generator/lib/module_generator.rb +3 -3
- data/plugins/report_tests_teamcity_stdout/lib/report_tests_teamcity_stdout.rb +53 -80
- data/plugins/sanitize/lib/sanitize_records.rb +3 -6
- data/plugins/valgrind/lib/valgrind.rb +14 -7
- data/site-local/configuration/reference/cmock.html +2 -1
- data/site-local/configuration/reference/files.html +9 -3
- data/site-local/configuration/reference/libraries.html +21 -3
- data/site-local/configuration/reference/paths.html +29 -6
- data/site-local/configuration/reference/project.html +17 -7
- data/site-local/configuration/reference/release-build.html +2 -0
- data/site-local/configuration/reference/tools.html +9 -0
- data/site-local/configuration/which-ceedling.html +377 -17
- data/site-local/development/releases.html +5 -1
- data/site-local/development/workflow.html +48 -43
- data/site-local/getting-started/builds.html +2 -0
- data/site-local/getting-started/command-line.html +56 -4
- data/site-local/plugins/dependencies.html +6 -3
- data/site-local/plugins/fff.html +42 -11
- data/site-local/plugins/gcov/gcovr.html +15 -12
- data/site-local/plugins/gcov/setup.html +2 -1
- data/site-local/plugins/report-tests-raw-output-log.html +3 -1
- data/site-local/plugins/report-tests-teamcity-stdout.html +6 -3
- data/site-local/plugins/sanitize.html +7 -6
- data/site-local/plugins/valgrind.html +8 -7
- data/site-local/project/upgrade.html +3 -0
- data/site-local/reference/command-line.html +9 -2
- data/site-local/sitemap.xml.gz +0 -0
- data/site-local/snapshot/plugins/bullseye/config/defaults_bullseye.rb +1 -1
- data/site-local/snapshot/plugins/gcov/config/defaults_gcov.rb +1 -1
- data/site-local/testing-guide/conventions.html +53 -0
- data/spec/integration/actionator_file_operations_spec.rb +91 -1
- data/spec/integration/compile_commands_json_db_spec.rb +1 -1
- data/spec/integration/configurator_validation_spec.rb +1 -1
- data/spec/integration/dependencies/dependency_tracker_cache_hardening_spec.rb +26 -0
- data/spec/integration/dependencies/dependency_tracker_core_spec.rb +22 -0
- data/spec/integration/launcher_handoff_spec.rb +297 -0
- data/spec/integration/mixin_loading_spec.rb +1 -1
- data/spec/integration/module_generator_spec.rb +3 -3
- data/spec/integration/nested_test_artifacts_spec.rb +99 -0
- data/spec/integration/partials_module_resolution_spec.rb +7 -4
- data/spec/integration/path_intake_scenarios_spec.rb +101 -0
- data/spec/integration/path_scenarios_spec.rb +322 -0
- data/spec/integration/quote_include_isolator_spec.rb +1 -1
- data/spec/integration/report_build_warnings_log_spec.rb +1 -1
- data/spec/integration/report_tests_log_factory_spec.rb +1 -1
- data/spec/integration/test_executable_manifest_spec.rb +1 -1
- data/spec/integration/test_includes_extractinator_spec.rb +2 -1
- data/spec/integration/test_naming_spec.rb +198 -0
- data/spec/integration/test_source_file_checks_spec.rb +166 -0
- data/spec/integration/tool_validator_spec.rb +1 -1
- data/spec/integration/upgrade_docs_spec.rb +84 -0
- data/spec/integration/vendor_copy_transient_io_retry_spec.rb +74 -5
- data/spec/support/file_tree_helper.rb +88 -0
- data/spec/support/integration/configurator_integration_helper.rb +6 -6
- data/spec/support/integration/dependency_tracker_integration_helper.rb +1 -1
- data/spec/support/integration/partials_generation_integration_helper.rb +2 -2
- data/spec/support/integration/path_scenario_harness.rb +173 -0
- data/spec/support/integration/spec_integration_helper.rb +1 -1
- data/spec/support/integration/test_includes_harness.rb +13 -2
- data/spec/support/spec_helper.rb +2 -0
- data/spec/support/system/spec_system_helper.rb +7 -6
- data/spec/support/system/system_context.rb +21 -3
- data/spec/support/working_dir_tracking.rb +49 -0
- data/spec/system/build_output_mirroring_spec.rb +2 -2
- data/spec/system/conditional_mock_includes_spec.rb +1 -1
- data/spec/system/delta_builds_spec.rb +137 -11
- data/spec/system/gcov_deployment_spec.rb +1 -0
- data/spec/system/header_include_path_validation_spec.rb +4 -4
- data/spec/system/launcher_handoff_spec.rb +82 -0
- data/spec/system/mock_include_folders_spec.rb +91 -0
- data/spec/system/parent_directory_reference_spec.rb +5 -3
- data/spec/system/path_handling_probes_spec.rb +192 -0
- data/spec/system/preprocessing_parameterized_tests_spec.rb +1 -1
- data/spec/system/rake_release_task_path_disambiguation_spec.rb +6 -6
- data/spec/system/rake_test_task_path_disambiguation_spec.rb +85 -0
- data/spec/system/special_path_characters_spec.rb +86 -0
- data/spec/system/support/common_test_cases.rb +23 -21
- data/spec/system/support/gcov_common_test_cases.rb +37 -9
- data/spec/system/support/sanitize_common_test_cases.rb +2 -2
- data/spec/system/support/valgrind_common_test_cases.rb +12 -12
- data/spec/system/test_pipeline_stop_points_spec.rb +4 -4
- data/spec/system/test_runner_system_include_spec.rb +1 -1
- data/spec/system/test_source_file_directive_spec.rb +34 -5
- data/spec/units/bin/actionator_spec.rb +14 -17
- data/spec/units/bin/app_cfg_spec.rb +37 -0
- data/spec/units/bin/cli_handler_spec.rb +282 -6
- data/spec/units/bin/cli_helper_spec.rb +116 -45
- data/spec/units/bin/installation_selector_spec.rb +114 -0
- data/spec/units/bin/launchinator_spec.rb +171 -0
- data/spec/units/bin/path_validator_spec.rb +10 -0
- data/spec/units/bin/versionator_spec.rb +38 -6
- data/spec/units/build_log_writer_spec.rb +57 -0
- data/spec/units/config/build_root_policy_spec.rb +61 -0
- data/spec/units/config/configurator_builder_spec.rb +37 -6
- data/spec/units/config/configurator_paths_validator_spec.rb +292 -0
- data/spec/units/config/configurator_setup_spec.rb +9 -65
- data/spec/units/config/configurator_spec.rb +27 -5
- data/spec/units/config/configurator_validator_spec.rb +1 -172
- data/spec/units/default_tools_quoting_spec.rb +83 -0
- data/spec/units/dependencies/dependency_cache_store_spec.rb +33 -2
- data/spec/units/dependencies/dependency_debug_tree_spec.rb +1 -1
- data/spec/units/dependencies/dependency_hasher_spec.rb +42 -1
- data/spec/units/dependencies/dependency_path_normalizer_spec.rb +1 -1
- data/spec/units/dependencies/dependency_tracker_spec.rb +3 -1
- data/spec/units/filename_extension_spec.rb +11 -0
- data/spec/units/filesystem/build_subpath_spec.rb +122 -0
- data/spec/units/filesystem/destination_collision_spec.rb +30 -0
- data/spec/units/{file_finder_helper_spec.rb → filesystem/file_finder_helper_spec.rb} +46 -1
- data/spec/units/{file_finder_spec.rb → filesystem/file_finder_spec.rb} +188 -22
- data/spec/units/{file_path_collection_utils_spec.rb → filesystem/file_path_collection_utils_spec.rb} +181 -1
- data/spec/units/{file_path_utils_spec.rb → filesystem/file_path_utils_spec.rb} +204 -87
- data/spec/units/filesystem/file_system_wrapper_spec.rb +33 -0
- data/spec/units/filesystem/file_tree_spec.rb +511 -0
- data/spec/units/filesystem/file_tree_windows_spec.rb +78 -0
- data/spec/units/{file_wrapper_spec.rb → filesystem/file_wrapper_spec.rb} +95 -12
- data/spec/units/{path_matcher_spec.rb → filesystem/path_matcher_spec.rb} +12 -1
- data/spec/units/{path_mirror_spec.rb → filesystem/path_mirror_spec.rb} +32 -4
- data/spec/units/filesystem/project_paths_spec.rb +147 -0
- data/spec/units/filesystem/working_dir_spec.rb +71 -0
- data/spec/units/generators/generator_spec.rb +12 -6
- data/spec/units/generators/generator_test_results_backtrace_spec.rb +50 -46
- data/spec/units/generators/generator_test_results_spec.rb +1 -1
- data/spec/units/handoff_spec.rb +205 -0
- data/spec/units/includes/include_factory_spec.rb +3 -3
- data/spec/units/includes/include_pathinator_spec.rb +46 -0
- data/spec/units/installation_spec.rb +228 -0
- data/spec/units/library_resolver_spec.rb +157 -0
- data/spec/units/mock_locator_spec.rb +76 -1
- data/spec/units/partials/partializer_config_spec.rb +7 -0
- data/spec/units/partials/partializer_spec.rb +1 -0
- data/spec/units/partials_manager_spec.rb +17 -0
- data/spec/units/plugins/bullseye_spec.rb +15 -2
- data/spec/units/plugins/console_reportinator_spec.rb +18 -20
- data/spec/units/plugins/dependencies_spec.rb +33 -7
- data/spec/units/plugins/dependency_spec_spec.rb +17 -0
- data/spec/units/plugins/gcov_spec.rb +28 -3
- data/spec/units/plugins/gcovr_reportinator_spec.rb +19 -47
- data/spec/units/plugins/gcovr_thresholds_spec.rb +95 -0
- data/spec/units/plugins/module_generator_spec.rb +5 -5
- data/spec/units/plugins/report_build_warnings_log_spec.rb +3 -3
- data/spec/units/plugins/report_log_writer_plugin_spec.rb +10 -1
- data/spec/units/plugins/report_tests_raw_output_log_spec.rb +13 -2
- data/spec/units/plugins/report_tests_teamcity_stdout_spec.rb +77 -3
- data/spec/units/plugins/reportgenerator_reportinator_spec.rb +1 -1
- data/spec/units/plugins/sanitize_records_spec.rb +3 -1
- data/spec/units/plugins/sanitize_spec.rb +1 -1
- data/spec/units/plugins/valgrind_spec.rb +23 -8
- data/spec/units/preprocess/preprocessinator_comment_stripper_spec.rb +1 -1
- data/spec/units/rake_app/rakefile_component_resolver_spec.rb +21 -0
- data/spec/units/release_build_executor_spec.rb +53 -14
- data/spec/units/release_build_planner_spec.rb +15 -3
- data/spec/units/reportinator_spec.rb +5 -5
- data/spec/units/standin_headerinator_spec.rb +31 -1
- data/spec/units/test_build_executor_spec.rb +65 -3
- data/spec/units/test_build_planner_spec.rb +104 -2
- data/spec/units/test_build_setup_spec.rb +96 -12
- data/spec/units/test_context_extractor_spec.rb +25 -0
- data/spec/units/test_file_preprocessinator_spec.rb +17 -1
- data/spec/units/test_includes_extractinator_spec.rb +5 -1
- data/spec/units/test_invoker/objects_wiring_spec.rb +6 -3
- data/spec/units/test_invoker_spec.rb +14 -1
- data/spec/units/test_source_file_directive_resolver_spec.rb +38 -7
- data/spec/units/tool_executor_spec.rb +26 -0
- data/spec/units/yaml_wrapper_spec.rb +11 -0
- metadata +109 -25
- data/lib/ceedling/file_path_collection_utils.rb +0 -164
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# =========================================================================
|
|
2
|
+
# Ceedling - Test-Centered Build System for C
|
|
3
|
+
# ThrowTheSwitch.org
|
|
4
|
+
# Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
|
5
|
+
# SPDX-License-Identifier: MIT
|
|
6
|
+
# =========================================================================
|
|
7
|
+
|
|
8
|
+
require 'rbconfig'
|
|
9
|
+
|
|
10
|
+
# One Ceedling installation, identified by its root directory. Its version is read
|
|
11
|
+
# from its own files, never from the constants of whichever installation loaded first.
|
|
12
|
+
#
|
|
13
|
+
# An application loaded by an older launcher reaches this file through require_relative
|
|
14
|
+
# with someone else's code already loaded, so it depends on nothing else in lib/.
|
|
15
|
+
class Installation
|
|
16
|
+
|
|
17
|
+
VERSION_FILE = File.join( 'lib', 'version.rb' )
|
|
18
|
+
BUILTIN_MIXINS_DIR = File.join( 'vendor', 'unity', 'test', 'targets' )
|
|
19
|
+
|
|
20
|
+
attr_reader :root
|
|
21
|
+
|
|
22
|
+
def self.windows?
|
|
23
|
+
return (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|msys|ucrt/i) ? true : false
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def initialize(root)
|
|
27
|
+
@root = File.expand_path( root )
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def bin_path
|
|
31
|
+
return File.join( @root, 'bin', 'ceedling' )
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def rakefile_path
|
|
35
|
+
return File.join( @root, 'lib', 'ceedling', 'rakefile.rb' )
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# The version tag, or nil when this installation's lib/version.rb is missing or unreadable
|
|
39
|
+
def version
|
|
40
|
+
@version = read_version() unless defined?( @version )
|
|
41
|
+
return @version
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# True when this installation's launcher validates a built-in mixin directory the
|
|
45
|
+
# installation does not hold. `--local` vendoring left it out from 1.1.0 through 1.2.1,
|
|
46
|
+
# so such a copy fails on its own and only ever ran inside another launcher's process.
|
|
47
|
+
def missing_builtin_mixins?
|
|
48
|
+
mixins_filepath = File.join( @root, 'bin', 'mixins.rb' )
|
|
49
|
+
return false if !File.exist?( mixins_filepath )
|
|
50
|
+
return false if !File.read( mixins_filepath ).include?( 'BUILTIN_MIXIN_LOAD_PATHS' )
|
|
51
|
+
|
|
52
|
+
return !File.directory?( File.join( @root, BUILTIN_MIXINS_DIR ) )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Symlinks resolve, and Windows paths compare without case
|
|
56
|
+
def ==(other)
|
|
57
|
+
return false unless other.is_a?( Installation )
|
|
58
|
+
return Installation.windows? ? identity.casecmp?( other.identity ) : (identity == other.identity)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# "Ceedling 1.2.0", or without the version when it cannot be read
|
|
62
|
+
def name(noun='Ceedling')
|
|
63
|
+
return [noun, version()].compact.join( ' ' )
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# "Ceedling 1.2.0 at /path/", or without the version when it cannot be read
|
|
67
|
+
def describe(noun='Ceedling')
|
|
68
|
+
return "#{name( noun )} at #{@root}/"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
protected
|
|
72
|
+
|
|
73
|
+
def identity
|
|
74
|
+
return File.realpath( @root )
|
|
75
|
+
rescue SystemCallError
|
|
76
|
+
return @root
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
# lib/version.rb defines Ceedling::Version. Evaluated within an anonymous module, its
|
|
82
|
+
# constants land beneath that module instead of reopening the loaded ::Ceedling.
|
|
83
|
+
def read_version
|
|
84
|
+
filepath = File.join( @root, VERSION_FILE )
|
|
85
|
+
sandbox = Module.new
|
|
86
|
+
sandbox.module_eval( File.read( filepath ), filepath )
|
|
87
|
+
return sandbox.const_get( :Ceedling, false ).const_get( :Version, false ).const_get( :TAG, false )
|
|
88
|
+
rescue StandardError, ScriptError
|
|
89
|
+
return nil
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# =========================================================================
|
|
2
|
+
# Ceedling - Test-Centered Build System for C
|
|
3
|
+
# ThrowTheSwitch.org
|
|
4
|
+
# Copyright (c) 2010-26 Mike Karlesky, Mark VanderVoord, & Greg Williams
|
|
5
|
+
# SPDX-License-Identifier: MIT
|
|
6
|
+
# =========================================================================
|
|
7
|
+
|
|
8
|
+
# Finds the library files a link's :libraries entries name, so a link can depend on their
|
|
9
|
+
# contents. Which file a toolchain links is its own choice, so every candidate that exists
|
|
10
|
+
# is found. A library only the toolchain's own search paths hold is not found, and a link
|
|
11
|
+
# never depends on a file that doesn't exist, which would read as changed on every build.
|
|
12
|
+
class LibraryResolver
|
|
13
|
+
|
|
14
|
+
# Library extensions toolchains search for beyond a project's own :extension ↳ :libraries
|
|
15
|
+
TOOLCHAIN_EXTENSIONS = ['.a', '.so', '.dylib', '.tbd', '.dll.a', '.lib'].freeze
|
|
16
|
+
|
|
17
|
+
constructor :file_wrapper, :file_path_collection_utils
|
|
18
|
+
|
|
19
|
+
def setup
|
|
20
|
+
@lock = Mutex.new
|
|
21
|
+
@directories = {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# entries: :libraries entries, each a bare name, an `-l:` filename, or a path
|
|
25
|
+
# search_paths: :paths ↳ :libraries, decorated and globbed as configured
|
|
26
|
+
# files: library files known exactly, as a plugin knows those it builds
|
|
27
|
+
def resolve(entries:, search_paths:, files: [])
|
|
28
|
+
return resolve_within( entries, @file_path_collection_utils.collect_paths( search_paths ), files )
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# The library files a link with these :libraries entries depends on: those the entries
|
|
32
|
+
# resolve to on :paths ↳ :libraries, and those plugins publish in LIBRARIES_LINK_FILES
|
|
33
|
+
def link_files(entries)
|
|
34
|
+
return resolve_within( entries, search_directories(), ((defined? LIBRARIES_LINK_FILES) ? LIBRARIES_LINK_FILES : nil) || [] )
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# A link's library search path arguments: each directory of search_directories in
|
|
38
|
+
# :libraries ↳ :path_flag
|
|
39
|
+
def search_path_arguments
|
|
40
|
+
directories = search_directories()
|
|
41
|
+
return directories unless defined?( LIBRARIES_PATH_FLAG )
|
|
42
|
+
|
|
43
|
+
return directories.map { |directory| LIBRARIES_PATH_FLAG.gsub( '${1}' ) { directory } }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The directories :paths ↳ :libraries names, decorated and globbed as configured, with
|
|
47
|
+
# those plugins add once configuration is done. Collected once for a set of paths, since
|
|
48
|
+
# every link asks.
|
|
49
|
+
def search_directories
|
|
50
|
+
paths = ((defined? PATHS_LIBRARIES) ? PATHS_LIBRARIES : nil) || []
|
|
51
|
+
return @lock.synchronize { @directories[paths.dup] ||= @file_path_collection_utils.collect_paths( paths ) }
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def resolve_within(entries, directories, files)
|
|
57
|
+
candidates = Array( entries ).flatten.compact.flat_map { |entry| candidates_for( entry.to_s, directories ) }
|
|
58
|
+
candidates += Array( files )
|
|
59
|
+
|
|
60
|
+
found = candidates.map { |path| @file_path_collection_utils.shortest_path_from_working( File.expand_path( path ) ) }
|
|
61
|
+
return found.select { |path| library_file?( path ) }.uniq
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# An `-l:` entry names its exact filename, a path names itself, and a bare name names every
|
|
65
|
+
# library filename a toolchain makes of it
|
|
66
|
+
def candidates_for(entry, directories)
|
|
67
|
+
return within( directories, entry.delete_prefix( ':' ) ) if entry.start_with?( ':' )
|
|
68
|
+
return [entry] if absolute?( entry )
|
|
69
|
+
return [entry] + within( directories, entry ) if path?( entry )
|
|
70
|
+
|
|
71
|
+
return within( directories, *library_filenames( entry ) )
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def within(directories, *names)
|
|
75
|
+
return directories.product( names ).map { |directory, name| File.join( directory, name ) }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def library_filenames(name)
|
|
79
|
+
return ["lib#{name}", name].product( extensions ).map( &:join )
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# A path, or a filename with a library extension, rather than a name the linker expands
|
|
83
|
+
def path?(entry)
|
|
84
|
+
return entry.match?( %r{[/\\]} ) || extensions.any? { |extension| entry.end_with?( extension ) }
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def absolute?(entry)
|
|
88
|
+
return File.expand_path( entry ) == entry || entry.match?( %r{\A[A-Za-z]:[/\\]} )
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def extensions
|
|
92
|
+
@extensions ||= ((defined?( EXTENSION_LIBRARIES ) ? EXTENSION_LIBRARIES.to_a : []) + TOOLCHAIN_EXTENSIONS).uniq
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def library_file?(path)
|
|
96
|
+
return @file_wrapper.exist?( path ) && !@file_wrapper.directory?( path )
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
data/lib/ceedling/objects.yml
CHANGED
|
@@ -87,6 +87,7 @@ configurator_setup:
|
|
|
87
87
|
compose:
|
|
88
88
|
- configurator_builder
|
|
89
89
|
- configurator_validator
|
|
90
|
+
- configurator_paths_validator
|
|
90
91
|
- loginator
|
|
91
92
|
- reportinator
|
|
92
93
|
- file_wrapper
|
|
@@ -101,11 +102,17 @@ configurator_plugins:
|
|
|
101
102
|
configurator_validator:
|
|
102
103
|
compose:
|
|
103
104
|
- config_walkinator
|
|
104
|
-
- file_wrapper
|
|
105
105
|
- loginator
|
|
106
106
|
- reportinator
|
|
107
107
|
- tool_validator
|
|
108
108
|
|
|
109
|
+
configurator_paths_validator:
|
|
110
|
+
compose:
|
|
111
|
+
- config_walkinator
|
|
112
|
+
- file_wrapper
|
|
113
|
+
- loginator
|
|
114
|
+
- reportinator
|
|
115
|
+
|
|
109
116
|
configurator_builder:
|
|
110
117
|
compose:
|
|
111
118
|
- file_path_collection_utils
|
|
@@ -148,6 +155,10 @@ plugin_reportinator_helper:
|
|
|
148
155
|
|
|
149
156
|
verbosinator:
|
|
150
157
|
|
|
158
|
+
build_log_writer:
|
|
159
|
+
compose:
|
|
160
|
+
- file_wrapper
|
|
161
|
+
|
|
151
162
|
file_finder:
|
|
152
163
|
compose:
|
|
153
164
|
- configurator
|
|
@@ -247,7 +258,7 @@ generator_test_results_backtrace:
|
|
|
247
258
|
- generator_test_results
|
|
248
259
|
- generator_helper
|
|
249
260
|
- file_path_utils
|
|
250
|
-
-
|
|
261
|
+
- build_log_writer
|
|
251
262
|
- loginator
|
|
252
263
|
|
|
253
264
|
generator_test_results_sanity_checker:
|
|
@@ -402,6 +413,7 @@ test_invoker:
|
|
|
402
413
|
- loginator
|
|
403
414
|
- verbosinator
|
|
404
415
|
- test_pipeline_manager
|
|
416
|
+
- include_pathinator
|
|
405
417
|
|
|
406
418
|
test_pipeline_manager:
|
|
407
419
|
compose:
|
|
@@ -434,6 +446,7 @@ test_build_setup:
|
|
|
434
446
|
- dependinator
|
|
435
447
|
- test_search_paths
|
|
436
448
|
- mock_locator
|
|
449
|
+
- test_source_file_directive_resolver
|
|
437
450
|
|
|
438
451
|
test_includes_extractinator:
|
|
439
452
|
compose:
|
|
@@ -559,6 +572,8 @@ test_build_executor:
|
|
|
559
572
|
- gcc_dependency_parser
|
|
560
573
|
- quote_include_isolator
|
|
561
574
|
- generator_helper
|
|
575
|
+
- library_resolver
|
|
576
|
+
- mock_locator
|
|
562
577
|
|
|
563
578
|
partials_manager:
|
|
564
579
|
compose:
|
|
@@ -603,6 +618,12 @@ release_build_executor:
|
|
|
603
618
|
- file_wrapper
|
|
604
619
|
- file_path_utils
|
|
605
620
|
- dependinator
|
|
621
|
+
- library_resolver
|
|
622
|
+
|
|
623
|
+
library_resolver:
|
|
624
|
+
compose:
|
|
625
|
+
- file_wrapper
|
|
626
|
+
- file_path_collection_utils
|
|
606
627
|
|
|
607
628
|
gcc_dependency_parser:
|
|
608
629
|
|
|
@@ -14,7 +14,7 @@ require 'ceedling/c_extractor/c_extractor'
|
|
|
14
14
|
require 'ceedling/c_extractor/c_extractor_constants'
|
|
15
15
|
require 'ceedling/c_extractor/c_extractor_types'
|
|
16
16
|
require 'ceedling/constants'
|
|
17
|
-
require 'ceedling/path_mirror'
|
|
17
|
+
require 'ceedling/filesystem/path_mirror'
|
|
18
18
|
require 'ceedling/encodinator'
|
|
19
19
|
|
|
20
20
|
class Partializer
|
|
@@ -124,7 +124,7 @@ class Partializer
|
|
|
124
124
|
def _find_module_source(_module, header_filepath)
|
|
125
125
|
return @file_finder.find_source_file(_module, :ignore) if _names_directory?(_module)
|
|
126
126
|
|
|
127
|
-
subdir = header_filepath.nil? ? '' : PathMirror.
|
|
127
|
+
subdir = header_filepath.nil? ? '' : PathMirror.relative_subdir_from_clean_roots( header_filepath, _header_roots )
|
|
128
128
|
|
|
129
129
|
unless subdir.empty?
|
|
130
130
|
found = @file_finder.find_source_file(File.join(subdir, _module), :ignore)
|
|
@@ -135,9 +135,9 @@ class Partializer
|
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
# Roots a header can sit beneath, which is what its mirrored directory is measured
|
|
138
|
-
# against
|
|
138
|
+
# against: those the project-wide header collection is built from, spelled canonically.
|
|
139
139
|
def _header_roots
|
|
140
|
-
@configurator.
|
|
140
|
+
@configurator.collection_mirror_roots_headers
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
# Either separator counts. The qualifier validation already rejects a backslash-rooted
|
|
@@ -9,6 +9,7 @@ require 'stringio'
|
|
|
9
9
|
require 'strscan'
|
|
10
10
|
require 'ceedling/partials/partials'
|
|
11
11
|
require 'ceedling/exceptions'
|
|
12
|
+
require 'ceedling/filesystem/project_paths'
|
|
12
13
|
require 'ceedling/c_extractor/c_extractor_preprocessing'
|
|
13
14
|
require 'ceedling/encodinator'
|
|
14
15
|
|
|
@@ -259,7 +260,8 @@ class PartializerConfig
|
|
|
259
260
|
_validate_qualifier!( dir, macro_name )
|
|
260
261
|
_validate_module!( params[1], macro_name, dir: dir )
|
|
261
262
|
|
|
262
|
-
|
|
263
|
+
# A `.` segment names nothing, so `./drv` and `drv` name one module
|
|
264
|
+
File.join( *ProjectPaths.segments( dir ), params[1] )
|
|
263
265
|
end
|
|
264
266
|
|
|
265
267
|
# The module argument names one file's stem and nothing more. The preprocessor emits it
|
|
@@ -27,12 +27,10 @@ class ReportLogWriterPlugin < Plugin
|
|
|
27
27
|
|
|
28
28
|
private
|
|
29
29
|
|
|
30
|
-
#
|
|
31
|
-
#
|
|
30
|
+
# Returns the filepath for `filename` beneath <build root>/artifacts/<context>/, with its
|
|
31
|
+
# directory made. A filename named for a test carries the test's subdirectories.
|
|
32
32
|
def artifact_filepath(context, filename)
|
|
33
|
-
|
|
34
|
-
@file_wrapper.mkdir(path)
|
|
35
|
-
File.join(path, filename)
|
|
33
|
+
@file_wrapper.mkdir_for( File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s, filename) )
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
# Logs a heading, then either reports `empty_message` or runs the
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'rake' # for ext() method
|
|
9
|
-
require 'ceedling/file_wrapper'
|
|
9
|
+
require 'ceedling/filesystem/file_wrapper'
|
|
10
10
|
require 'ceedling/encodinator'
|
|
11
11
|
require 'ceedling/preprocess/c_preprocessor_conditionals'
|
|
12
12
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/includes/includes'
|
|
9
|
-
require 'ceedling/path_matcher'
|
|
9
|
+
require 'ceedling/filesystem/path_matcher'
|
|
10
10
|
require 'ceedling/preprocess/preprocessinator_bare_includes_extractor'
|
|
11
11
|
require 'ceedling/preprocess/preprocessinator_line_marker_includes_extractor'
|
|
12
12
|
require 'ceedling/preprocess/c_preprocessor_conditionals'
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
|
+
require 'ceedling/filesystem/project_paths'
|
|
9
10
|
|
|
10
11
|
# Resolves the ordered list of .rake files Ceedling will load for a given project
|
|
11
12
|
# configuration. Callable from both bin/ (early, before do_setup) and lib/ (within
|
|
@@ -39,8 +40,11 @@ module RakefileComponentResolver
|
|
|
39
40
|
# plugins path last. This ordering lets user plugins shadow built-in plugins of the
|
|
40
41
|
# same name. Used by both resolve() (bin/ CLI scope) and Configurator#prepare_plugins_load_paths
|
|
41
42
|
# (application scope) so both scopes search plugins in the same priority order.
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
#
|
|
44
|
+
# `expand` applies inline Ruby string expansion to each configured path, and each is then
|
|
45
|
+
# standardized as every other configured path is, so both scopes read them alike.
|
|
46
|
+
def prepare_plugin_load_paths(config, ceedling_plugins_path, expand: ->(path) { path })
|
|
47
|
+
load_paths = Array( config.dig(:plugins, :load_paths) ).compact.map { |path| ProjectPaths.standardize( expand.call( path ) ) }
|
|
44
48
|
load_paths << ceedling_plugins_path
|
|
45
49
|
load_paths.compact!
|
|
46
50
|
load_paths.uniq!
|
|
@@ -51,7 +55,7 @@ module RakefileComponentResolver
|
|
|
51
55
|
# - Stock files (always)
|
|
52
56
|
# - Conditional stock files (rules_release, tasks_release if release_build is enabled)
|
|
53
57
|
# - Plugin .rake files (first matching <root>/<plugin>/<plugin>.rake across load_paths)
|
|
54
|
-
def resolve(config, ceedling_lib_path, ceedling_plugins_path)
|
|
58
|
+
def resolve(config, ceedling_lib_path, ceedling_plugins_path, expand: ->(path) { path })
|
|
55
59
|
paths = base_rakefiles(ceedling_lib_path) + test_rakefiles(ceedling_lib_path)
|
|
56
60
|
|
|
57
61
|
if config.dig(:project, :release_build)
|
|
@@ -59,7 +63,7 @@ module RakefileComponentResolver
|
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
paths.concat(
|
|
62
|
-
plugin_rake_files( config, prepare_plugin_load_paths(config, ceedling_plugins_path) )
|
|
66
|
+
plugin_rake_files( config, prepare_plugin_load_paths(config, ceedling_plugins_path, expand: expand) )
|
|
63
67
|
)
|
|
64
68
|
|
|
65
69
|
return paths
|
|
@@ -70,20 +74,9 @@ module RakefileComponentResolver
|
|
|
70
74
|
# Uses File.exist? directly (no DI needed) — same check as ConfiguratorPlugins#find_rake_plugins.
|
|
71
75
|
# Array() wraps nil gracefully so missing config keys don't raise.
|
|
72
76
|
def plugin_rake_files(config, load_paths)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
enabled.each do |plugin|
|
|
77
|
-
load_paths.each do |load_path|
|
|
78
|
-
candidate = File.join(load_path, plugin, "#{plugin}.rake")
|
|
79
|
-
if File.exist?(candidate)
|
|
80
|
-
results << candidate
|
|
81
|
-
break
|
|
82
|
-
end
|
|
83
|
-
end
|
|
77
|
+
return Array( config.dig(:plugins, :enabled) ).filter_map do |plugin|
|
|
78
|
+
load_paths.lazy.map { |load_path| File.join(load_path, plugin, "#{plugin}.rake") }.find { |candidate| File.exist?(candidate) }
|
|
84
79
|
end
|
|
85
|
-
|
|
86
|
-
results
|
|
87
80
|
end
|
|
88
81
|
|
|
89
82
|
end
|
data/lib/ceedling/rakefile.rb
CHANGED
|
@@ -5,6 +5,18 @@
|
|
|
5
5
|
# SPDX-License-Identifier: MIT
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
|
+
# A launcher before 1.2.2 loads this application into its own process, where its code
|
|
9
|
+
# mixes with this installation's. Before anything else loads, restart in this
|
|
10
|
+
# installation's own process. require_relative, because such a launcher's load path
|
|
11
|
+
# cannot reach files newer than itself.
|
|
12
|
+
require_relative 'handoff'
|
|
13
|
+
Handoff.complete_in_process(
|
|
14
|
+
app_root: File.expand_path( File.join( __dir__, '..', '..' ) ),
|
|
15
|
+
app_cfg: CEEDLING_APPCFG,
|
|
16
|
+
handoff_objects: CEEDLING_HANDOFF_OBJECTS,
|
|
17
|
+
env: ENV
|
|
18
|
+
)
|
|
19
|
+
|
|
8
20
|
require 'fileutils'
|
|
9
21
|
|
|
10
22
|
# Add Unity and CMock's Ruby code paths to $LOAD_PATH for runner generation and mocking
|
|
@@ -49,7 +61,9 @@ begin
|
|
|
49
61
|
# 1. Add full path to $LOAD_PATH to simplify objects.yml
|
|
50
62
|
# 2. Perform object construction + dependency injection
|
|
51
63
|
# 3. Remove full path from $LOAD_PATH
|
|
52
|
-
|
|
64
|
+
# The full path comes last, behind its subdirectories, so a file an older Ceedling left
|
|
65
|
+
# directly in lib/ceedling/ never stands in for one that has moved below it
|
|
66
|
+
$LOAD_PATH.push( CEEDLING_APPCFG[:ceedling_lib_path] )
|
|
53
67
|
objects_filepath = File.join( CEEDLING_APPCFG[:ceedling_lib_path], 'objects.yml' )
|
|
54
68
|
|
|
55
69
|
# Create object hash and dependency injection context
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
|
-
require 'ceedling/file_path_utils'
|
|
9
|
+
require 'ceedling/filesystem/file_path_utils'
|
|
10
10
|
|
|
11
11
|
# Set Rake verbosity using global constant verbosity set before Rake is loaded
|
|
12
12
|
if !!defined?(PROJECT_VERBOSITY)
|
|
@@ -21,11 +21,9 @@ namespace RELEASE_SYM do
|
|
|
21
21
|
# Use rules to increase efficiency for large projects (instead of iterating through all sources and creating defined tasks)
|
|
22
22
|
|
|
23
23
|
# Unadvertised Rake task to execute source file compilation in isolation.
|
|
24
|
-
# A source extension can be configured as more than one string, so
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
release_source_extensions = EXTENSION_SOURCE.to_a.map { |ext| Regexp.escape(ext) }.join('|')
|
|
28
|
-
rule(/^#{RELEASE_COMPILE_TASK_ROOT}\S+(?:#{release_source_extensions}|#{Regexp.escape(EXTENSION_CORE_SOURCE)})$/ => [ # compile task names by regex
|
|
24
|
+
# A source extension can be configured as more than one string, so a task name ending in
|
|
25
|
+
# any of them matches, rather than only the first/primary one.
|
|
26
|
+
rule(/^#{RELEASE_COMPILE_TASK_ROOT}\S+(?:#{EXTENSION_SOURCE.pattern}|#{Regexp.escape(EXTENSION_CORE_SOURCE)})$/ => [ # compile task names by regex
|
|
29
27
|
proc do |task_name|
|
|
30
28
|
source = task_name.sub(/#{RELEASE_COMPILE_TASK_ROOT}/, '')
|
|
31
29
|
@ceedling[:file_finder].find_source_file(source)
|
|
@@ -37,8 +35,7 @@ namespace RELEASE_SYM do
|
|
|
37
35
|
|
|
38
36
|
# Unadvertised Rake task to execute source file assembly in isolation
|
|
39
37
|
if (RELEASE_BUILD_USE_ASSEMBLY)
|
|
40
|
-
|
|
41
|
-
rule(/^#{RELEASE_ASSEMBLE_TASK_ROOT}\S+(?:#{release_assembly_extensions})$/ => [ # assemble task names by regex
|
|
38
|
+
rule(/^#{RELEASE_ASSEMBLE_TASK_ROOT}\S+#{EXTENSION_ASSEMBLY.pattern}$/ => [ # assemble task names by regex
|
|
42
39
|
proc do |task_name|
|
|
43
40
|
source = task_name.sub(/#{RELEASE_ASSEMBLE_TASK_ROOT}/, '')
|
|
44
41
|
@ceedling[:file_finder].find_assembly_file(source)
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
# =========================================================================
|
|
7
7
|
|
|
8
8
|
require 'ceedling/constants'
|
|
9
|
+
require 'ceedling/filename_extension'
|
|
9
10
|
require 'ceedling/release_invoker/release_invoker_types'
|
|
10
11
|
|
|
11
12
|
# Does the actual work of a release build: compiling objects, linking the
|
|
@@ -24,7 +25,8 @@ class ReleaseBuildExecutor
|
|
|
24
25
|
:file_finder,
|
|
25
26
|
:file_wrapper,
|
|
26
27
|
:file_path_utils,
|
|
27
|
-
:dependinator
|
|
28
|
+
:dependinator,
|
|
29
|
+
:library_resolver
|
|
28
30
|
)
|
|
29
31
|
|
|
30
32
|
def compile_objects(state)
|
|
@@ -44,17 +46,22 @@ class ReleaseBuildExecutor
|
|
|
44
46
|
def link(state)
|
|
45
47
|
objects, libraries = sort_objects_and_libraries( state.objects )
|
|
46
48
|
lib_args = convert_libraries_to_arguments( libraries )
|
|
47
|
-
lib_paths =
|
|
49
|
+
lib_paths = @library_resolver.search_path_arguments()
|
|
50
|
+
library_files = @library_resolver.link_files( release_library_entries( libraries ) )
|
|
48
51
|
target = @configurator.project_release_build_target
|
|
49
52
|
|
|
53
|
+
# As with a test link, the object and library lists as meta relink an artifact that a
|
|
54
|
+
# dropped source or library would otherwise leave holding its code
|
|
50
55
|
@dependinator.register(
|
|
51
56
|
target,
|
|
52
|
-
files: objects,
|
|
53
|
-
meta: { flags: state.link_flags, lib_args: lib_args, lib_paths: lib_paths, tools: [@configurator.tools_release_linker] }
|
|
57
|
+
files: objects + library_files,
|
|
58
|
+
meta: { flags: state.link_flags, lib_args: lib_args, lib_paths: lib_paths, tools: [@configurator.tools_release_linker], objects: objects, libraries: library_files }
|
|
54
59
|
)
|
|
55
60
|
stale = @dependinator.stale?( target )
|
|
56
61
|
|
|
57
62
|
if stale
|
|
63
|
+
# A target named by an absolute :output may sit in a directory no build made
|
|
64
|
+
@file_wrapper.mkdir( File.dirname( target ) )
|
|
58
65
|
@generator.generate_executable_file(
|
|
59
66
|
@configurator.tools_release_linker,
|
|
60
67
|
RELEASE_SYM,
|
|
@@ -192,13 +199,7 @@ class ReleaseBuildExecutor
|
|
|
192
199
|
end
|
|
193
200
|
|
|
194
201
|
def convert_libraries_to_arguments(libraries)
|
|
195
|
-
args =
|
|
196
|
-
(libraries || []) +
|
|
197
|
-
((defined? LIBRARIES_SYSTEM) ? LIBRARIES_SYSTEM : []) +
|
|
198
|
-
((defined? LIBRARIES_RELEASE) ? LIBRARIES_RELEASE : [])
|
|
199
|
-
|
|
200
|
-
args.flatten!
|
|
201
|
-
args.compact!
|
|
202
|
+
args = release_library_entries( libraries )
|
|
202
203
|
|
|
203
204
|
if (defined? LIBRARIES_FLAG)
|
|
204
205
|
args.map! { |v| LIBRARIES_FLAG.gsub(/\$\{1\}/, v) }
|
|
@@ -207,12 +208,15 @@ class ReleaseBuildExecutor
|
|
|
207
208
|
return args
|
|
208
209
|
end
|
|
209
210
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
# The :libraries entries a release links, whatever form each takes, beside the library
|
|
212
|
+
# files its object list names
|
|
213
|
+
def release_library_entries(libraries)
|
|
214
|
+
entries =
|
|
215
|
+
(libraries || []) +
|
|
216
|
+
((defined? LIBRARIES_SYSTEM) ? LIBRARIES_SYSTEM : []) +
|
|
217
|
+
((defined? LIBRARIES_RELEASE) ? LIBRARIES_RELEASE : [])
|
|
218
|
+
|
|
219
|
+
return entries.flatten.compact
|
|
216
220
|
end
|
|
217
221
|
|
|
218
222
|
# A release's object list can include precompiled libraries/archives
|
|
@@ -221,35 +225,20 @@ class ReleaseBuildExecutor
|
|
|
221
225
|
# arguments rather than as ordinary link inputs, so they're split out here
|
|
222
226
|
# by file extension before linking.
|
|
223
227
|
def sort_objects_and_libraries(both)
|
|
224
|
-
# A library type may be named by several extensions at once (.a and .so, say), so its
|
|
225
|
-
# regex alternation is built from however many are configured -- one entry needs no
|
|
226
|
-
# alternation at all, several are joined into one. Enumerable is the test rather than
|
|
227
|
-
# Array specifically, since a library-type extension is a FilenameExtension by the time
|
|
228
|
-
# it reaches here, not a raw Array, even though both are iterable the same way.
|
|
229
|
-
extension = if ((defined? EXTENSION_SUBPROJECTS) && (defined? EXTENSION_LIBRARIES))
|
|
230
|
-
extension_libraries = if (EXTENSION_LIBRARIES.is_a? Enumerable)
|
|
231
|
-
EXTENSION_LIBRARIES.to_a.join(")|(?:\\")
|
|
232
|
-
else
|
|
233
|
-
EXTENSION_LIBRARIES
|
|
234
|
-
end
|
|
235
|
-
"(?:\\#{EXTENSION_SUBPROJECTS})|(?:\\#{extension_libraries})"
|
|
236
|
-
elsif (defined? EXTENSION_SUBPROJECTS)
|
|
237
|
-
"\\#{EXTENSION_SUBPROJECTS}"
|
|
238
|
-
elsif (defined? EXTENSION_LIBRARIES)
|
|
239
|
-
if (EXTENSION_LIBRARIES.is_a? Enumerable)
|
|
240
|
-
"(?:\\#{EXTENSION_LIBRARIES.to_a.join(")|(?:\\")})"
|
|
241
|
-
else
|
|
242
|
-
"\\#{EXTENSION_LIBRARIES}"
|
|
243
|
-
end
|
|
244
|
-
else
|
|
245
|
-
"\\.LIBRARY"
|
|
246
|
-
end
|
|
247
228
|
# Compile once rather than once per entry in `both`
|
|
248
|
-
library_pattern = /.+#{
|
|
229
|
+
library_pattern = /.+#{library_endings()}$/
|
|
249
230
|
sorted_objects = both.group_by { |v| v.match?( library_pattern ) ? :libraries : :objects }
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
231
|
+
return (sorted_objects[:objects] || []), (sorted_objects[:libraries] || [])
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# A library type may be named by several extensions at once (.a and .so, say), and a
|
|
235
|
+
# subproject's by its own
|
|
236
|
+
def library_endings
|
|
237
|
+
endings = []
|
|
238
|
+
endings << FilenameExtension.new( EXTENSION_SUBPROJECTS ).pattern if defined? EXTENSION_SUBPROJECTS
|
|
239
|
+
endings << FilenameExtension.new( EXTENSION_LIBRARIES ).pattern if defined? EXTENSION_LIBRARIES
|
|
240
|
+
endings << Regexp.escape( '.LIBRARY' ) if endings.empty?
|
|
241
|
+
return "(?:#{endings.join( '|' )})"
|
|
253
242
|
end
|
|
254
243
|
|
|
255
244
|
# States, in one line, how many targets a build step left untouched because nothing
|
|
@@ -34,15 +34,16 @@ class ReleaseBuildPlanner
|
|
|
34
34
|
def plan(state, files: nil)
|
|
35
35
|
tailor_release_tools()
|
|
36
36
|
|
|
37
|
-
sources
|
|
37
|
+
# A link-only name is no source of its own. Placed apart from the sources, one naming
|
|
38
|
+
# the object a source builds to joins it rather than colliding with it.
|
|
39
|
+
sources, link_only =
|
|
38
40
|
if files.nil?
|
|
39
|
-
@configurator.collection_release_build_input
|
|
40
|
-
@configurator.collection_release_artifact_extra_link_objects
|
|
41
|
+
[@configurator.collection_release_build_input, @configurator.collection_release_artifact_extra_link_objects]
|
|
41
42
|
else
|
|
42
|
-
files.dup
|
|
43
|
+
[files.dup, []]
|
|
43
44
|
end
|
|
44
45
|
|
|
45
|
-
state.objects =
|
|
46
|
+
state.objects = release_objects( sources, link_only )
|
|
46
47
|
state.compile_flags = @flaginator.flag_down( context: RELEASE_SYM, operation: OPERATION_COMPILE_SYM )
|
|
47
48
|
state.assemble_flags = @flaginator.flag_down( context: RELEASE_SYM, operation: OPERATION_ASSEMBLE_SYM )
|
|
48
49
|
state.link_flags = @flaginator.flag_down( context: RELEASE_SYM, operation: OPERATION_LINK_SYM )
|
|
@@ -52,6 +53,13 @@ class ReleaseBuildPlanner
|
|
|
52
53
|
|
|
53
54
|
private
|
|
54
55
|
|
|
56
|
+
def release_objects(sources, link_only)
|
|
57
|
+
objects = @file_path_utils.form_release_build_objects_filelist( sources ).to_a
|
|
58
|
+
return objects if link_only.empty?
|
|
59
|
+
|
|
60
|
+
return (objects + @file_path_utils.form_release_build_objects_filelist( link_only ).to_a).uniq
|
|
61
|
+
end
|
|
62
|
+
|
|
55
63
|
# Shared libraries and static archives need compiler/linker argument tags
|
|
56
64
|
# (-fPIC, -shared, or swapping the linker for `ar` outright) that a plain
|
|
57
65
|
# executable target doesn't -- derived once per build from the release
|
|
@@ -73,7 +81,7 @@ class ReleaseBuildPlanner
|
|
|
73
81
|
when '.a'
|
|
74
82
|
compiler[:arguments] << '-fPIC' unless compiler[:arguments].include?('-fPIC')
|
|
75
83
|
linker[:executable] = 'ar'
|
|
76
|
-
linker[:arguments] = ['rcs', '${2}', '${1}']
|
|
84
|
+
linker[:arguments] = ['rcs', '"${2}"', '"${1}"']
|
|
77
85
|
end
|
|
78
86
|
end
|
|
79
87
|
|