Skip to content

[Clang][Docs][NFC] Correct documentation for the CPATH environment variable #129113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 6, 2025

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
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
…riable (llvm#129113)

Clang's prior documentation for the `CPATH` environment variable stated 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.

The documentation additionally claimed that empty path entries in the `CPATH`
environment variable are ignored. This was also incorrect; Clang treats empty
entries as nominating the compiler's current working directory; as though `.`
was specified.

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`).

Fixes issue llvm#49742.
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