Fossil SCM

fossil-scm / autosetup / cc-run.tcl
Blame History Raw 166 lines
1
# @synopsis:
2
#
3
# The 'cc-run' module provides a way to compile and run a bit of
4
# code. This is not cross compilation friendly and is therefore
5
# against autosetup's general philosophy, but is sometimes the only
6
# way to perform a test.
7
#
8
9
use cc
10
11
module-options {}
12
13
# cc-run is based on cctest in cc.tcl.
14
15
# @cc-run ?settings?
16
#
17
# Low level C/C++ program checker. Compiles, links, and runs a small
18
# C/C++ program according to the arguments and returns 1 if OK, or 0
19
# if not.
20
#
21
# Supported settings are:
22
#
23
## -cflags cflags A list of flags to pass to the compiler
24
## -includes list A list of includes, e.g. {stdlib.h stdio.h}
25
## -declare code Code to declare before main()
26
## -lang c|c++ Use the C (default) or C++ compiler
27
## -libs liblist List of libraries to link, e.g. {-ldl -lm}
28
## -code code Code to compile in the body of main()
29
## -source code Compile a complete program. Ignore -includes, -declare and -code
30
## -sourcefile file Shorthand for -source [readfile [get-define srcdir]/$file]
31
#
32
# Unless -source or -sourcefile is specified, the C program looks like:
33
#
34
## #include <firstinclude> /* same for remaining includes in the list */
35
##
36
## declare-code /* any code in -declare, verbatim */
37
##
38
## int main(void) {
39
## code /* any code in -code, verbatim */
40
## return 0;
41
## }
42
#
43
# Any failures are recorded in 'config.log'
44
#
45
proc cc-run {args} {
46
set src conftest__.c
47
set tmp conftest__
48
49
# Easiest way to merge in the settings
50
cc-with $args {
51
array set opts [cc-get-settings]
52
}
53
54
if {[info exists opts(-sourcefile)]} {
55
set opts(-source) [readfile [get-define srcdir]/$opts(-sourcefile) "#error can't find $opts(-sourcefile)"]
56
}
57
if {[info exists opts(-source)]} {
58
set lines $opts(-source)
59
} else {
60
foreach i $opts(-includes) {
61
if {$opts(-code) ne "" && ![feature-checked $i]} {
62
# Compiling real code with an unchecked header file
63
# Quickly (and silently) check for it now
64
65
# Remove all -includes from settings before checking
66
set saveopts [cc-update-settings -includes {}]
67
msg-quiet cc-check-includes $i
68
cc-store-settings $saveopts
69
}
70
if {$opts(-code) eq "" || [have-feature $i]} {
71
lappend source "#include <$i>"
72
}
73
}
74
lappend source {*}$opts(-declare)
75
lappend source "int main(void) {"
76
lappend source $opts(-code)
77
lappend source "return 0;"
78
lappend source "}"
79
80
set lines [join $source \n]
81
}
82
83
# Build the command line
84
set cmdline {}
85
lappend cmdline {*}[get-define CCACHE]
86
switch -exact -- $opts(-lang) {
87
c++ {
88
lappend cmdline {*}[get-define CXX] {*}[get-define CXXFLAGS]
89
}
90
c {
91
lappend cmdline {*}[get-define CC] {*}[get-define CFLAGS]
92
}
93
default {
94
autosetup-error "cc-run called with unknown language: $opts(-lang)"
95
}
96
}
97
98
lappend cmdline {*}$opts(-cflags)
99
100
switch -glob -- [get-define host] {
101
*-*-darwin* {
102
# Don't generate .dSYM directories
103
lappend cmdline -gstabs
104
}
105
}
106
lappend cmdline $src -o $tmp {*}$opts(-libs)
107
108
# At this point we have the complete command line and the
109
# complete source to be compiled. Get the result from cache if
110
# we can
111
if {[info exists ::cc_cache($cmdline,$lines)]} {
112
msg-checking "(cached) "
113
set ok $::cc_cache($cmdline,$lines)
114
if {$::autosetup(debug)} {
115
configlog "From cache (ok=$ok): [join $cmdline]"
116
configlog "============"
117
configlog $lines
118
configlog "============"
119
}
120
return $ok
121
}
122
123
writefile $src $lines\n
124
125
set ok 1
126
if {[catch {exec-with-stderr {*}$cmdline} result errinfo]} {
127
configlog "Failed: [join $cmdline]"
128
configlog $result
129
configlog "============"
130
configlog "The failed code was:"
131
configlog $lines
132
configlog "============"
133
set ok 0
134
} else {
135
if {$::autosetup(debug)} {
136
configlog "Compiled OK: [join $cmdline]"
137
configlog "============"
138
configlog $lines
139
configlog "============"
140
}
141
if {[catch {exec-with-stderr ./$tmp} result errinfo]} {
142
configlog "Failed: $tmp"
143
configlog $result
144
configlog "============"
145
configlog "The failed code was:"
146
configlog $lines
147
configlog "============"
148
set ok 0
149
} else {
150
if {$::autosetup(debug)} {
151
configlog "Ran OK: $tmp"
152
configlog "============"
153
configlog $lines
154
configlog "============"
155
}
156
}
157
}
158
file delete $src
159
file delete $tmp
160
161
# cache it
162
set ::cc_cache($cmdline,$lines) $ok
163
164
return $ok
165
}
166

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button