Xcode 11 broke genstrings given *.mm


Steve Mills
 

One of my projects stopped building when it got to a build phase that runs "genstrings -q -o Base.lproj *.m *.mm" giving the error:

/genstrings:1:1: failed to read input file *.mm

Neat. Luckily this particular project only has 3 .mm files and none of them have localizable strings. Anybody else run into this?

--
Steve Mills
Drummer, Mac geek


 



On Sep 29, 2019, at 8:49 PM, Steve Mills via Groups.Io <sjmills@...> wrote:

One of my projects stopped building when it got to a build phase that runs "genstrings -q -o Base.lproj *.m *.mm" giving the error:
/genstrings:1:1: failed to read input file *.mm

Where exactly does the command-line with 'genstrings' appear? Looks like that place is no longer performing wildcard expansion. I'm guessing the problem is that you put it directly in the "Shell" text field … ? This isn't meant to be a command line, just a path.

The text-box for the shell script should work, since it runs bash by default. If it doesn't, try putting the line
#! bin/bash
at the top.

—Jens


Steve Mills
 

On Sep 30, 2019, at 12:00:37, Jens Alfke <jens@mooseyard.com> wrote:

On Sep 29, 2019, at 8:49 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

One of my projects stopped building when it got to a build phase that runs "genstrings -q -o Base.lproj *.m *.mm" giving the error:
/genstrings:1:1: failed to read input file *.mm
Where exactly does the command-line with 'genstrings' appear? Looks like that place is no longer performing wildcard expansion. I'm guessing the problem is that you put it directly in the "Shell" text field … ? This isn't meant to be a command line, just a path.

The text-box for the shell script should work, since it runs bash by default. If it doesn't, try putting the line
#! bin/bash
at the top.
The script is in the same place it's been for over 2 years. I know how to use Run Script build phases. And it still works for *.m. It's just broken for .mm files.

--
Steve Mills
Drummer, Mac geek


Chris Hanson
 

On Sep 30, 2019, at 8:17 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

The script is in the same place it's been for over 2 years. I know how to use Run Script build phases. And it still works for *.m. It's just broken for .mm files.
There were major changes in genstrings for Xcode 11; extractLocStrings was renamed to genstrings and brought to feature parity with the few things that genstrings did that extractLocStrings didn’t. It also had support for things like SwiftUI added.

My suspicion is that you’re expecting “genstrings *.mm” to work in a directory that doesn’t contain any .mm files. The old genstrings would just silently ignore nonexistent files (e.g. a filename of literally “*.mm” as some shells will pass when expansion fails). Now it produces an error.

Also, I would strongly recommend adopting Xcode’s “Export for Localization…” and “Import Localizations…” feature instead of calling genstrings on your sources yourself. Doing a localization export have Xcode extract the strings from your sources, xib and storyboard files, etc. and also collect together all other localized resources, and produce a localization catalog that can be used as the basis for localization. Then your localizers can give you translated catalogs to import to produce the appropriate strings, stringsdict, and so on files for your languages. You can even set up your CI to do this since export and import are both supported in xcodebuild, not just the IDE.

-- Chris


Steve Mills
 

On Oct 1, 2019, at 20:50:44, Chris Hanson <cmhanson@eschatologist.net> wrote:

My suspicion is that you’re expecting “genstrings *.mm” to work in a directory that doesn’t contain any .mm files. The old genstrings would just silently ignore nonexistent files (e.g. a filename of literally “*.mm” as some shells will pass when expansion fails). Now it produces an error.
I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.

Also, I would strongly recommend adopting Xcode’s “Export for Localization…” and “Import Localizations…” feature instead of calling genstrings on your sources yourself. Doing a localization export have Xcode extract the strings from your sources, xib and storyboard files, etc. and also collect together all other localized resources, and produce a localization catalog that can be used as the basis for localization. Then your localizers can give you translated catalogs to import to produce the appropriate strings, stringsdict, and so on files for your languages. You can even set up your CI to do this since export and import are both supported in xcodebuild, not just the IDE.
My CI. That's rich. This is just me here. I'll check out the export thing. Even thought I doubt anyone will ever offer to localize any of my apps. I've just always done the genstrings thing so I'm prepared.

--
Steve Mills
Drummer, Mac geek


Marco S Hyman
 

On Oct 1, 2019, at 9:08 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.
That’s not how shells work.

--- bash ---
bash-3.2$ echo *.m *.mm
a.m b.m c.m *.mm

--- sh ---
$ echo *.m *.mm
a.m b.m c.m *.mm

--- zsh ---
echo *.m *.mm
zsh: no matches found: *.mm


zsh doesn’t even try if there is an error


 

*.{m,mm} might work better.

—Jens

On Oct 1, 2019, at 9:44 PM, Marco S Hyman <marc@snafu.org> wrote:



On Oct 1, 2019, at 9:08 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.
That’s not how shells work.

--- bash ---
bash-3.2$ echo *.m *.mm
a.m b.m c.m *.mm

--- sh ---
$ echo *.m *.mm
a.m b.m c.m *.mm

--- zsh ---
echo *.m *.mm
zsh: no matches found: *.mm


zsh doesn’t even try if there is an error


Bernie Maier
 

On Wed, 2 Oct 2019, at 4:42 PM, Jens Alfke wrote:
*.{m,mm} might work better.
As it happens, no. In both bash and zsh, whichever extension doesn’t match will still produce an error message. In both shells, brace expansion occurs before wildcard expansion and is basically a pure textual expansion without any check on the file system. Wildcard expansion does match against the file system.

zsh documentation (http://zsh.sourceforge.net/Doc/Release/Expansion.html#Brace-Expansion) says:

Note that brace expansion is not part of filename generation (globbing); an expression such as */{foo,bar} is split into two separate words */foo and */bar before filename generation takes place
bash documentation (https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) says:

Brace expansion is performed before any other expansions, and any characters special to other expansions are preserved in the result. It is strictly textual.
In zsh you could do *.(m|mm) or even *.m(|m) if you wanted to be tricksy. There might be other obscure constructs.

Cheers,
Bernie

—Jens

On Oct 1, 2019, at 9:44 PM, Marco S Hyman <marc@snafu.org> wrote:



On Oct 1, 2019, at 9:08 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.
That’s not how shells work.

--- bash ---
bash-3.2$ echo *.m *.mm
a.m b.m c.m *.mm

--- sh ---
$ echo *.m *.mm
a.m b.m c.m *.mm

--- zsh ---
echo *.m *.mm
zsh: no matches found: *.mm


zsh doesn’t even try if there is an error





Steve Mills
 

On Oct 1, 2019, at 23:44:25, Marco S Hyman <marc@snafu.org> wrote:

On Oct 1, 2019, at 9:08 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.
That’s not how shells work.
But it's how genstrings works. It accepts multiple files. This works:

genstrings -q -o Base.lproj *.m *.h

This does not:

genstrings -q -o Base.lproj *.m *.mm

And neither does this:

genstrings -q -o Base.lproj *.mm

--
Steve Mills
Drummer, Mac geek


Jonathan Prescott
 

genstrings itself does not expand filenames (turning *.mm into a.mm, b.mm, etc.). The shell does the expansion and feeds the file list to the command line and invokes genstrings with the expanded file list. If you "type

genstrings -q -o Base.lproj \*.m *.h

in a directory with .m and .h files, you will get the error with genstrings trying to open a "*.m" file. An interesting experiment would be to reverse the order of the .m and .mm specifications so that in a directory of with .m files, but, no .mm files, does genstrings process the .m files anyway while noting that there are no .mm files, i.e., does

genstrings -q -o Base.lproj *.mm *.m
exit 0

still process the .m files, even with genstrings complaining about no .mm files? Adding the “exit 0” keeps Xcode from complaining about a script file returning a non-zero status result.

You could also use something like:

for file in `ls -1 *.h *.m *.mm`
do
genstrings -q -o Base.lproj $file
done
exit 0

This will go through all the existing files with any of those suffixes. “ls" will complain about not finding files with a suffix in the error log, but it will process all the files it finds and send them to genstrings.

If you want to get one-liner about it

genstrings -q -o Base.lproj `ls *.h *.m *.mm`
exit 0

Jonathan

On Oct 2, 2019, at 10:37 AM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

On Oct 1, 2019, at 23:44:25, Marco S Hyman <marc@snafu.org> wrote:

On Oct 1, 2019, at 9:08 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.
That’s not how shells work.
But it's how genstrings works. It accepts multiple files. This works:

genstrings -q -o Base.lproj *.m *.h

This does not:

genstrings -q -o Base.lproj *.m *.mm

And neither does this:

genstrings -q -o Base.lproj *.mm

--
Steve Mills
Drummer, Mac geek




Chris Hanson
 

On Oct 1, 2019, at 9:08 PM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote:

On Oct 1, 2019, at 20:50:44, Chris Hanson <cmhanson@eschatologist.net> wrote:

My suspicion is that you’re expecting “genstrings *.mm” to work in a directory that doesn’t contain any .mm files. The old genstrings would just silently ignore nonexistent files (e.g. a filename of literally “*.mm” as some shells will pass when expansion fails). Now it produces an error.
I expect my existing working scripts using "genstrings *.m *.mm" to work, since it would find at least one of those types in every source folder.
Nonetheless, somehow the string “*.mm” is being passed to genstrings. Since a file of that name does not exist, genstrings produces an error about that file rather than silently ignoring it.

Can you share the exact text of your script as well as the exact shell under which it’s being run?

-- Chris


Chris Hanson
 

On Oct 2, 2019, at 7:37 AM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote

But it's how genstrings works. It accepts multiple files. This works:

genstrings -q -o Base.lproj *.m *.h

This does not:

genstrings -q -o Base.lproj *.m *.mm

And neither does this:

genstrings -q -o Base.lproj *.mm
Tools on UNIX do not perform shell wildcard expansion themselves, the shell does that before the tool is ever called. genstrings is no different in that regard; to my knowledge it has never done shell expansion, and I can assure you that it does not perform shell expansion now.

Are there files matching the pattern *.mm in the directory in which you’re invoking genstrings? If not, some shells will pass the raw “*.mm” to genstrings, others will produce an error before invoking genstrings.

-- Chris

PS - Strings files should not be put into Base.lproj; an asset type that supports Base Internationalization has localized strings substituted into it at either build or runtime, like a xib or storyboard or Siri intent definition. Strings should always be in a concrete lproj.


Gary L. Wade
 

Have you tried using the find command instead?
--
Gary L. Wade
http://www.garywade.com/

On Oct 2, 2019, at 11:03 AM, Chris Hanson <cmhanson@eschatologist.net> wrote:

On Oct 2, 2019, at 7:37 AM, Steve Mills via Groups.Io <sjmills=mac.com@groups.io> wrote

But it's how genstrings works. It accepts multiple files. This works:

genstrings -q -o Base.lproj *.m *.h

This does not:

genstrings -q -o Base.lproj *.m *.mm

And neither does this:

genstrings -q -o Base.lproj *.mm
Tools on UNIX do not perform shell wildcard expansion themselves, the shell does that before the tool is ever called. genstrings is no different in that regard; to my knowledge it has never done shell expansion, and I can assure you that it does not perform shell expansion now.

Are there files matching the pattern *.mm in the directory in which you’re invoking genstrings? If not, some shells will pass the raw “*.mm” to genstrings, others will produce an error before invoking genstrings.

-- Chris

PS - Strings files should not be put into Base.lproj; an asset type that supports Base Internationalization has localized strings substituted into it at either build or runtime, like a xib or storyboard or Siri intent definition. Strings should always be in a concrete lproj.