Skip to content

Commit

Permalink
Resolve Windows path problems (#8860)
Browse files Browse the repository at this point in the history
Moved up os.makedirs for ./core/ directory.
Strange problem creating files with file paths with spaces.
Strange that "create file" would work when the path did not contain spaces and the last folder of the path hadn't been created.

Added try/except on main to commit print buffer on traceback for context.

Additional issues with diacritics and locale character encoding for shell vs source code.
build.opt is written with the same encoding as the shell; however, the data read from the Sketch.ino.global.h is UTF-8.

Tested on Windows 10 (en-US) with Arduino IDE 2.0.3 Under an
account with a diacritic character in the user ID path.

Needs testing on Japanese Windows
  • Loading branch information
mhightower83 committed Feb 22, 2023
1 parent d7cd4be commit 71a51b1
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 12 deletions.
91 changes: 80 additions & 11 deletions tools/mkbuildoptglobals.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,13 @@
import glob
import os
import platform
import traceback
import sys
import textwrap
import time

import locale

# Need to work on signature line used for match to avoid conflicts with
# existing embedded documentation methods.
build_opt_signature = "/*@create-file:build.opt@"
Expand All @@ -201,6 +204,7 @@
err_print_flag = False
msg_print_buf = ""
debug_enabled = False
default_encoding = None

# Issues trying to address through buffered printing
# 1. Arduino IDE 2.0 RC5 does not show stderr text in color. Text printed does
Expand Down Expand Up @@ -295,16 +299,16 @@ def copy_create_build_file(source_fqfn, build_target_fqfn):
pass
return True # file changed


def add_include_line(build_opt_fqfn, include_fqfn):
global default_encoding
if not os.path.exists(include_fqfn):
# If file is missing, we need an place holder
with open(include_fqfn, 'w', encoding="utf-8"):
with open(include_fqfn, 'w', encoding=default_encoding):
pass
print("add_include_line: Created " + include_fqfn)
with open(build_opt_fqfn, 'a', encoding="utf-8") as build_opt:
build_opt.write('-include "' + include_fqfn.replace('\\', '\\\\') + '"\n')
print_msg("add_include_line: Created " + include_fqfn)

with open(build_opt_fqfn, 'a', encoding=default_encoding) as build_opt:
build_opt.write('-include "' + include_fqfn.replace('\\', '\\\\') + '"\n')

def extract_create_build_opt_file(globals_h_fqfn, file_name, build_opt_fqfn):
"""
Expand All @@ -313,8 +317,9 @@ def extract_create_build_opt_file(globals_h_fqfn, file_name, build_opt_fqfn):
copy of Sketch.ino.globals.h.
"""
global build_opt_signature
global default_encoding

build_opt = open(build_opt_fqfn, 'w', encoding="utf-8")
build_opt = open(build_opt_fqfn, 'w', encoding=default_encoding)
if not os.path.exists(globals_h_fqfn) or (0 == os.path.getsize(globals_h_fqfn)):
build_opt.close()
return False
Expand Down Expand Up @@ -605,12 +610,63 @@ def parse_args():
# ref nargs='*'', https://stackoverflow.com/a/4480202
# ref no '--n' parameter, https://stackoverflow.com/a/21998252


# retrieve *system* encoding, not the one used by python internally
if sys.version_info >= (3, 11):
def get_encoding():
return locale.getencoding()
else:
def get_encoding():
return locale.getdefaultlocale()[1]


def show_value(desc, value):
print_dbg(f'{desc:<40} {value}')
return

def locale_dbg():
show_value("get_encoding()", get_encoding())
show_value("locale.getdefaultlocale()", locale.getdefaultlocale())
show_value('sys.getfilesystemencoding()', sys.getfilesystemencoding())
show_value("sys.getdefaultencoding()", sys.getdefaultencoding())
show_value("locale.getpreferredencoding(False)", locale.getpreferredencoding(False))
try:
show_value("locale.getpreferredencoding()", locale.getpreferredencoding())
except:
pass
show_value("sys.stdout.encoding", sys.stdout.encoding)

# use current setting
show_value("locale.setlocale(locale.LC_ALL, None)", locale.setlocale(locale.LC_ALL, None))
try:
show_value("locale.getencoding()", locale.getencoding())
except:
pass
show_value("locale.getlocale()", locale.getlocale())

# use user setting
show_value("locale.setlocale(locale.LC_ALL, '')", locale.setlocale(locale.LC_ALL, ''))
# show_value("locale.getencoding()", locale.getencoding())
show_value("locale.getlocale()", locale.getlocale())
return


def main():
global build_opt_signature
global docs_url
global debug_enabled
global default_encoding
num_include_lines = 1

# Given that GCC will handle lines from an @file as if they were on
# the command line. I assume that the contents of @file need to be encoded
# to match that of the shell running GCC runs. I am not 100% sure this API
# gives me that, but it appears to work.
#
# However, elsewhere when dealing with source code we continue to use 'utf-8',
# ref. https://gcc.gnu.org/onlinedocs/cpp/Character-sets.html
default_encoding = get_encoding()

args = parse_args()
debug_enabled = args.debug
runtime_ide_path = os.path.normpath(args.runtime_ide_path)
Expand All @@ -623,6 +679,13 @@ def main():
build_path_core, build_opt_name = os.path.split(build_opt_fqfn)
globals_h_fqfn = os.path.join(build_path_core, globals_name)

if debug_enabled:
locale_dbg()

default_locale = locale.getdefaultlocale()
print_msg(f'default locale: {default_locale}')
print_msg(f'default_encoding: {default_encoding}')

print_dbg(f"runtime_ide_path: {runtime_ide_path}")
print_dbg(f"runtime_ide_version: {args.runtime_ide_version}")
print_dbg(f"build_path: {build_path}")
Expand Down Expand Up @@ -655,6 +718,10 @@ def main():
print_dbg(f"first_time: {first_time}")
print_dbg(f"use_aggressive_caching_workaround: {use_aggressive_caching_workaround}")

if not os.path.exists(build_path_core):
os.makedirs(build_path_core)
print_msg("Clean build, created dir " + build_path_core)

if first_time or \
not use_aggressive_caching_workaround or \
not os.path.exists(commonhfile_fqfn):
Expand All @@ -667,10 +734,6 @@ def main():
touch(commonhfile_fqfn)
print_err(f"Neutralized future timestamp on build file: {commonhfile_fqfn}")

if not os.path.exists(build_path_core):
os.makedirs(build_path_core)
print_msg("Clean build, created dir " + build_path_core)

if os.path.exists(source_globals_h_fqfn):
print_msg("Using global include from " + source_globals_h_fqfn)

Expand Down Expand Up @@ -750,4 +813,10 @@ def main():
handle_error(0) # commit print buffer

if __name__ == '__main__':
sys.exit(main())
rc = 1
try:
rc = main()
except:
print_err(traceback.format_exc())
handle_error(0)
sys.exit(rc)
13 changes: 12 additions & 1 deletion tools/sizes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,20 @@
import os
import subprocess
import sys
import locale

sys.stdout = sys.stderr


# retrieve *system* encoding, not the one used by python internally
if sys.version_info >= (3, 11):
def get_encoding():
return locale.getencoding()
else:
def get_encoding():
return locale.getdefaultlocale()[1]


def get_segment_sizes(elf, path, mmu):
iram_size = 0
iheap_size = 0
Expand Down Expand Up @@ -73,7 +84,7 @@ def get_segment_sizes(elf, path, mmu):
)

cmd = [os.path.join(path, "xtensa-lx106-elf-size"), "-A", elf]
with subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) as proc:
with subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True, encoding=get_encoding()) as proc:
lines = proc.stdout.readlines()
for line in lines:
words = line.split()
Expand Down

1 comment on commit 71a51b1

@jjsuwa-sys3175
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs testing on Japanese Windows

It seems fine for me (Win7 x64 SP1 Japanese NLV + Python 3.8.10 + Arduino IDE 1.8.19).
Under my installation, the file path does not contain any "exotic" Unicode chars but space.

Please sign in to comment.