Using premake with multi localizations - localization

I work with premake 5 for few days now. I'm currently trying to port our VS2015 solution (mainly C++ native and CLI projects) to a premake 5 solution. I had no problem so far but now I'm not able to build resource libraries for all languages we localize our assemblies to. For example, if we have fr and es (for French and Spanich), we should have an assembly split like this:
foo.dll (default, English),
satellites foo.resources.dll for each other languages (separated in different folders of course).
But I'm not able (read: I don't know how) to write the lua script correctly.
Does someone know how to generate localized (AKA satellite) assemblies with premake5?
Thanks for your help!
EDIT 1
I added this to my lua script:
files({"/**.resx"})
It added the .resx files to the .vcxproj file but rather than being included like this:
<EmbeddedResource Include="bar.resx"/>
they are included like this:
<None Include="bar.resx"/>
What's going on?
EDIT 2
I then added:
filter "files:**.resx"
buildaction "Embed"
But it remains the same. I found in premake 5 doc that buildaction was only supported in C# (my code is in C++/CLI). If this is true (it seems to be) is there a way to go deeper with my script to add, say, XML entries directly to the .vcxproj?

Well... after a lot of tries, I found a way. I just added a new (file) category for EmbeddedResource like this:
premake.vstudio.vc2010.categories.EmbeddedResource = {
name = "EmbeddedResource",
extensions = {".resx"},
priority = 50, -- arbitrary number, I saw priorities are 0, 1, 2...
emitFiles = function(prj, group)
premake.vstudio.vc2010.emitFiles(
prj,
group,
"EmbeddedResource",
{premake.vstudio.vc2010.generatedFile} -- cannot explain this...
)
end,
emitFilter = function(prj, group)
premake.vstudio.vc2010.filterGroup(prj, group, "EmbeddedResource")
end
}
Hope it can help...

Related

Xcode Localizable.string multiple targets issue

I have a project with multiple targets, which represent the same app just with different styling and translations.
Since almost whole project looks the same for each target, I need to have just few strings in Localizable.strings file, that I need to be different. And I don't want to copy whole huge Localizable.strings file to each project just because of the fact it has few lines different.
It is required for me to have just 1 strings file because of third-party libraries/SDK that are included in project. So I cannot use tableName for localizedString.
The problem is - I need to have a flexible possibility to override just few lines from Localizable.strings for each target separately. And I don't like the idea just to copy whole file to each target, cause it will lead to annoying flow in the future, in case I will have 10 targets and I need to add 1 string to all of them.
The goal is to have 1 huge Localizable.strings file with all strings included, that would be common for all targets, and have small configuration for each target for the strings that should tell different. So target's file should kinda merge and override the one that is common.
AFAIK it is not natively supported by Xcode, so I'm probably looking for a script that would make it works.
So, script should look into common and target's Localizable files, merge them, and in case some keys are defined in both, then it should use the one from target's file.
Can anyone help me with such script?
P.S. Similar issue exists with .xcassets, and CocoaPods solves it by merging multiple assets into 1, and it works as expected - if some targets has an asset containing the image with the same name that is already included into a common asset, then the one from target will replace it.
P.S.2. Similar feature is natively supported for Android devs - each image, each translations can be overridden by "child" flawor, or whatever it is called :)
TL;DR:
Example project: https://github.com/JakubMazur/SO45279964
OK, the easier thing to do would be shell/python script, because it will work for every build server. I assume that you have a different scheme for each target (otherwise it will make no sense). So what you can do is:
Let's say your target is named:
target1
target2
target3
1) Create separate files contains all the strings that should be different (i will put it under Localizable directory.
Your Localizable.strings file may look like this:
"someGeneralString" = "General string 1";
"AppName" = "This is a string that you probably need to change";
"someOtherGeneralString" = "General string 2";
And any of your targetX.strings file may look like this:
"AppName" = "target[x]"
And here is how it should look like in your project:
Note that your target localizable files should has target membership set only to one target, but your Localizable.strings should be for all targets!
That's all for project configuration. Let's go to scripting (I will use python for that):
#!/usr/bin/python
import sys
supportedLanguages = ["en","pl"]
commonPath = ".lproj/Localizable.strings"
keys = ["AppName"]
class CopyLocalizable():
target = ""
def __init__(self,arg):
self.target = arg
self.perform()
def perform(self):
for lang in supportedLanguages:
pathToLocalizable = lang+commonPath
textToFile = ""
with open(pathToLocalizable,"r") as languageFile:
for line in languageFile.readlines():
for key in keys:
if key in line:
textToFile += self.foundAndReplace(key,lang)
else:
textToFile += line
self.saveInFile(pathToLocalizable,textToFile)
def foundAndReplace(self,key,lang):
pathToTargetFile = "Localizable/"+lang+".lproj/"+self.target+".strings"
with open(pathToTargetFile,"r") as targetFile:
for targetLine in targetFile.readlines():
if key in targetLine:
return targetLine
def saveInFile(self,file,stringToSave):
with open(file,"w+") as languageFile:
languageFile.write(stringToSave)
You can optimize it yourself. It's easier script i can think about to get a job done.
And in the end let's automate it a bit:
- Go to your target
- add a new build phase
- Add a new script:
export PATH="/usr/local/bin:$PATH"
cd SO45279964/
python localize.py target[x]
and watch a magic happen ;)
http://www.giphy.com/gifs/26n6NKgiwYvuQk7WU
Here you can find example project that I've created to run this example:
https://github.com/JakubMazur/SO45279964
To keep it simple, Have a Macro defined for each target in Build Settings & define target specific strings within macro section like
#ifdef __TARGET__
//key values in localizable file
#endif

JacORB: changing prefix and suffix

I would like to change package prefix and suffix in my ant build while generating java from idl. This has to be generic solution! The idea goes like that:
I have idl files (ONE.idl, TWO.idl) with namespace ONE_cb in first and TWO_cb in second (as _cb suffix is required for c++ compatibility). TWO_cb has atributes from ONE_cb, ONE_cb has only basic types. I want to change that to packages going like com.example.ONE and com.example.TWO.
I'm using JacORB 3.6. and I don't know how to do it.
My code looks like that:
<target name="idlj-generate">
<idl2java
srcdir="${psm.dir}/${project}/"
destdir="${build.generated.dir}"
includepath="${psm.dir}"
all="true">
<define key="__JACORB_GENERATE__"/>
<i2jpackage names=":com.example"/>
<i2jpackage names="_cb:"/>
</idl2java>
</target>
It doesn't work. As I stated before it has to be generic solution. adding
<i2jpackage names="TWO_cb:TWO"/> //option 2
<i2jpackage names="ONE_cb:ONE"/> //option 2b
Is not acceptable
Thank you for Your time.
If I understand you correctly you have something like
module ONE_cb
{
...
}
but you want it to be
com.example.ONE { ... }
This is feasible with i2jpackage e.g.
idl -forceOverwrite -d /tmp/generated -i2jpackage ONE_cb:com.example.ONE myfile.idl
The problem you have is that you are compiling both files at once. Remove the "all" and try compiling them in two phases.
If you are using Maven I would also recommend trying org.codehaus.mojo:idlj-maven-plugin as you can do multiple executions very easily with that.
To use multiple i2jpackage I got it working with
idl -forceOverwrite -d /tmp/generated -all -i2jpackagefile /tmp/file antBugJac608-2.idl
(where antBugJac608-2 #includes antBugJac608).
For various research I concluded that generic solution is immpossible.
Only way to perform changing prefix and suffix the same time is to explicite set all included names.

Xcode 5: Set symbolic breakpoints programatically

Symbolic breakpoins are great, but it's a hassle to manually add then in xcode. Well, after you add one, you can just enable/disable them, but it would be nice to be able to do it in code... something like this:
#if DEBUG
SetBreakPointForFunction([Myclass myfunction], BreakPointActionPlaySound);
#endif
Is this possible?
https://developer.apple.com/library/ios/recipes/xcode_help-breakpoint_navigator/articles/setting_breakpoint_actions_and_options.html
Not in code exactly, but you might be able to create breakpoints during the debug build phase with a shell script (Or have the shell fire python, ruby, whatever… to do the work.)
If you peek inside the .xcodeproj folder, you'll see it has paths like:
[projectName].xcodeproj/xcuserdata/[userName].xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
[projectName].xcodeproj/xcshareddata/xcdebugger/Breakpoints_v2.xcbkptlist
(disclaimer, this example references xcode 5.1.1)
The contents of the files are fairly straightforward:
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "4"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
<BreakpointContent
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
symbolName = "-[ActivitySpanner thresholdTimePassed]"
moduleName = "">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>
So, by stuffing instances of BreakpointProxy into one of these files, you might apply a library of favorite breakpoints. Duplicates could be a pain, either push and pop the file or check for the instance first.
At worst, if xcode can't be forced to re-read the xcbkptlist files when they are changed by your script, then you could have a script that manipulates the breakpoint files, and then opens the project. (Perhaps overkill, we've gotten into the territory of continuous integration tools like Jenkins now :)

Auto rename compiled file in Delphi XE2

I use Delphi XE2 and I have a project called PGetBase. In this project, there is a module with a constant declaration. For example:
const
   FragH = 5;
   FragW = 4;
...
After compiling, the file is called PGetBase.exe. Is it possible to make the name of the build file dependent on the constants declared in the module, e.g. PGetBase_5_4.exe, by making use of a Post-Build event?
Add a project to the projectgroup which creates an executable that uses the same unit and changes the filename. Build and run that executable in the Post-Build event.
Microsoft Build knows nothing about the Pascal language and cannot parse the sources.
However you may extract "5" and "4" into some external text files.
const
FragH =
{$I Frag_h.txt}
;
FragW =
{$I Frag_W.txt}
;
Then make a simple program (or script: WSH, PowerShell, etc), that would be launched from post-build events.
You program would read those file and rename the Delphi-made PGetBase.exe to anything you wish.
PS. Of course one can parse the source unit to regain those constants, rather than offloading them into external storage. Comments hold the discussion pro et con.
PPS. NGLN came wit ha neat idea. Rather than parsing the file, you can just include that unit as part of your renamer project. Then you can add a pre-build event, that would compile(make) renamer and in post-buid the renamer would have those constants within itself. While calling make/dcc32 would probably be slower than just parsing the sources from inside the version-neutral pre-compiled renamer.exe, that NGLN's approach is elegant and self-contained in its own way.

Delphi .res file changer

I'm looking for a ready-to-use piece of code that would be able to read and modify Delphi .res files. The thing is that I need to create an application that will be compiling many Delphi projects at once (using the dcc32.exe file). However, it is necessary for me to change file version and language before compilation, and as far as I know, I have to modify the .res file to do that.
Have you come across any code that would give me an interface to .res files allowing me to modify the data contained in it? The thing is that I want to change only those two pieces of information keeping the rest unchanged. This is why I can't compile my own .res file based on a script.
An application executed from a command line would also be OK if it allows to be called with parameters and does what I need it to do.
Thank you very in advance!
If all you need is to add file version resource then create appver.rc file, compile it with brcc32 and in one of your app unit (for example appver.pas) add {$R appver.res} (as Marian noticed you must turn off Delphi project option to include version info).
I created command line programs that increase build numbers in .rc file, create new branch/tag in SVN with new version in branch name, compiles .rc to .res, and build application.
My .rc files with such info (Polish language) looks like:
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO LOADONCALL MOVEABLE DISCARDABLE IMPURE
FILEVERSION 7,28,7,17
PRODUCTVERSION 7,28,7,17
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
{
BLOCK "StringFileInfo"
{
BLOCK "041504E2"
{
VALUE "CompanyName", "xxx\0"
VALUE "FileDescription", "yyy\0"
VALUE "ProductName", "zzz\0"
VALUE "FileVersion", "7.28.7.17\0"
VALUE "ProductVersion", "7.28.7.17\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0415, 1250
}
}
For all things .res, look at Colin Wilson's "XN Resource Editor", for which he provides the source code: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm
And probably all you need is his resource utility library:
http://www.wilsonc.demon.co.uk/d9resourceutils.htm
I haven't used this source, but if I needed it, that's the first place I'd look. His resource editor is very useful, btw.
There is ChangeRes which seems to match your needs.
Check out sources:
http://code.google.com/p/gedemin/source/browse/trunk#trunk/Gedemin/Utility/IncVerRC
It is our utility which reads .RC file with version information and increments build number. We use it inside our build process. Here is an excerpt:
incverrc.exe ..\gedemin\gedemin.rc
"%delphi_path%\brcc32.exe" -fogedemin.res -i..\images gedemin.rc
"%delphi_path%\dcc32.exe" -b gedemin.dpr
The utility uses TIncVerRc class written by Chris Morris.
Check Resource Tuner Console on www.heaventools.com. They position that product for tasks like yours. Also there's a free rcstamp tool on CodeProject.

Resources