Can the C preprocessor be used to tell if a file exists?

后端 未结 9 1687
眼角桃花
眼角桃花 2020-11-30 22:21

I have a very large codebase (read: thousands of modules) that has code shared across numerous projects that all run on different operating systems with different C++ compil

相关标签:
9条回答
  • 2020-11-30 22:44

    The preprocessor itself cannot identify the existence of files but you certainly can use the build environment to do so. I'm mostly familiar with make, which would allow you to do something like this in your makefile:

    ifdef $(test -f filename && echo "present")
      DEFINE=-DFILENAME_PRESENT
    endif
    

    Of course, you'd have to find an analog to this in other build environments like VisualStudio, but I'm sure they exist.

    0 讨论(0)
  • 2020-11-30 22:45

    Generally this is done by using a script that tries running the preprocessor on an attempt at including the file. Depending on if the preprocessor returns an error, the script updates a generated .h file with an appropriate #define (or #undef). In bash, the script might look vaguely like this:

    cat > .test.h <<'EOM'
    #include <asdf.h>
    EOM
    if gcc -E .test.h
     then
      echo '#define HAVE_ASDF_H 1' >> config.h
     else 
      echo '#ifdef HAVE_ASDF_H' >> config.h
      echo '# undef HAVE_ASDF_H' >> config.h
      echo '#endif' >> config.h
     fi
    

    A pretty thorough framework for portably working with portability checks like this (as well as thousands others) is autoconf.

    0 讨论(0)
  • 2020-11-30 22:48

    Contrary to some claims here and on the internet, Visual Studio 2015 does NOT support the __has_include feature - at least according to my experience. Tested with Update 3.

    The rumors may have arisen from the fact that VS 2017 is also referred to as "Version 15"; VS 2015 is instead referred to as "Version 14". Support for the feature seems to have been officially introduced with "Visual Studio 2017 Version 15.3".

    0 讨论(0)
  • 2020-11-30 22:53

    Another possibility: populate a directory somewhere with zero-length versions of all of the headers you wish to optionally include. Pass a -I argument to this directory as the last such option.

    The GCC cpp searches its include directories in order, if it finds a header file in an earlier directory it will use it. Otherwise, it will eventually find the zero-length file, and be happy.

    I presume that other cpp implementations also search their include directories in the order specified.

    0 讨论(0)
  • 2020-11-30 22:57

    Create a special folder for missing headers, and make that folder to be searched last
    (that is compliler specific - last item in "INCLUDES" environment variable, something like that)

    Then if some header1.h can be missing, create in that folder a stub

    header1.h:

    #define header1_is_missing
    

    Now you can always write

    #include <header1.h>
    #ifdef header1_is_missing
    
       // there is no header1.h 
    
    #endif
    
    0 讨论(0)
  • 2020-11-30 22:58

    You could have a pre-build step run that generates an include file that contains a list of #defines that represent the names of the files existing in the current directory:

    #define EXISTS_FILE1_C
    #define EXISTS_FILE1_H
    #define EXISTS_FILE2_C
    

    Then, include that file from within your source code, and then your source can test the EXISTS_* defines to see whether a file exists or not.

    0 讨论(0)
提交回复
热议问题