3

I am wondering what is the recommended folder structure for a C project. I read several posts about using src, include, test, build folders. But what if I want to structure the project in modules?

Should I use a structure like:

src/
    core/
        main.c
        sysinit.c
        interrupts.c
        ...
    module1/
        file1_1.c
        ...
    module2/
        file2_1.c
        ...

include/
    core/
        main.h
        sysinit.h
        interrupts.h
        ...
    module1/
        file1_1.h
        ...
    module2/
        file2_1.h
        ...

or like this:

core/
    src/
        main.c
        sysinit.c
        interrupts.c
    include/
        main.h
        sysinit.h
        interrupts.h
        ...
module1/
    src/
        file1_1.c
        ...
    include/
        file1_1.h
        ...
module2/
    src/
        file2_1.c
        ...
    include/
        file2_1.h
        ...

If the previous two patterns are not recommended, what are the conventions/commonly used patterns?

4
  • For folder structure, there is not really a difference between embedded and other types of projects. Much of it is a matter of what feels right for your project. Sep 29 '18 at 8:42
  • @BartvanIngenSchenau I edited my question according to your comment by removing "embedded".
    – Mat.R
    Sep 29 '18 at 8:53
  • Questions about folder structure always have the same answer: use the folder structure that is most useful for you, your application and your team (in whatever ways you define "useful"). Sep 29 '18 at 18:46
  • The include/ directory is for headers for installed libraries. If you don't have any installed libraries, then you shouldn't have it. The header files for the source files goes in the same directory. Oct 3 '18 at 12:31
3

Both is possible, so if you find any reason to use one approach instead of the other, go ahead.

I would use the second approach (top level directories are core, module1, module2, etc.) if the different modules are somewhat useful on their own (except maybe the "core" module, if every other module depends on it.)

If all modules depend on each other, and the individual modules are useless without the other modules, use the first approach (top level directories are src, include, etc.)

Example 1:

You have 4 modules for a small offline customer relationship managment (CRM) system:

  • "infrastructure" - it contains logging, basic data types, and some functions to abstract away platform dependencies
  • "domain" - it contains business logic
  • "gui" - it contains the gui, and builds on top of "infrastructure" and "domain"
  • "cli" - it contains a command line interface, also builds upon "infrastructure" and "domain".

In this case, I would use the first approach (top level directories are src, include, etc.) The different parts cannot really be used separately, they are all connected. Maybe the "infrastructure" folder compiles without the other folders, but how can you use the resulting.. library?

Example 2:

You have 5 modules for a document management system that reads arbitrary files and converts them to a common format:

  • base - contains the basic data types and platform support
  • spreadsheets - allows parsing of excel and openoffice spreadsheets
  • pdfparser - can read PDF and PS files
  • imagescanner - reads JPG, PNG and TIFF files to do OCR with them
  • conversiontools - can convert 90 different file formats to more common supported file formats

In this case I would use the second approach (top level directories are core, module1, module2, etc.) - All modules can be used standalone and be useful (except for the "base" module, obviously.) The different modules are somewhat decoupled, and putting them into separate directories clearly communicates to everyone that this is a basic design decision.


When making up examples, it is good to really make up realistic examples. This makes the answer much more obvious. Bad examples are so common, though. A real project has never modules named "module1" and "module2". Without knowing what the modules are, it is not possible to know wether approach 1 or approach 2 is better.

1
  • By using names like "module1", "module2" you gave me a general answer covering both cases. If I would use specific names, maybe I would not get a general answer but a specific one. My question was general. Anyway, I am satisfied with your answer. I will accept it.
    – Mat.R
    Oct 1 '18 at 8:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.