[CMake] Issue with check_include_file() and GL/glxproto.h

Michael Hertling mhertling at online.de
Thu Nov 10 22:13:20 EST 2011


On 11/10/2011 11:22 PM, Eric Noulard wrote:
> 2011/11/10 GOUJON Alexandre <ale.goujon at gmail.com>:
>> Hi,
>>
>> It all started when I tried compiling Piglit [1] : cmake checked all the
>> dependencies, didn't complain and generated Makefiles but doing 'make'
>> caused an error because a header was missing.
>>
>> So I proposed myself to write a patch and add the check.
>> But the following didn't work :
>>
>> check_include_file(GL/glxproto.h HAVE_GL_GLXPROTO_H)
>> if (NOT HAVE_GL_GLXPROTO_H)
>>    message(FATAL_ERROR "GL/glxproto.h required. On Ubuntu, you need the
>> x11proto-gl-dev package.")
>> endif (NOT HAVE_GL_GLXPROTO_H)
>>
> [...]
> 
>> I'm not really familiar with CMake so I may have missed something.
>> What I understand is that check_include_file() tries to compile a test which
>> includes GL/glxproto.h.
>> It seems another header is needed prior to using GL/glxproto.h.
> 
> If this is the case then it is a "GL/glxproto.h" design mistake
> not CMake mistake.

Absolutely, try to compile the following program by hand; it's
the same the CHECK_INCLUDE_FILE() macro tries to compile, too:

#include <GL/glxproto.h>
int main(void){return 0;}

It will fail with the same error message, i.e. the GL/glxproto.h header
is not self-sufficient; if intentionally or accidentally, I don't know.
It's this failure that makes CHECK_INCLUDE_FILE() report the header as
non-existent, or better as "not compilable".

> Until now I did never cross a "public" C or C++ header that needs
> a previous include.
> 
> A public include file should always include its needed dependencies, right?

Yes, and the #include directives should always be ordered from most-to-
least dependent, as this helps to reveal hidden non-self-sufficiencies
of the included headers.

> Or may be I'm missing some particular use case?

There might be rare exceptions, e.g. a header X.h which needs either
A.h or B.h but cannot decide by itself, so the user must decide if
A.h or B.h has to be included before X.h. Anyway, I don't know an
example, but any occurrence of this kind should be documented.

>> From my "user" point of view, this approach is quite strange because the
>> header is present but "not found".
>> If you want to check the usability of the file, I think a comment or a
>> better macro name would help.
> 
> This is true but the documentation tells you more about the macro
> cmake --help-module CheckIncludeFile
> 
> says
> "an optional third argument is the CFlags to add to the compile line or
>        you can use CMAKE_REQUIRED_FLAGS"
> 
> which clearly states that it does a compilation.

Indeed, CHECK_INCLUDE_FILE() means: Check if a header is *functional*.

> If you just want to find a file then may be,
> 
> find_file
> 
> cmake command would be a better choice.
> 
>> And, could you add a check like
>> IF(${VARIABLE}) message(FATAL_ERROR "${VARIABLE} already defined :
>> aborting") ENDIF(${VARIABLE})
>> ?
> 
> The thing you want is probably
> 
> if(DEFINED VARIABLE)
>    message(FATAL_ERROR "VARIABLE already defined : <${VARIABLE}> aborting")
> endif()
> 
> 
>> That is, explicitly abort the macro instead of letting the user testing a
>> variable previously defined and not modified by check_include_file.
> 
> I think it's not the responsability of check_include_file to do such job
> but you can do that in your CMakeLists.txt

With FIND_FILE/PATH() looking for a header, the user must have the
possibility to make them no-ops by presetting the result variable,
so these functions must not overwrite a valid path. However, with
CHECK_INCLUDE_FILE(), the user can't "define" a header as working;
thus, there is no need to protect an already defined variable from
being overwritten, IMO. Moreover, the user must have the chance to
reuse the same variable for this purpose again without having the
configuration terminate. OTOH, one usually uses an individually
named variable for each header, e.g. HAVE_GL_GLXPROTO_H, as you
do, which is most certainly not reused for anything at all.

Regards,

Michael

>> IF("${VARIABLE}" MATCHES "^${VARIABLE}$") fails : is it intended ?
> 
> I do not understand
> In which case does it fail?


More information about the CMake mailing list