A very good question and the answer isn't simple. Several things to consider. Here are a few opinions from my experience so far.
Common Code vs Project-Local Copy
One important decision is whether to use "common" library code that is updated automatically from a central location (your company's "reuse library"), or whether to keep a project-local copy.
This is discussed in detail in this SO question.
The benefit of a central library is that work done once can benefit many projects. The difficulty with a project-local copy is that any bug fixes and improvements aren't contributed back to the central library, and any bug fixes in the central library may not be brought into your project.
But a potential difficulty with using a central library is if people on their particular modify it in an uncontrolled way to suit their project, and it unintentionally breaks other projects. I've seen that personally, in "common" code that became full of #ifdefs and regularly broke other projects.
To get good value out of common code aka central reuse library:
The library:
- must have well-defined requirements, API, and unit tests
- must avoid project-specific code; it should be general-purpose
- should have a mechanism for cleanly setting project-specific settings (this can be seen as part of the API, effectively)
- must have a formal release process, with version numbers and fixes, issues must be tracked.
Individual projects:
- shouldn't automatically and blindly get "the latest", but should be able to get a particular "release" with a specified version number. Then projects should have control over if/when they update to a newer version. The project should be able to clearly track, "we are using version 1.2.3 of library xyz".
- should avoid "forking" the library code if at all possible. E.g. avoid adding project-specific "features" to the library code.
- should track any local modifications to the library code
- should regard bugs as library bugs, to be fixed in the central library if at all possible. The company should have processes to fix them in the central library, test the library with its own unit test suite (probably improving the unit tests to catch the bug in future). Then release a new version of the central library as needed, and deploy to other projects if/when those projects see fit.
If a company doesn't have such a process in place, then a project should just make a local copy of a piece of code (say, copied from a previous project) and then take full project-local responsibility from then on. You're still getting some benefit from reuse in that situation, because you're not rewriting it from scratch.
Project-Specific Configuration
If the code needs project-specific configuration, ideally that should be kept to as small a part of the code as possible--not scattered through a bunch of source files. Ideally, a single header file. But quite possibly a .C file as well (say, if you need to define some look-up tables). The library should provide a template, with the options well-commented.
For a good example of how this can be done, see the µC/OS-II RTOS (book) by Jean Labrosse, from Micrium.