@@ -91,6 +91,129 @@ fn build_glue<P: AsRef<Path> + std::fmt::Debug>(include_path: &P) {
91
91
. unwrap ( ) ;
92
92
}
93
93
94
+ // When cross-compiling, we cannot use `build_glue` as we cannot run the generated
95
+ // executable. Instead, let's take a stab at synthesizing the likely values.
96
+ // If you're cross-compiling and using a non-vendored library then there is a chance
97
+ // that the values selected here may be incorrect, but we have no way to determine
98
+ // that here.
99
+ fn generate_glue ( ) -> std:: io:: Result < ( ) > {
100
+ use std:: io:: Write ;
101
+ let build_dir = PathBuf :: from ( env:: var_os ( "OUT_DIR" ) . unwrap ( ) ) ;
102
+ let mut glue = std:: fs:: File :: create ( build_dir. join ( "glue.rs" ) ) ?;
103
+ write ! (
104
+ glue,
105
+ "/* This file was generated by build/main.rs; do not modify by hand */\n "
106
+ ) ?;
107
+ write ! ( glue, "use std::os::raw::*;\n " ) ?;
108
+
109
+ // We can't statically determine the default paths.
110
+ // It is possible though to use something like lazy_static! to create a new
111
+ // lua context and extract that information.
112
+ // For my (@wez) purposes, I actually don't want there to be a default path,
113
+ // so I'm just leaving this blank for the moment.
114
+ write ! ( glue, "pub const LUA_PATH_DEFAULT: &str = \" \" ;\n " ) ?;
115
+ write ! ( glue, "pub const LUA_CPATH_DEFAULT: &str = \" \" ;\n " ) ?;
116
+
117
+ write ! (
118
+ glue,
119
+ "#[cfg(windows)] pub const LUA_DIRSEP: &str = \" \\ \\ \" ;\n "
120
+ ) ?;
121
+ write ! ( glue, "#[cfg(unix)] pub const LUA_DIRSEP: &str = \" /\" ;\n " ) ?;
122
+
123
+ let pointer_bit_width: usize = env:: var ( "CARGO_CFG_TARGET_POINTER_WIDTH" )
124
+ . unwrap ( )
125
+ . parse ( )
126
+ . unwrap ( ) ;
127
+ write ! (
128
+ glue,
129
+ "pub const LUA_EXTRASPACE: c_int = {} / 8;\n " ,
130
+ pointer_bit_width
131
+ ) ?;
132
+
133
+ // This is generally hardcoded to this size
134
+ write ! ( glue, "pub const LUA_IDSIZE: c_int = 60;\n " ) ?;
135
+
136
+ write ! ( glue, "pub const LUAL_BUFFERSIZE: c_int = 16 * ({} / 8) * std::mem::size_of::<LUA_NUMBER>() as c_int;\n " , pointer_bit_width) ?;
137
+
138
+ // Unless the target is restricted, the defaults are 64 bit
139
+ write ! ( glue, "pub type LUA_NUMBER = c_double;\n " ) ?;
140
+ write ! ( glue, "pub type LUA_INTEGER = i64;\n " ) ?;
141
+ write ! ( glue, "pub type LUA_UNSIGNED = u64;\n " ) ?;
142
+
143
+ let version = if cfg ! ( feature = "luajit" ) || cfg ! ( feature = "lua51" ) {
144
+ ( 5 , 1 , 0 )
145
+ } else if cfg ! ( feature = "lua52" ) {
146
+ ( 5 , 2 , 0 )
147
+ } else if cfg ! ( feature = "lua53" ) {
148
+ ( 5 , 3 , 0 )
149
+ } else if cfg ! ( feature = "lua54" ) {
150
+ ( 5 , 4 , 0 )
151
+ } else {
152
+ unreachable ! ( ) ;
153
+ } ;
154
+
155
+ write ! (
156
+ glue,
157
+ "pub const LUA_VERSION_NUM: c_int = {};\n " ,
158
+ ( version. 0 * 100 ) + version. 1
159
+ ) ?;
160
+ write ! (
161
+ glue,
162
+ "pub const LUA_VERSION: &str = \" Lua {}.{}\" ;\n " ,
163
+ version. 0 , version. 1
164
+ ) ?;
165
+ write ! (
166
+ glue,
167
+ "pub const LUA_RELEASE: &str = \" Lua {}.{}.{}\" ;\n " ,
168
+ version. 0 , version. 1 , version. 2
169
+ ) ?;
170
+
171
+ let max_stack = if pointer_bit_width >= 32 {
172
+ 1_000_000
173
+ } else {
174
+ 15_000
175
+ } ;
176
+ write ! (
177
+ glue,
178
+ "pub const LUA_REGISTRYINDEX: c_int = -{} - 1000;\n " ,
179
+ max_stack
180
+ ) ?;
181
+
182
+ // These two are only defined in lua 5.1
183
+ write ! ( glue, "pub const LUA_ENVIRONINDEX: c_int = -10001;\n " ) ?;
184
+ write ! ( glue, "pub const LUA_GLOBALSINDEX: c_int = -10002;\n " ) ?;
185
+
186
+ // This is only defined in lua 5.3 and up, but we can always generate its value here,
187
+ // even if we don't use it.
188
+ // This matches the default definition in lauxlib.h
189
+ write ! ( glue, "pub const LUAL_NUMSIZES: c_int = std::mem::size_of::<LUA_INTEGER>() as c_int * 16 + std::mem::size_of::<LUA_NUMBER>() as c_int;\n " ) ?;
190
+
191
+ write ! (
192
+ glue,
193
+ r#"
194
+ #[cfg(feature = "luajit")]
195
+ pub const LUA_BITLIBNAME: &str = "bit";
196
+ #[cfg(not(feature = "luajit"))]
197
+ pub const LUA_BITLIBNAME: &str = "bit32";
198
+
199
+ pub const LUA_COLIBNAME: &str = "coroutine";
200
+ pub const LUA_DBLIBNAME: &str = "debug";
201
+ pub const LUA_IOLIBNAME: &str = "io";
202
+ pub const LUA_LOADLIBNAME: &str = "package";
203
+ pub const LUA_MATHLIBNAME: &str = "math";
204
+ pub const LUA_OSLIBNAME: &str = "os";
205
+ pub const LUA_STRLIBNAME: &str = "string";
206
+ pub const LUA_TABLIBNAME: &str = "table";
207
+ pub const LUA_UTF8LIBNAME: &str = "utf8";
208
+
209
+ pub const LUA_JITLIBNAME: &str = "jit";
210
+ pub const LUA_FFILIBNAME: &str = "ffi";
211
+ "#
212
+ ) ?;
213
+
214
+ Ok ( ( ) )
215
+ }
216
+
94
217
fn main ( ) {
95
218
#[ cfg( not( any(
96
219
feature = "lua54" ,
@@ -132,5 +255,9 @@ fn main() {
132
255
) ;
133
256
134
257
let include_dir = find:: probe_lua ( ) ;
135
- build_glue ( & include_dir) ;
258
+ if env:: var ( "TARGET" ) . unwrap ( ) != env:: var ( "HOST" ) . unwrap ( ) {
259
+ generate_glue ( ) . unwrap ( ) ;
260
+ } else {
261
+ build_glue ( & include_dir) ;
262
+ }
136
263
}
0 commit comments