1

I'm observing strange CMake behavior. If my project has a header file included to all sources using -include inc.h by means of ADD_COMPILE_OPTIONS(-include inc.h) command then changes to the header never detected. Meaning I can change the header, but CMake will never try to recompile the main.cpp. Am I doing something wrong? Is it a CMake bug? Any workaround?

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
PROJECT(include_test)

SET(CMAKE_CXX_STANDARD 17)

INCLUDE_DIRECTORIES(.)
ADD_COMPILE_OPTIONS(
        -include inc.h
)
ADD_EXECUTABLE(include_test main.cpp)

main.cpp

#include <iostream>

int main()
{

    foo a;
    std::cout << a.bar << std::endl;
    return 0;
}

inc.h

struct foo
{
    int bar = 1;
    double baz = 3;
};

EDIT001: As @Oliv suggests, when trying to use something like SET_SOURCE_FILES_PROPERTIES(main.cpp PROPERTY OBJECT_DEPENDS inc.h) Of course it wouldnt work because dependency should be a target and not a file on which the cpp depends so I added following:

ADD_CUSTOM_TARGET(HeaderChanged
                  DEPENDS
                  inc.h
                  COMMENT "Checking if include file has changed")

SET_SOURCE_FILES_PROPERTIES(main.cpp PROPERTY OBJECT_DEPENDS HeaderChanged)

which still results in make[2]: *** No rule to make target 'HeaderChanged', needed by 'CMakeFiles/include_test.dir/main.cpp.o'. Stop. despite the HeaderChanged target exists

kreuzerkrieg
  • 3,009
  • 3
  • 28
  • 59
  • Just don't use `-include`? – Alan Birtles Oct 07 '18 at 06:12
  • I think that in your specific example, inc.h is not recognized as a project source or header file since you do not explicitly include it in main.cpp. Thus, every time you touch inc.h you should clean and make again. – Gergely Nyiri Oct 07 '18 at 07:14
  • @AlanBirtles, it is existing state and I cant change it – kreuzerkrieg Oct 07 '18 at 08:54
  • @GergelyNyiri It is quite obvious why it is not working if CMake does not have any special treatment for such a case. The question is what can be done now. – kreuzerkrieg Oct 07 '18 at 08:55
  • 1
    If you can not change the compile option, maybe you can add `inc.h` to [OBJECT_DEPENDS](https://cmake.org/cmake/help/v3.12/prop_sf/OBJECT_DEPENDS.html) source file property for each file that includes it. – Oliv Oct 07 '18 at 10:11
  • An other option would be to make a script that `touch` each source files to change their last modification time when `inc.h` is modified. It would be easy on linux, I don't know on other systems. – Oliv Oct 07 '18 at 10:16
  • OBJECT_DEPENDS sounds like a good idea, will check it. Touching files, on the other hand is horrifically ugly. – kreuzerkrieg Oct 07 '18 at 10:24
  • @Olive, It didnt work, question updated – kreuzerkrieg Oct 07 '18 at 13:54
  • OBJECT_DEPENDS should work, it isn't quite clear what you mean by *dependency should be a target and not a file on which the cpp depends*. – n. m. could be an AI Oct 07 '18 at 14:22
  • @n.m. How the full command should be? something like `SET_SOURCE_FILES_PROPERTIES(main.cpp PROPERTY OBJECT_DEPENDS inc.h)`? – kreuzerkrieg Oct 07 '18 at 14:24
  • Yes exactly this. – n. m. could be an AI Oct 07 '18 at 14:38
  • @n.m. then I get *** No rule to make target 'inc.h' – kreuzerkrieg Oct 07 '18 at 15:20
  • 1
    This means make sees the right rule but cannot find the file. You should specify a valid path to inc.h. – n. m. could be an AI Oct 07 '18 at 15:42
  • @n.m. you are right! Odd thing, nor "inc.h" neither "./inc.h" worked. Dont get it why, everything is in the same directory. Is the current dir when the CMake is executing is `CMAKE_CURRENT_BINARY_DIR` and not `CMAKE_CURRENT_LIST_DIR`? – kreuzerkrieg Oct 08 '18 at 04:40

1 Answers1

1

On your EDIT0001: You probably need to specify the entire path to inc.h such that the Makefile knows where to find it (since you're most likely doing an out of source build), i.e:

SET_SOURCE_FILES_PROPERTIES(main.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/inc.h)

Also note that the OBJECT_DEPENDS solution won't work for Visual Studio (neither does the flag -include). But in Visual Studio it was sufficient to add the ADD_COMPILE_OPTIONS(/FIinc.h) and it would automatically detect changes to inc.h.

J. Borgh
  • 51
  • 4