Software reuse is concerned with the ability use a source code component in more than one context without changing the component.
Sounds simple enough, right? The problem comes with the "without change" restriction. Not only does this mean that the file containing the source code may not be changed, it also means that the file cannot be moved, copied, renamed or conditionally compiled.
This strict definition of software reuse is important so that we may achieve the promise of software reuse.
Build environment files include makefiles, environment variables, and build scripts that specify the location of files to be used within a project. For example, header include paths or paths specifying which source files need to be compiled for a given application.
Dependent source files may also be affected. For example if it is a header file whose name or location is being changed, all source files that include that header file must be modified to refer to the new location/name.
Moving files that have only one or two other dependent files is reasonably
trivial. However, once a source code module has many dependents (a property
that is highly desirable in a reuse environment), moving or renaming
a file becomes prohibitively time consuming. Thus, the organization
of the source code repository is extremely important when reusing software.
Unfortunately, copying a source file and using it in another context
is a common practice within the software industry, that is frequently termed
"software reuse". However, since this technique does not meet the standards
defined here for software reuse, the terms "port" or "copy"
will be used to refer to this technique.
Like any tool, conditional compilation has its place. For example, as a mechanism for ensuring that a file is included only once for a given compilation unit. However, for the purposes of software reuse, conditional compilation is usually a sign that there is a need to examine the source code for abstraction opportunities. Typically, interfaces can be defined and the appropriate implementation used by the project at compile and link time rather than during pre-processing.