A way to include a lot of directories

Hello, everyone.

First, I am using CMake 3.27 from MingW 13.2.0, Windows 10 X64, VSCode 1.80.2, CMake Tools Extension v1.15.27

I have a project with like less than 1000 source & header files. About 150-160 directories. And I need all that to build together in one project.
The issue is that when I am including a .rc file in my project, I having an issue, a fatal error “Too long command line”.
So, this is my CmakeLists.txt content

cmake_minimum_required(VERSION 3.27)

#----------COMPILER SETUP--------------

set(CMAKE_C_COMPILER "C:/software/mingw64/bin/gcc.exe")
set(CMAKE_CXX_COMPILER "C:/software/mingw64/bin/g++.exe")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wall -fmax-errors=5 -Werror-implicit-function-declaration")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -fmax-errors=5")

project(Vima_WX)

#----------CKM DEBUG GRID--------------

option(CKM_DEBUG_GRID "Build debug ckm files" ON)

if(CKM_DEBUG_GRID)
    add_definitions(-D__CKM_DEBUG_MODE__)
endif()

#----------INCLUDE .CMAKE FILES--------
include(fpo_src.cmake)
include(slpo_src.cmake)   
include(target_src.cmake)
include(open_gl.cmake)
include(wxWidgets.cmake)

add_compile_definitions(-D__MFI_FLIGHT_IMITATION -D_WINDOWS -D_DEBUG -D_CPT_SECURE_NO_WARNING -D__WXMSW__ -D_UNICODE)

add_executable(${PROJECT_NAME} WIN32 ${TRGT_CPP_FILES} ${FPO_C_FILES} ${SLPO_C_FILES} ${RC_FILE})

target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} ${GLEW_LIBS} ${wxWidgets_LIBRARIES} ${SRC_LIBRARY})
target_compile_definitions(${PROJECT_NAME} PRIVATE wxUSE_DPU_AWARE_MANIFEST=2)

add_dependencies(${PROJECT_NAME} COPY_RESOURCES)

When I’m configuring my project with CMake in VSCode I have this output:

[proc] Executing command: C:/software/mingw64/bin/cmake.exe --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_CXX_COMPILER:FILEPATH=C:/software/mingw64/bin/g++.exe -DCMAKE_C_COMPILER:FILEPATH=C:/software/mingw64/bin/gcc.exe -SD:/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/cmake_configs -Bd:/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/build -G "MinGW Makefiles"
[cmake] Not searching for unused variables given on the command line.
[cmake] -- The C compiler identification is GNU 13.2.0
[cmake] -- The CXX compiler identification is GNU 13.2.0
[cmake] -- Detecting C compiler ABI info
[cmake] -- Detecting C compiler ABI info - done
[cmake] -- Check for working C compiler: C:/software/mingw64/bin/gcc.exe - skipped
[cmake] -- Detecting C compile features
[cmake] -- Detecting C compile features - done
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Check for working CXX compiler: C:/software/mingw64/bin/g++.exe - skipped
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done
[cmake] -- Found OpenGL: opengl32   
[cmake] -- Found wxWidgets: // There are just wxWidgets library paths in my project
[cmake] -- Configuring done (1.8s)
[cmake] -- Generating done (0.2s)
[cmake] -- Build files have been written to: D:/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/build

I have a project directory and hierarchy like this:
Project folder
–FPO
–SLPO
–Shell
--------CMake
-------------cmake_configs
--------------------CMakeLists.txt
--------------------Other .cmake files
-------------res
-------------target
--------------------some .cpp, .h
--------------------some directories
--------------------lib
------------------------wxWIdgets
------------------------glew

So when I’m trying to build my project, everything builds up great until coming to ${RC_FILE}:

[build] Starting build
[proc] Executing command: C:/software/mingw64/bin/cmake.exe --build d:/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/build --config Debug --target all -j 16 --
[build] [  0%] Built target COPY_RESOURCES
[build] [  0%] Building RC object CMakeFiles/Vima_WX.dir/D_/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/res/project.rc.obj
[build] Too long command line
[build] C:\software\mingw64\bin\windres.exe: preprocessing failed.
[build] mingw32-make[2]: *** [CMakeFiles\Vima_WX.dir\build.make:6209: CMakeFiles/Vima_WX.dir/D_/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/res/project.rc.obj] Error 1
[build] mingw32-make[1]: *** [CMakeFiles\Makefile2:110: CMakeFiles/Vima_WX.dir/all] Error 2
[build] mingw32-make: *** [Makefile:90: all] Error 2
[proc] The command: C:/software/mingw64/bin/cmake.exe --build d:/Users/user_name/Desktop/cmake_test/project_name/shell/CMake/build --config Debug --target all -j 16 -- exited with code: 2
[driver] Build completed: 00:00:01.743
[build] Build finished with exit code 2

The issue stays until

include(fpo_src.cmake)

presents in my project, because when I’m commenting this line everything builds up okay, even .rc file, however, source files from this .cmake file are necessary to my project.

Here some content of this fpo_src.cmake file

set(FPO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../FPO")
set(FPO_ONE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../FPO/part_one")
set(FPO_TWO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../FPO/part_two")

file(GLOB_RECURSE FPO_C_FILES ${FPO_PATH}/*.c)
file(GLOB_RECURSE FPO_H_FILES ${FPO_PATH}/*.h)

include_directories( ... - here are paths to 90 different directories
i.e. ${FPO_ONE_PATH}/directory_one
	 ${FPO_ONE_PATH}/directory_one/abc
	 ${FPO_ONE_PATH}/directory_one/abd
	 
	 {FPO_ONE_PATH}/directory_two/ddd
	 etc...)

I’m thinking that the issue with “Too long command line” stays cause of a lot of including directories passed to windres compiler.

I’ve tried to make fpo_src, slpo_scr, target_src are 3 different libraries and add them in one INTERFACE library, however, this didn’t work, cause one source files have dependency on another header files from second library, for example, source.cpp from FPO includes header.h from SLPO and so on.
So I’m running out of solutions, maybe is there some way to make this work?

You might be able to do something like:

add_library(justrc OBJECT foo.rc)
target_link_libraries(needsrc PRIVATE justrc)

Note that justrc will need to be declared outside of any of those include_directories call’s scopes (either before it in the directory or in another subdir tree).

This issue is of interest here too:

https://gitlab.kitware.com/cmake/cmake/-/issues/16171

But how was the issue you mentioned solved there?
I’ll try the code you’ve provided in a few days at my work, thank you!

The issue just describes why this is a problem. The solution of the OBJECT library is to create the target outside of a place where there are dozens of include directories that don’t matter for it.

So, if I’m placing my .rc file in CMAKE_SOURCE_FOLDER it would be okay? I’ve demonstrated files hierarchy of my project above in the post.

It just needs to be outside of the effects of those massive include_directories calls. Probably as the first include(rc_src.cmake) would suffice.

Though if you used target_include_directories instead they would be target-local and order wouldn’t matter.

But if I’m using target_include_directories I should define a target. However I have no any targets defined in .cmake files, there are just include_directories because fpo_src.cmake, slpo_src.cmake, trgt_src.cmake have dependencies on each other. So I’ll try to make a different .cmake file with including there rc object like you said. I’ll look into that tomorrow.

So I made another .cmake file, named rc_file.cmake. I placed that at my current CMakeLists.txt folder. include(rc_file.cmake) was above other includes)
rc_file.cmake content

set(RC_FILE ${CMAKE_SOURCE_DIR}/…/res/project.rc)

add_library(RC_SRC OBJECT ${RC_FILE})

I wrote

target_link_libaries(${PROJECT_NAME$} PRIVATE ${RC_SRC})

in my CMakeLists.txt, however still got the same issue.

I’m thinking that I’m not quite understand what you mean by including .rc file separately from other include_directories(…) commands. Should I make another subdirectory with CMakeLists.txt inside for .rc file or what?
Probably I wouldn’t be able to change all my include_directories(…) in my other .cmake files for target_include_directories because I’ve not specified target, like FPO, SLPO, TARGET - they are all have dependencies on each other.
And OpenGL and wxWidgets needs to be there as well. I’m a little bit confused with all that, to be honest.

In your first example by needsrc you meant my main target?

I found an issue with my problem for Too long command line. This lines fixed .rc compiling:

if(MINGW)
  SET(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> -O coff -DwxUSE_DPI_AWARE_MANIFEST=2 -I \"${wxWidgets_ROOT_DIR}/include\" -i <SOURCE> -o <OBJECT>")
endif(MINGW)