(defun internal--c-header-file-path ()
"Return search path for C header files (a list of strings)."
(delete-dups
- (let ((base '("/usr/include" "/usr/local/include")))
- (cond ((or (internal--gcc-is-clang-p)
- (and (executable-find "clang")
- (not (executable-find "gcc"))))
- ;; This is either macOS, or a system with clang only.
+ ;; We treat MS-Windows/MS-DOS specially, since there's no
+ ;; widely-accepted canonical directory for C include files.
+ (let ((base (if (not (memq system-type '(windows-nt ms-dos)))
+ '("/usr/include" "/usr/local/include")))
+ (call-clang-p (or (internal--gcc-is-clang-p)
+ (and (executable-find "clang")
+ (not (executable-find "gcc"))))))
+ (cond ((or call-clang-p
+ (memq system-type '(windows-nt ms-dos)))
+ ;; This is either macOS, or MS-Windows/MS-DOS, or a system
+ ;; with clang only.
(with-temp-buffer
(ignore-errors
- (call-process (if (internal--gcc-is-clang-p) "gcc" "clang")
+ (call-process (if call-clang-p "clang" "gcc")
nil t nil
"-v" "-E" "-"))
(goto-char (point-min))
(pos-bol)))
(while (search-forward "(framework directory)" nil t)
(delete-line))
- (append base
- (reverse
- (split-string (buffer-substring-no-properties
- (point-min) (point-max)))))))
+ ;; "gcc -v" reports file names with many "..", so we
+ ;; normalize it.
+ (or (mapcar #'expand-file-name
+ (append base
+ (split-string (buffer-substring-no-properties
+ (point-min) (point-max)))))
+ ;; Fallback for whedn the compiler is not available.
+ (list (expand-file-name "/usr/include")
+ (expand-file-name "/usr/local/include")))))
;; Prefer GCC.
((let ((arch (with-temp-buffer
(when (eq 0 (ignore-errors
(ert-deftest subr-tests-internal--c-header-file-path ()
(should (seq-every-p #'stringp (internal--c-header-file-path)))
- (should (member "/usr/include" (internal--c-header-file-path)))
+ (should (locate-file "stdio.h" (internal--c-header-file-path)))
+ (or (memq system-type '(windows-nt ms-dos))
+ (should (member "/usr/include" (internal--c-header-file-path))))
(should (equal (internal--c-header-file-path)
(delete-dups (internal--c-header-file-path))))
;; Return a meaningful result even if calling some compiler fails.
(cl-letf (((symbol-function 'call-process)
(lambda (_program &optional _infile _destination _display &rest _args) 1)))
(should (seq-every-p #'stringp (internal--c-header-file-path)))
- (should (member "/usr/include" (internal--c-header-file-path)))
+ (should (member (expand-file-name "/usr/include")
+ (internal--c-header-file-path)))
(should (equal (internal--c-header-file-path)
(delete-dups (internal--c-header-file-path))))))
(lambda (_program &optional _infile _destination _display &rest args)
(when (equal (car args) "-print-multiarch")
(insert "\n") 0))))
- (should (member "/usr/include" (internal--c-header-file-path))))
+ (should (member (expand-file-name "/usr/include")
+ (internal--c-header-file-path))))
;; Handle single values of "gcc -print-multiarch".
- (cl-letf (((symbol-function 'call-process)
+ (cl-letf ((system-type 'foo)
+ ((symbol-function 'call-process)
(lambda (_program &optional _infile _destination _display &rest args)
(when (equal (car args) "-print-multiarch")
(insert "x86_64-linux-gnu\n") 0))))
- (should (member "/usr/include/x86_64-linux-gnu" (internal--c-header-file-path)))))
+ (should (member (expand-file-name "/usr/include/x86_64-linux-gnu")
+ (internal--c-header-file-path)))))
(ert-deftest subr-tests-internal--c-header-file-path/clang-mocked ()
;; Handle clang 15.0.0 output on macOS 15.2.
# 1 \"<built-in>\" 2
# 1 \"<stdin>\" 2")
0)))
- (should (member "/usr/include" (internal--c-header-file-path)))
- (should (member "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include"
+ (should (member (expand-file-name "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include")
(internal--c-header-file-path)))))
(provide 'subr-tests)