Skip to content

Commit e311f36

Browse files
committed
fix(upload): use an absolute, space-safe bitstream path in custom apio raw commands
Custom upload commands that shell out through 'apio raw' (openFPGALoader for the iCESugar-Pro and ColorLight-i5-v7.0 boards) could not open the bitstream on Windows. 'apio raw' mangles the path there in two ways, both seen in the field (macOS/Linux are immune): - A relative path is not found: 'apio raw' does not run the wrapped tool with our cwd on Windows (it does elsewhere), so '_build/default/ hardware.bit' resolves against the wrong directory. This is why the earlier {BITSTREAM_REL} fix still failed. - An absolute path with spaces is re-split at the first space: apio re-joins argv and the shell re-parses it unquoted, breaking on build dirs like '.../1. Basic/ice-build/02. Two LEDs/...'. The only form that survives both is an absolute path with no spaces. {BITSTREAM} is now absolute and, on Windows, uses the 8.3 short name of the build dir (which always exists) via shortBuildDir(); it is a no-op off Windows and falls back to the long path if 8.3 lookup fails. The six affected boards switch from {BITSTREAM_REL} to {BITSTREAM}; {BITSTREAM_REL} is kept for commands we exec directly (with cwd = build dir), not apio raw. Verified on macOS end to end: the resolved command opens an absolute, space-containing bitstream path through apio raw. Windows still to be confirmed on hardware.
1 parent 51f89fe commit e311f36

7 files changed

Lines changed: 46 additions & 18 deletions

File tree

app/resources/boards/ColorLight-i5-v7.0_(FT2232H)/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"commands": {
2020
"upload": [
21-
"{APIO_CMD} raw -- openFPGALoader -c ft2232 --freq 30000000 -v --file-type bin \"{BITSTREAM_REL}\""
21+
"{APIO_CMD} raw -- openFPGALoader -c ft2232 --freq 30000000 -v --file-type bin \"{BITSTREAM}\""
2222
]
2323
}
2424
}

app/resources/boards/ColorLight-i5-v7.0_(FT232H)/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"commands": {
2020
"upload": [
21-
"{APIO_CMD} raw -- openFPGALoader -c ft232 --freq 30000000 -v --file-type bin \"{BITSTREAM_REL}\""
21+
"{APIO_CMD} raw -- openFPGALoader -c ft232 --freq 30000000 -v --file-type bin \"{BITSTREAM}\""
2222
]
2323
}
2424
}

app/resources/boards/ColorLight-i5-v7.0_(USB-Blaster)/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"commands": {
2020
"upload": [
21-
"{APIO_CMD} raw -- openFPGALoader -c usb-blaster -v --file-type bin \"{BITSTREAM_REL}\""
21+
"{APIO_CMD} raw -- openFPGALoader -c usb-blaster -v --file-type bin \"{BITSTREAM}\""
2222
]
2323
}
2424
}

app/resources/boards/iCESugar-Pro_(FT2232H)/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"commands": {
2020
"upload": [
21-
"{APIO_CMD} raw -- openFPGALoader -c ft2232 --freq 30000000 -v --file-type bin \"{BITSTREAM_REL}\""
21+
"{APIO_CMD} raw -- openFPGALoader -c ft2232 --freq 30000000 -v --file-type bin \"{BITSTREAM}\""
2222
]
2323
}
2424
}

app/resources/boards/iCESugar-Pro_(FT232H)/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"commands": {
2020
"upload": [
21-
"{APIO_CMD} raw -- openFPGALoader -c ft232 --freq 30000000 -v --file-type bin \"{BITSTREAM_REL}\""
21+
"{APIO_CMD} raw -- openFPGALoader -c ft232 --freq 30000000 -v --file-type bin \"{BITSTREAM}\""
2222
]
2323
}
2424
}

app/resources/boards/iCESugar-Pro_(USB-Blaster)/info.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"commands": {
2020
"upload": [
21-
"{APIO_CMD} raw -- openFPGALoader -c usb-blaster -v --file-type bin \"{BITSTREAM_REL}\""
21+
"{APIO_CMD} raw -- openFPGALoader -c usb-blaster -v --file-type bin \"{BITSTREAM}\""
2222
]
2323
}
2424
}

app/scripts/services/tools.js

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,32 @@ angular
11291129
return '';
11301130
}
11311131

1132+
//-- Windows-only: return the 8.3 short form of an (existing) directory.
1133+
//-- A path with spaces is mangled when it travels through `apio raw`
1134+
//-- (apio re-joins argv and the shell re-splits at the space), and a
1135+
//-- path relative to the build dir is not found either because
1136+
//-- `apio raw` does not run the wrapped tool with our cwd on Windows
1137+
//-- (it does on macOS/Linux). The one form that always survives is an
1138+
//-- ABSOLUTE path with no spaces, i.e. the short name of the build dir,
1139+
//-- which always exists at command time. No-op off Windows and, if the
1140+
//-- lookup fails (e.g. 8.3 creation disabled), falls back to the input.
1141+
function shortBuildDir(dir) {
1142+
if (process.platform !== 'win32' || !dir) {
1143+
return dir;
1144+
}
1145+
try {
1146+
var out = nodeChildProcess
1147+
.execSync('for %I in ("' + dir + '") do @echo %~sI', {
1148+
shell: 'cmd.exe',
1149+
})
1150+
.toString()
1151+
.trim();
1152+
return out || dir;
1153+
} catch (e) {
1154+
return dir;
1155+
}
1156+
}
1157+
11321158
//-- Build the placeholder substitution context for custom commands
11331159
function buildPlaceholderContext() {
11341160
var board = common.selectedBoard;
@@ -1153,29 +1179,31 @@ angular
11531179
var projectDir =
11541180
project.dirname ||
11551181
(project.filepath ? utils.dirname(project.filepath) : '');
1182+
//-- Build dir made safe to embed in a custom command line: on Windows
1183+
//-- its 8.3 short form (space-free, immune to `apio raw` mangling),
1184+
//-- unchanged elsewhere.
1185+
var safeBuildDir = shortBuildDir(common.BUILD_DIR);
11561186
return {
11571187
BUILD_DIR: common.BUILD_DIR,
11581188
TOP: 'main',
11591189
CONSTRAINT_FILE: nodePath.join(common.BUILD_DIR, constraintName),
11601190
//-- apio (>=1.3) builds into <build>/_build/<env>/, and icestudio's
11611191
//-- apio.ini always declares [env:default], so the bitstream is here
1162-
//-- (NOT at the build-dir root as in older apio).
1192+
//-- (NOT at the build-dir root as in older apio). ABSOLUTE and, on
1193+
//-- Windows, space-free (safeBuildDir is the 8.3 short name): this
1194+
//-- is the form that survives `apio raw` on every OS, so it is the
1195+
//-- one to use in custom upload commands (openFPGALoader, etc.).
11631196
BITSTREAM: nodePath.join(
1164-
common.BUILD_DIR,
1197+
safeBuildDir,
11651198
'_build',
11661199
'default',
11671200
bitstreamName
11681201
),
1169-
//-- Same bitstream, but RELATIVE to the build dir. Custom commands
1170-
//-- run with cwd = common.BUILD_DIR (see runSequential), so this
1171-
//-- resolves to the same file. Prefer it in toolchain command lines
1172-
//-- that must survive spaces in the path: a relative path has no
1173-
//-- spaces, so it is immune to a space anywhere in the build dir
1174-
//-- (temp folder, spaced Windows username, "My Documents"...) that
1175-
//-- some launchers mangle — e.g. openFPGALoader through `apio raw`
1176-
//-- on Windows, which re-splits an absolute quoted path at the
1177-
//-- first space. cwd is passed to the process directly, never
1178-
//-- through the shell/command string, so it is not affected.
1202+
//-- Same bitstream, RELATIVE to the build dir. Works only when the
1203+
//-- tool runs with cwd = common.BUILD_DIR. That holds for our own
1204+
//-- exec (see runSequential) but NOT through `apio raw` on Windows,
1205+
//-- which drops the cwd — so do not use it in `apio raw` command
1206+
//-- lines (prefer {BITSTREAM}). Kept for commands we run directly.
11791207
BITSTREAM_REL: nodePath.join('_build', 'default', bitstreamName),
11801208
VERILOG: nodePath.join(common.BUILD_DIR, 'main.v'),
11811209
ARCH: arch,

0 commit comments

Comments
 (0)