Skip to main content

Note: The question was heavily rewritten after the comments it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem: Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

  • Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
  • Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
  • If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

Note: The question was heavily rewritten after the comments it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem: Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

Note: The question was heavily rewritten after the comments it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem:

  • Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
  • Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
  • If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

Post Reopened by Hans-Martin Mosner, Basilevs, Doc Brown
added 3 characters in body
Source Link

Note: The question was heavily rewritten after the postscomments it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem: Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

Note: The question was heavily rewritten after the posts it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem: Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

Note: The question was heavily rewritten after the comments it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem: Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release.
If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

deleted 3023 characters in body; edited tags; edited title
Added to review
Source Link

How to Refactor Monolithic Repositories for Embedded “Bare Metal” Applications and Shared Libraries with Intermanage common library dependencies to prevent cross-Dependenciesapplication breakage?

Note: The question was heavily rewritten after the posts it received.

I work on ana team that develops embedded software team responsible for multiplevarious in-house developed devices. Each device runs several “bare metal” applications—there is no operating system like Linux; insteadhosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., binary images are flashed to the devicesfor networking, with each image statically linking all required codecryptography, etc. Only one application can run at a given time) used by the applications.

Current Setup and Issues

Monolithic Repository per Device

Each device has All the code lives inside a single per-device repository that contains:where every commit goes into a main branch.

  • Code for all the device’s applications.
  • Static libraries providing common features (e.g., networking, cryptography) that are shared between the applications.

Shared Code Challenges

  • Breaking Changes:
    When one developer makes a change in a library shared between applications to add a new feature, the update is committed directly to the repository’s main branch. While the change may work for the developer’s specific application, it can inadvertently break up other applications that depend on the same library.

  • Duplicated Fixes:
    A bug fix in a library in one device repository must then be manually replicated across other device repositories, increasing maintenance overhead.

Proposed New Approach

  • Separate Repositories:
    Move each library and each application to its own dedicated Git repository.

  • Version Control for Dependencies:
    In each application repository, specify the exact version (using tags or commit hashes) for each required library. This is similar to dependency management strategies (such as Zephyr’s west) where an application “pulls” the precise version of each library it depends on.

Advantages

  • Isolation of Changes:
    A breaking change in a library will not force an immediate upgrade on all applications—each application remains pinned to the version that has been thoroughly tested.

  • Streamlined Bug Fixes:
    A reported bug can be addressed by updating the pinned version for a single application, enabling the QA team to validate the change independently. This provides stability while development on the common libraries continues.

  • Reduced Duplication:
    Fixes in common libraries do not need to be manually replicated across multiple device repositories.

New Requirement – Inter-Dependent Libraries

The challenge grows when we introduce inter-dependencies among libraries. For example,This setup has led to a “Hardware Abstraction Layer” (HAL) library is utilizedmajor problem: Team members that are working on one application are breaking others application and work by almost every other librarycommitting changes to the common libraries.
The same goes for a “OS Abstraction Layer”Developer of "App B that abstracts away OS multithreading things (We can't use STL threading related classes like thread, mutex, condition_variable, etc since they are generally not supported inuses Lib A" has no way to choose a fixed version of the embedded world)"Lib A" for his release. 
How should we effectively manage versioning and dependency control when libraries themselves depend onIf developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other libraries? Specifically:developers to be ready before doing it's commit.

  • What strategies or tools can resolve conflicts or manage cascading changes across a hierarchy of inter-dependent libraries?
  • Are there approaches from similar embedded or constrained environments that may better serve our needs in terms of modularity, testing, and maintenance?

Additional Context and Considerations

  • Embedded Development Constraints:
    Since our applications are “bare metal,” all dependency resolutions must be handled at build time with no runtime dependency management.

  • Impact on Workflow:
    How do we strike a balance between the stability required for intensive QA testing (pinning tested versions) and the flexibility needed to integrate improvements or necessary fixes in common libraries, especially as those libraries are used across multiple applications?

Request for Community Input

I’m looking for guidance on:The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

  • Best practices for managing versioned dependencies in a modularized codebase for embedded “bare metal” systems.
  • Tools, methodologies, or dependency management systems that have been effective in similar scenarios with inter-library dependencies.
  • Potential pitfalls or alternative strategies that might be considered, given the dual priorities of ongoing development and ensuring the stability needed for QA testing and bug resolution.

Any insights, experiences, or referencesWhat strategy can we adopt to similar cases would be greatly appreciated!resolve the above problem?

How to Refactor Monolithic Repositories for Embedded “Bare Metal” Applications and Shared Libraries with Inter-Dependencies?

I work on an embedded software team responsible for multiple in-house developed devices. Each device runs several “bare metal” applications—there is no operating system like Linux; instead, binary images are flashed to the devices, with each image statically linking all required code. Only one application can run at a given time.

Current Setup and Issues

Monolithic Repository per Device

Each device has a single repository that contains:

  • Code for all the device’s applications.
  • Static libraries providing common features (e.g., networking, cryptography) that are shared between the applications.

Shared Code Challenges

  • Breaking Changes:
    When one developer makes a change in a library shared between applications to add a new feature, the update is committed directly to the repository’s main branch. While the change may work for the developer’s specific application, it can inadvertently break up other applications that depend on the same library.

  • Duplicated Fixes:
    A bug fix in a library in one device repository must then be manually replicated across other device repositories, increasing maintenance overhead.

Proposed New Approach

  • Separate Repositories:
    Move each library and each application to its own dedicated Git repository.

  • Version Control for Dependencies:
    In each application repository, specify the exact version (using tags or commit hashes) for each required library. This is similar to dependency management strategies (such as Zephyr’s west) where an application “pulls” the precise version of each library it depends on.

Advantages

  • Isolation of Changes:
    A breaking change in a library will not force an immediate upgrade on all applications—each application remains pinned to the version that has been thoroughly tested.

  • Streamlined Bug Fixes:
    A reported bug can be addressed by updating the pinned version for a single application, enabling the QA team to validate the change independently. This provides stability while development on the common libraries continues.

  • Reduced Duplication:
    Fixes in common libraries do not need to be manually replicated across multiple device repositories.

New Requirement – Inter-Dependent Libraries

The challenge grows when we introduce inter-dependencies among libraries. For example, a “Hardware Abstraction Layer” (HAL) library is utilized by almost every other library.
The same goes for a “OS Abstraction Layer” that abstracts away OS multithreading things (We can't use STL threading related classes like thread, mutex, condition_variable, etc since they are generally not supported in the embedded world). How should we effectively manage versioning and dependency control when libraries themselves depend on other libraries? Specifically:

  • What strategies or tools can resolve conflicts or manage cascading changes across a hierarchy of inter-dependent libraries?
  • Are there approaches from similar embedded or constrained environments that may better serve our needs in terms of modularity, testing, and maintenance?

Additional Context and Considerations

  • Embedded Development Constraints:
    Since our applications are “bare metal,” all dependency resolutions must be handled at build time with no runtime dependency management.

  • Impact on Workflow:
    How do we strike a balance between the stability required for intensive QA testing (pinning tested versions) and the flexibility needed to integrate improvements or necessary fixes in common libraries, especially as those libraries are used across multiple applications?

Request for Community Input

I’m looking for guidance on:

  • Best practices for managing versioned dependencies in a modularized codebase for embedded “bare metal” systems.
  • Tools, methodologies, or dependency management systems that have been effective in similar scenarios with inter-library dependencies.
  • Potential pitfalls or alternative strategies that might be considered, given the dual priorities of ongoing development and ensuring the stability needed for QA testing and bug resolution.

Any insights, experiences, or references to similar cases would be greatly appreciated!

How to manage common library dependencies to prevent cross-application breakage?

Note: The question was heavily rewritten after the posts it received.

I work on a team that develops embedded software for various in-house devices. Each device hosts multiple "bare metal" applications—all compiled into self-contained binaries—and we also maintain a set of common static libraries (e.g., for networking, cryptography, etc.) used by the applications. All the code lives inside a single per-device repository where every commit goes into a main branch.

This setup has led to a major problem: Team members that are working on one application are breaking others application and work by committing changes to the common libraries.
Developer of "App B that uses Lib A" has no way to choose a fixed version of the "Lib A" for his release. 
If developer of "App A that uses Lib A" needs to make a required breaking change it has to wait for the other developers to be ready before doing it's commit.

The codebase currently does not support automated testing. Making the code testable requires heavy refactoring that in the current situation we can't easily do because of the above It's something we are aiming to do after resolving or making this issue less problematic.

What strategy can we adopt to resolve the above problem?

Post Closed as "Needs more focus" by gnat, Arseni Mourzenko, Greg Burghardt
added 240 characters in body
Source Link
Loading
Source Link
Loading