Skip to content

Conversation

@tahonermann
Copy link
Contributor

Clang's current documentation for the CPATH environment variable states that paths it specifies are added as system header search paths. That documentation has been in place and incorrect since it was added in 2009 (via this commit). The actual behavior (see here) is that such paths are treated as though they were passed via -I options at the end of the driver command line and are thus added as non-system (user) header search paths; that has been the behavior since at least 2011 (see this commit. Clang's behavior is consistent with gcc as documented at https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-CPATH. This change aligns Clang's documentation with the behavior actually observed. Additional editorial changes are included to clarify that the related C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH, and OBJCPLUS_INCLUDE_PATH environment variables specify additional paths that are treated as system header search paths (in contrast to CPATH).

@tahonermann tahonermann self-assigned this Feb 27, 2025
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Feb 27, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 27, 2025

@llvm/pr-subscribers-clang

Author: Tom Honermann (tahonermann)

Changes

Clang's current documentation for the CPATH environment variable states that paths it specifies are added as system header search paths. That documentation has been in place and incorrect since it was added in 2009 (via this commit). The actual behavior (see here) is that such paths are treated as though they were passed via -I options at the end of the driver command line and are thus added as non-system (user) header search paths; that has been the behavior since at least 2011 (see this commit. Clang's behavior is consistent with gcc as documented at https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-CPATH. This change aligns Clang's documentation with the behavior actually observed. Additional editorial changes are included to clarify that the related C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJC_INCLUDE_PATH, and OBJCPLUS_INCLUDE_PATH environment variables specify additional paths that are treated as system header search paths (in contrast to CPATH).


Full diff: https://github.com/llvm/llvm-project/pull/129113.diff

1 Files Affected:

  • (modified) clang/docs/CommandGuide/clang.rst (+8-7)
diff --git a/clang/docs/CommandGuide/clang.rst b/clang/docs/CommandGuide/clang.rst
index ca8176f854729..dc8ee3dacf895 100644
--- a/clang/docs/CommandGuide/clang.rst
+++ b/clang/docs/CommandGuide/clang.rst
@@ -733,16 +733,17 @@ ENVIRONMENT
 
 .. envvar:: CPATH
 
-  If this environment variable is present, it is treated as a delimited list of
-  paths to be added to the default system include path list. The delimiter is
-  the platform dependent delimiter, as used in the PATH environment variable.
-
-  Empty components in the environment variable are ignored.
+  This environment variable specifies additional header file search paths which
+  behave as if they were specified with the :option:`-I` option at the end of
+  the driver command line. Paths are delimited by the platform dependent
+  delimiter as used in the :envvar:`PATH` environment variable. Empty components
+  in the environment variable are ignored.
 
 .. envvar:: C_INCLUDE_PATH, OBJC_INCLUDE_PATH, CPLUS_INCLUDE_PATH, OBJCPLUS_INCLUDE_PATH
 
-  These environment variables specify additional paths, as for :envvar:`CPATH`, which are
-  only used when processing the appropriate language.
+  These environment variables specify additional system header file search
+  paths to be used when processing the corresponding language. Search paths are
+  delimited as for the :envvar:`CPATH` environment variable.
 
 .. envvar:: MACOSX_DEPLOYMENT_TARGET
 

…riable.

Clang's current documentation for the `CPATH` environment variable states that
paths it specifies are added as system header search paths. The actual behavior
is that such paths are treated as though they were passed via `-I` options at
the end of the driver command line and are thus added as non-system (user)
header search paths. Clang's behavior is consistent with gcc as documented at
https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html#index-CPATH.
This change aligns Clang's documentation with the behavior actually observed.
Additional editorial changes are included to clarify that the related
`C_INCLUDE_PATH`, `CPLUS_INCLUDE_PATH`, `OBJC_INCLUDE_PATH`, and
`OBJCPLUS_INCLUDE_PATH` environment variables specify additional paths that are
treated as system header search paths (in contrast to `CPATH`).
behave as if they were specified with the :option:`-I\<directory\>` option at
the end of the driver command line. Paths are delimited by the platform
dependent delimiter as used in the ``PATH`` environment variable. Empty
components in the environment variable are ignored.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize this is pre-existing, but 'empty components' is a little awkward? Anyone got a thesaurus for this :D ? Perhaps 'empty directories' (though perhaps inaccurate?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also found that wording a little awkward, but I wasn't able to come up with anything better. We could say something like "empty entries in the delimited path list are ignored". Is that an improvement? I dunno.

Separately, and interestingly, gcc treats such empty components/entries as if "." were specified. I find that horrifying and am glad that clang doesn't emulate that behavior! We could document this deviation from gcc behavior though.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'entries' is actually way nicer I think, I'd prefer that instead. components makes me wonder whether that means parts of a path/etc.

Documenting that deviation is a good idea too IMO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @erichkeane, I switched to "entries" and that does read better. I also documented the deviation from GCC as discussed. But then I discovered #49742, validated that it was correct, and instead fixed another case of blatantly incorrect documentation. Clang does do the awful thing that GCC does.

In the Clang Language WG meeting yesterday, we briefly discussed whether, e.g., paths set by C_INCLUDE_PATH are used when compiling for C++. I tested all of the environment variables with both Clang and GCC across all of C, C++, Objective-C, and Objective-C++. GCC consistently applies paths only with the associated language (e.g., paths nominated by C_INCLUDE_PATH are not used for C++, Objective-C, or Objective-C++ compilation). Clang does similarly with one exception for which there is a FIXME comment in the relevant code (see here). I chose not to document that deviation due to the FIXME comment.

Finally, I observed that GCC doesn't document the OBJCPLUS_INCLUDE_PATH environment variable. So I checked whether GCC supports it and found that it does and has since at least 2003 and filed a documentation bug for GCC maintainers (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119146).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For historical reference, that FIXME was introduced by 559865c by @d0k.

@tahonermann tahonermann requested a review from erichkeane March 6, 2025 17:31
@tahonermann tahonermann merged commit a907246 into llvm:main Mar 6, 2025
7 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants