Question

For simplicity, let's say I have the following C project structure:

src/
  utils/
    logger.c
    logger.h
   main.c
   secondary_component.c

main.c starts with:

#include "utils/logger.h"

I would like to keep the code and its structure as-is, but stub out logger.c, logger.h and avoid compiling secondary_component.c (i.e. only use the subset of main and logger). For instance, instead of the regular logger.c writing to a file, the stubbed version would include a simple printf.

My attempted solution: create an extra folder stubbed_src/utils and place my new logger.c, logger.h inside that folder. Then, I perform:

clang -iquote stubbed_src -iquote src -o main_proj main.c stubbed_src/utils/logger.c

The goal is that when clang sees the #include logger.h in main.c, it will first look at the stubbed_src folder and find it (and thereby ignore the original src/utils/logger.h). Unfortunately, clang always looks at the current folder first (i.e. it looks for utils/logger.h starting at src, where main.c is located) and only if it doesn't find it will it then looks at the iquote folders. In which case, it will always stop when it finds the implementation in src/utils.

There used to be a clang command line workaround which disabled this current working directory behavior, but it has since been deprecated.

If I were willing to change main.c's #include to be an angle bracketed #include, then using -I would also solve the problem since -I has no such restriction regarding the current directory. But this would be an improper usage of angle brackets, and also I'm unable to change main.c in this case.

Ideally, my stubbed versions of logger.c, logger.h would be much reduced in size and only implement functions used in main.c. For instance, I would like to discard any logger functions called by secondary_component.c since I only want to compile main.c. In addition, those extraneous functions called by secondary_component.c introduce their own #include requirements into the original logger files and I'm trying to avoid compiling those extra #includes. I would like to be able to simply compile main.c and have it work with stubbed logger functions and be able to avoid compiling any extra files.

Any other suggestions on how to use an alternative/stubbed out implementation of logger.c, logger.h?

Was it helpful?

Solution

The normal practice when mocking functions in C (or otherwise using different implementations) is to use different .c source files in your build process. Normally, header files are not replaced.

If header files really must be replaced, then the #include "header.h" include directive must not refer to a file that can be found directly from the current source's directory. The C standard specifies that the #include "..." form must always first look in the current directory before starting to look into other paths.

Licensed under: CC-BY-SA with attribution
scroll top