0

First of all, I don't know what I should call it, module, component, or library are all fitting for me, but gave all mixed results trying to figure this out.

Problem

I am working on a project in C, where the amount of files grew quite large, so I wanted to split it up a bit, both for ordering and make it look less cluttered.
I want a file structure that looks something like this:

root
├modules
│├module_foo
││├include
│││├module_foo_a.h
││││...
│││└module_foo_z.h
││├private_include
│││├a.h
││││...
│││└z.h
││├source
│││├module_foo_a.c
││││...
│││└module_foo_z.c
││└module_foo.h
│└module_bar
│ ├include
│ │├module_bar_a.h
│ ││...
│ │└module_bar_z.h
│ ├private_include
│ │├a.h
│ ││...
│ │└z.h
│ ├source
│ │├module_bar_a.c
│ ││...
│ │└module_bar_z.c
│ └module_bar.h
├main.c
├main.h
└CMakeLists.txt

Clarification

The goal of this would be that the private_include folders would be inaccessible by other modules and main, and the different modules would need to work (fairly) independent. Modules can include other modules, but this would need to be defined explicitly.
I also would like the CMake to be easy to modify, ideally only a single/couple line(s) to change for the modules used.

Pre research

As mentioned above, I have searched already, but the CMake documentation isn't meant for the people who just want to do some C coding.
When I searched for modules, almost all results were about the C++ modules and how to integrate them into CMake.
Components mostly gave results about the COMPONENTS keyword.
Library had the most results, however it still requires me to use #include "modules/module_foo/include/module_foo_a.h" from main, or #include "../../module_bar/include/module_bar_a.h" from module foo. The goal would be to have in both instances #include "module_foo_a.h". Subdirectory isn't what I am looking for I believe, because that still makes it part of the root project. This is not what I want.

For the modules I currently have

project(foo)

add_library(${PROJECT_NAME} STATIC source/module_foo_a.c include/module_foo_a.h)

include_directories(private_include include)

link_libraries(bar)

target_include_directories(${PROJECT_NAME} INTERFACE include)

target_link_libraries(${PROJECT_NAME} PRIVATE bar)

I have included the header files in the add_library because one source I found said it helped with IDE's. I don't remember why I made the target_include_directories interface, or the target_link_libraries private.

For my main CMake I have

project(foobar)

include_directories(include)

add_executable(${PROJECT_NAME} source/main.c)

target_link_libraries(${PROJECT_NAME} foo bar)

I believe I need to include bar again because of the private link in the module.

I don't even know if what I am searching for is actually possible, but I would really like to work with it this way, or close to this.

edit

Before I tried to add modules the folder structure looked something like this:

root
├include
│├foo_a.h
││...
│├foo_z.h
│├bar_a.h
││...
│├bar_z.h
│└main.h
└source
 ├foo_a.c
 │...
 ├foo_z.c
 ├bar_a.c
 │...
 ├bar_z.c
 └main.c

This got very cluttered very quickly, hence why I want to change to modules.

As stated in my comment, the part that I have put above is what I have now. This does not make the modules easy to work with, as they don't provide short include names, both from outside the modules (main) and other modules (bar).

The little bits that I understand from CMake is that the functions have a 'normal' variant and a 'target' variant.
'Normal' is just for the current project, and 'target' is meant to also allow other CMakes to use those specified files/folders. This should however not work for the private_include folders, as they are only to be known to the module itself.
If I understand it correctly, including private_include in the 'target' variant would make it possible that you would do #include "a.h" or #include "private_include/a.h" in main, which is not what I want.

  • What problems do you face with your solution? Do you get error messages from the configuration or build step? I suggest to [edit] the question and create a [mre]. Then it will be possible to actually run `cmake` and test a proposed solution. – Bodo Dec 06 '22 at 16:44
  • The problem with the solution is that I do not yet have a solution, the thing that I currently have has no use in my program (look at the include paths) and it doesn't work differently from just putting everything in root. – ThunderSphun Dec 06 '22 at 17:35
  • Please add all requested information or clarification to the question. To me, your description is not clear enough. Your claim that "it doesn't work differently from just putting everything in root" depends on what exactly you put into your project's root directory. Using `target_include_directories` with `INTERFACE`, `PUBLIC` or `PRIVATE` instead of `include_directories` and the same for the libraries might help. It is difficult to do for a theoretical description. I again suggest to [edit] the question and create a [mre], i.e. all files for minimal modules and main program. – Bodo Dec 06 '22 at 17:50

0 Answers0