;;; --------------------------------------------------------------------- ;;; ;;; Auxiliary utilities for the proccpuinfo egg. ;;; ;;; These utilities aren't at all necessary for your typical egg, much ;;; less a C binding. They're just here to make the egg's installation ;;; attempt go a bit smoother than it otherwise would in case of an error. ;;; ;;; In particular, they are intended to be used to catch the case of ;;; Chicken being unable to find a header file that's required for ;;; the proper compilation of this egg. ;;; ;;; This is done using the (header-search ...) procedure, which is ;;; defined below. The rest of the procedures in this module just help ;;; it do its job. ;;; ;;; --------------------------------------------------------------------- ;;; ;;; Copyright (C) 2012 - Sergey Goldgaber ;;; ;;; This program is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU Affero General Public License as published by ;;; the Free Software Foundation, either version 3 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU Affero General Public License for more details. ;;; ;;; You should have received a copy of the GNU Affero General Public License ;;; along with this program. If not, see . ;;; ;;; --------------------------------------------------------------------- (module proccpuinfo-utils ;; Export these procedures: (header-search) (import chicken data-structures extras scheme setup-api) (use posix srfi-1) ;; Return #t when the given file can be found in any of the given directories. ;; Otherwise return #f (define (find-file-in-dirs given-file dirs) (any (lambda (dir) (let ((candidate (string-append dir "/" given-file))) (regular-file? candidate))) dirs)) ;; Return #t when the given header can be found in ;; any of the -I directories specified in CFLAGS. Otherwise, ;; return #f (define (find-header-in-cflags given-file) (let ((CFLAGS (get-environment-variable "CFLAGS"))) (if CFLAGS (let ((dirs (find-include-dirs CFLAGS))) (find-file-in-dirs given-file dirs)) #f))) ;; A procedure that will search for a given header, ;; exiting with an error and a helpful message if it isn't found. (define (find-header-or-exit given-header) (printf "; searching for ~A ...~%" given-header) ;; We're going to use my-find-header here, instead of find-header, ;; because the former respects CFLAGS passed on the command line, ;; while the latter does not. (unless (my-find-header given-header) ;; Oops.. we couldn't find a required header. (report-dependency-error-and-exit given-header))) ;; Return a list of just those elements of a given string that ;; start with "-I" (but remove the "-I" itself from each of the ;; return values) ;; ;; For example, given this string: ;; ;; "foo -Ibar baz -Iabc def" ;; ;; This procedure would return: ;; ;; (bar abc) ;; (define (find-include-dirs given-string) (let* ((candidates (string-split given-string)) (include-dirs (filter looks-like-an-include-dir candidates))) (map strip-first-two-chars include-dirs))) ;; Try to find all the required headers, exiting with an error ;; and a helpful message if any of them aren't found. (define (header-search required-headers) (for-each find-header-or-exit required-headers)) ;; Check to see if the given string starts with "-I" (define (looks-like-an-include-dir given-string) (string-starts-with given-string "-I")) ;; Check to see if the given string starts with "-L" (define (looks-like-a-library-dir given-string) (string-starts-with given-string "-L")) ;; Return #t when the given header can be found in the ;; standard locations Chicken usually looks for it, or in ;; any of the -I directories specified in CFLAGS. Otherwise, ;; return #f (define (my-find-header given-header) (or (find-header-in-cflags given-header) (find-header given-header))) ;; A procedure to print a nice error message for the user, then exit. (define (report-dependency-error-and-exit file) (fprintf (current-error-port) #< (string-length haystack) needle-length) (let ((candidate (substring haystack 0 needle-length))) (if (string=? needle candidate) #t ; Found the perfect match #f)) ; No match #f))) ; No match (the haystack is too short) ;; Return everything after the 2nd character in the given string: (define (strip-first-two-chars given-string) (substring given-string 2 (string-length given-string))) ) ;;; vim: ft=chicken