/usb-modeswitch-1.2.3/jim/autosetup/cc.tcl
TCL | 660 lines | 376 code | 60 blank | 224 comment | 49 complexity | b989c33ea6b83db143237e1a759a094f MD5 | raw file
Possible License(s): GPL-2.0, AGPL-3.0
- # Copyright (c) 2010 WorkWare Systems http://www.workware.net.au/
- # All rights reserved
- # @synopsis:
- #
- # The 'cc' module supports checking various 'features' of the C or C++
- # compiler/linker environment. Common commands are cc-check-includes,
- # cc-check-types, cc-check-functions, cc-with, make-autoconf-h and make-template.
- #
- # The following environment variables are used if set:
- #
- ## CC - C compiler
- ## CXX - C++ compiler
- ## CCACHE - Set to "none" to disable automatic use of ccache
- ## CFLAGS - Additional C compiler flags
- ## CXXFLAGS - Additional C++ compiler flags
- ## LDFLAGS - Additional compiler flags during linking
- ## LIBS - Additional libraries to use (for all tests)
- ## CROSS - Tool prefix for cross compilation
- #
- # The following variables are defined from the corresponding
- # environment variables if set.
- #
- ## CPPFLAGS
- ## LINKFLAGS
- ## CC_FOR_BUILD
- ## LD
- use system
- module-options {}
- # Note that the return code is not meaningful
- proc cc-check-something {name code} {
- uplevel 1 $code
- }
- # Checks for the existence of the given function by linking
- #
- proc cctest_function {function} {
- cctest -link 1 -declare "extern void $function\(void);" -code "$function\();"
- }
- # Checks for the existence of the given type by compiling
- proc cctest_type {type} {
- cctest -code "$type _x;"
- }
- # Checks for the existence of the given type/structure member.
- # e.g. "struct stat.st_mtime"
- proc cctest_member {struct_member} {
- lassign [split $struct_member .] struct member
- cctest -code "static $struct _s; return sizeof(_s.$member);"
- }
- # Checks for the existence of the given define by compiling
- #
- proc cctest_define {name} {
- cctest -code "#ifndef $name\n#error not defined\n#endif"
- }
- # Checks for the existence of the given name either as
- # a macro (#define) or an rvalue (such as an enum)
- #
- proc cctest_decl {name} {
- cctest -code "#ifndef $name\n(void)$name;\n#endif"
- }
- # @cc-check-sizeof type ...
- #
- # Checks the size of the given types (between 1 and 32, inclusive).
- # Defines a variable with the size determined, or "unknown" otherwise.
- # e.g. for type 'long long', defines SIZEOF_LONG_LONG.
- # Returns the size of the last type.
- #
- proc cc-check-sizeof {args} {
- foreach type $args {
- msg-checking "Checking for sizeof $type..."
- set size unknown
- # Try the most common sizes first
- foreach i {4 8 1 2 16 32} {
- if {[cctest -code "static int _x\[sizeof($type) == $i ? 1 : -1\] = { 1 };"]} {
- set size $i
- break
- }
- }
- msg-result $size
- set define [feature-define-name $type SIZEOF_]
- define $define $size
- }
- # Return the last result
- get-define $define
- }
- # Checks for each feature in $list by using the given script.
- #
- # When the script is evaluated, $each is set to the feature
- # being checked, and $extra is set to any additional cctest args.
- #
- # Returns 1 if all features were found, or 0 otherwise.
- proc cc-check-some-feature {list script} {
- set ret 1
- foreach each $list {
- if {![check-feature $each $script]} {
- set ret 0
- }
- }
- return $ret
- }
- # @cc-check-includes includes ...
- #
- # Checks that the given include files can be used
- proc cc-check-includes {args} {
- cc-check-some-feature $args {
- cctest -includes $each
- }
- }
- # @cc-check-types type ...
- #
- # Checks that the types exist.
- proc cc-check-types {args} {
- cc-check-some-feature $args {
- cctest_type $each
- }
- }
- # @cc-check-defines define ...
- #
- # Checks that the given preprocessor symbol is defined
- proc cc-check-defines {args} {
- cc-check-some-feature $args {
- cctest_define $each
- }
- }
- # @cc-check-decls name ...
- #
- # Checks that each given name is either a preprocessor symbol or rvalue
- # such as an enum. Note that the define used for a decl is HAVE_DECL_xxx
- # rather than HAVE_xxx
- proc cc-check-decls {args} {
- set ret 1
- foreach name $args {
- msg-checking "Checking for $name..."
- set r [cctest_decl $name]
- define-feature "decl $name" $r
- if {$r} {
- msg-result "ok"
- } else {
- msg-result "not found"
- set ret 0
- }
- }
- return $ret
- }
- # @cc-check-functions function ...
- #
- # Checks that the given functions exist (can be linked)
- proc cc-check-functions {args} {
- cc-check-some-feature $args {
- cctest_function $each
- }
- }
- # @cc-check-members type.member ...
- #
- # Checks that the given type/structure members exist.
- # A structure member is of the form "struct stat.st_mtime"
- proc cc-check-members {args} {
- cc-check-some-feature $args {
- cctest_member $each
- }
- }
- # @cc-check-function-in-lib function libs ?otherlibs?
- #
- # Checks that the given given function can be found in one of the libs.
- #
- # First checks for no library required, then checks each of the libraries
- # in turn.
- #
- # If the function is found, the feature is defined and lib_$function is defined
- # to -l$lib where the function was found, or "" if no library required.
- # In addition, -l$lib is added to the LIBS define.
- #
- # If additional libraries may be needed for linking, they should be specified
- # as $extralibs as "-lotherlib1 -lotherlib2".
- # These libraries are not automatically added to LIBS.
- #
- # Returns 1 if found or 0 if not.
- #
- proc cc-check-function-in-lib {function libs {otherlibs {}}} {
- msg-checking "Checking libs for $function..."
- set found 0
- cc-with [list -libs $otherlibs] {
- if {[cctest_function $function]} {
- msg-result "none needed"
- define lib_$function ""
- incr found
- } else {
- foreach lib $libs {
- cc-with [list -libs -l$lib] {
- if {[cctest_function $function]} {
- msg-result -l$lib
- define lib_$function -l$lib
- define-append LIBS -l$lib
- incr found
- break
- }
- }
- }
- }
- }
- if {$found} {
- define [feature-define-name $function]
- } else {
- msg-result "no"
- }
- return $found
- }
- # @cc-check-tools tool ...
- #
- # Checks for existence of the given compiler tools, taking
- # into account any cross compilation prefix.
- #
- # For example, when checking for "ar", first AR is checked on the command
- # line and then in the environment. If not found, "${host}-ar" or
- # simply "ar" is assumed depending upon whether cross compiling.
- # The path is searched for this executable, and if found AR is defined
- # to the executable name.
- #
- # It is an error if the executable is not found.
- #
- proc cc-check-tools {args} {
- foreach tool $args {
- set TOOL [string toupper $tool]
- set exe [get-env $TOOL [get-define cross]$tool]
- if {![find-executable $exe]} {
- user-error "Failed to find $exe"
- }
- define $TOOL $exe
- }
- }