Skip to content

Commit 285d56d

Browse files
committed
better path handling in wrapper scripts to locate the mingw binaries more reliably
1 parent b900bc3 commit 285d56d

6 files changed

Lines changed: 161 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

77
## [Unreleased]
8+
### Fixed
9+
- Windows: better path handling to fix "'cp' and 'rm' not found" error
10+
811

912

1013
## [0.3.2 - 2017-11-08]

docs/developer/ide-integration.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# IDE integration
2+
3+
The IDE uses arduino-builder as a build tool. This tool is tightly build
4+
around the gcc. It always assumes that the main sketch is a cpp file and it
5+
includes hardcoded assumptions about the file suffixes '.o' for object files
6+
and '.a' for libraries.
7+
8+
As SDCC is not flexible about file suffix' as well we need some wrapper
9+
scripts to convert the different suffixes before and after the compiler run:
10+
11+
file type |gcc file suffix |SDCC file suffix
12+
----------- |------------- |-----------
13+
source file |any |.c
14+
object file |.o |.rel
15+
library archive |.a |.lib
16+
dependency file |.d |.d
17+
18+
19+
## Linux and MacOS
20+
21+
I like minimal approaches and usually prefer using dash over bash. Less
22+
features => less problems. You know.
23+
24+
The linker wrapper sdcc-link.sh is tricky, as we need to parse all
25+
arguments, modify them if an object file or a library is found and call sdcc
26+
with the full list. The required array handling is not implemented in dash,
27+
so we are stuck with the full bash.
28+
29+
30+
## bash on Windows
31+
32+
Using the bash.exe from the MinGW project we can use the same script files
33+
even for Windows.
34+
35+
36+
### Figuring out the path
37+
38+
The hard part is locating the executeables without requiring the user to
39+
modify the PATH variable. Relative to the location of the wrapper scripts
40+
the executeables for `cp` and `rm` are in `../win`. But a simple simple `cd
41+
../win` or `../win/cp` does't work, as the current working directory at this
42+
point is still the Arduino binary directory.
43+
44+
Since the script is called with a full absolute path, we can extract the
45+
needed path from there. This is the obvious solution:
46+
47+
PATH="${0%/wrapper/*}"/win:$PATH
48+
49+
It looks ok, but it doesn't work on some Windows systems. It will result
50+
in an absolute path like
51+
`C:\Users\michael\AppData\Local\Arduino15\packages\sduino\tools\STM8Tools/win`.
52+
On some systems this works, on some it doesn't. Surprisingly, the mingw
53+
system somehow decides to set the `tools/STM8Tools` directory as the root
54+
directory. On some systems absolute paths above that point are ok, on some
55+
systems they are not. No idea why. And no idea where this root base is
56+
defined (or how to influence it). How can the bash.exe know that it was
57+
extracted from a tar file below the `tools/STM8Tools` directory?
58+
59+
So we need a plan B.
60+
61+
This is technically wrong, but surprisingly it works with Windows:
62+
63+
cd $0/../..
64+
PATH=$(pwd)/win:$PATH
65+
66+
The `pwd` has the positive side effect of converting the path from Windows
67+
to Unix syntax avoiding all these backslash issues.
68+
69+
Finally, this is syntactally correct and works on all systems:
70+
71+
cd "${0%/wrapper/*}"
72+
PATH=$(pwd)/win:$PATH
73+
74+
All together it leds to this solution:
75+
76+
```bash
77+
# check if cp is in the path
78+
if ! command -v cp > /dev/null; then
79+
cd "${0%/wrapper/*}"
80+
PATH=$(pwd)/win:$PATH
81+
fi
82+
```
83+
84+
Now we are ready to go even on Windows. All used functions `command`, `cd`
85+
and `pwd` and the pattern matching are POSIX-conformant builtin shell
86+
functions without any external dependencies resulting in almost no overhead
87+
and high portability.
88+
89+
90+
### Using only cmd.exe
91+
92+
It might be possible to get away with straight cmd.exe batch programming.
93+
But my ambitions of getting into Windows programming are very limited, so
94+
maybe somebody else would like to investigate this.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pages:
3030
- 'ESP14: Wifi board, STM8S003': hardware/esp14.md
3131
- 'STM8S105Discovery: Evaluation board made my ST': hardware/stm8sdiscovery.md
3232
- Developer Guide:
33+
- IDE integration: 'developer/ide-integration.md'
3334
- C preprocessor macro magic: 'developer/macro.md'
3435
- Ways to define a pin mapping: 'developer/pin_mapping.md'
3536
- Using the SDCC compiler: 'developer/sdcc.md'

sduino/hardware/sduino/tools/wrapper/sdar.sh

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,27 @@ WHITE='\033[1;37m'
3434
OFF='\033[0m'
3535
fi
3636

37-
# check if cp is in the path, add our binaries to the PATH if needed
38-
cp --version >/dev/null 2>&1 || PATH=${0%/wrapper/*}/win:$PATH
39-
37+
# check if cp is in the path using 'command -v' (a builtin POSIX function)
38+
if ! command -v cp > /dev/null; then
39+
# Ok, this means we are on a Windows system and we have to find a
40+
# way to access cp and rm in ../win. A simple 'cd ../win' or
41+
# '../win/cp' does't work, as the current working directory is still
42+
# the Arduino binary directory.
43+
#
44+
# This looks ok, but it doesn't work on some Windows systems:
45+
# (No idea why)
46+
# PATH="${0%/wrapper/*}"/win:$PATH
47+
#
48+
# This is technically wrong, but surprisingly it works with Windows:
49+
# cd $0/../..
50+
# PATH=$(pwd)/win:$PATH
51+
#
52+
# Use cd/pwd as a replacement for 'realpath' using only builtins.
53+
# It has the positive side effect of converting from Windows to Unix
54+
# path syntax avoiding all these backslash issues.
55+
cd "${0%/wrapper/*}"
56+
PATH=$(pwd)/win:$PATH
57+
fi
4058

4159
# echo the full command line in cyan:
4260
>&2 echo -ne "${CYAN}"

sduino/hardware/sduino/tools/wrapper/sdcc-link.sh

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,27 @@ WHITE='\033[1;37m'
3636
OFF='\033[0m'
3737
fi
3838

39-
# check if cp is in the path, add our binaries to the PATH if needed
40-
cp --version >/dev/null 2>&1 || PATH=${0%/wrapper/*}/win:$PATH
39+
# check if cp is in the path using 'command -v' (a builtin POSIX function)
40+
if ! command -v cp > /dev/null; then
41+
# Ok, this means we are on a Windows system and we have to find a
42+
# way to access cp and rm in ../win. A simple 'cd ../win' or
43+
# '../win/cp' does't work, as the current working directory is still
44+
# the Arduino binary directory.
45+
#
46+
# This looks ok, but it doesn't work on some Windows systems:
47+
# (No idea why)
48+
# PATH="${0%/wrapper/*}"/win:$PATH
49+
#
50+
# This is technically wrong, but surprisingly it works with Windows:
51+
# cd $0/../..
52+
# PATH=$(pwd)/win:$PATH
53+
#
54+
# Use cd/pwd as a replacement for 'realpath' using only builtins.
55+
# It has the positive side effect of converting from Windows to Unix
56+
# path syntax avoiding all these backslash issues.
57+
cd "${0%/wrapper/*}"
58+
PATH=$(pwd)/win:$PATH
59+
fi
4160

4261
SDCC="$1"
4362
shift

sduino/hardware/sduino/tools/wrapper/sdcc.sh

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,27 @@ WHITE='\033[1;37m'
4545
OFF='\033[0m'
4646
fi
4747

48-
# check if cp is in the path, add our binaries to the PATH if needed
49-
cp --version >/dev/null 2>&1 || PATH=${0%/wrapper/*}/win:$PATH
50-
48+
# check if cp is in the path using 'command -v' (a builtin POSIX function)
49+
if ! command -v cp > /dev/null; then
50+
# Ok, this means we are on a Windows system and we have to find a
51+
# way to access cp and rm in ../win. A simple 'cd ../win' or
52+
# '../win/cp' does't work, as the current working directory is still
53+
# the Arduino binary directory.
54+
#
55+
# This looks ok, but it doesn't work on some Windows systems:
56+
# (No idea why)
57+
# PATH="${0%/wrapper/*}"/win:$PATH
58+
#
59+
# This is technically wrong, but surprisingly it works with Windows:
60+
# cd $0/../..
61+
# PATH=$(pwd)/win:$PATH
62+
#
63+
# Use cd/pwd as a replacement for 'realpath' using only builtins.
64+
# It has the positive side effect of converting from Windows to Unix
65+
# path syntax avoiding all these backslash issues.
66+
cd "${0%/wrapper/*}"
67+
PATH=$(pwd)/win:$PATH
68+
fi
5169

5270
# echo the full command line in cyan:
5371
>&2 echo -ne "${CYAN}"

0 commit comments

Comments
 (0)