Qmake get the target output file path - qmake

I have a qmake project that looks like this:
TEMPLATE = lib
CONFIG += dll
TARGET = mydll
SOURCES += ...
HEADERS += ....
Now I want to add an INSTALLS section, so I have:
target.path = /path/to/somedir/
target.files =./$$TARGET
INSTALLS+= target
Unfortunately this will not work, because $$TARGET contains the target name, and not the output file name. Is there a portable way to obtain the output file name? (Please no platform dependent string concatenation like lib + $$TARGET + .so)

You don't have to specify target.files, target is a special case and it's predefined in qmake.
http://qt-project.org/doc/qt-4.8/qmake-environment-reference.html#installs
If you append a built-in install set to the INSTALLS variable and do not specify files or extra members, qmake will decide what needs to be copied for you. Currently, the only supported built-in install set is target:
target.path = /usr/local/myprogram
INSTALLS += target
In the above lines, qmake knows what needs to be copied, and will handle the installation process automatically.

Related

Xcode Projects: Is it possible to programmatically determine the path to a Library?

I have an entry like this in my pbxproj file:
146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = "<group>"; };
The part of it I'm interested is this line:
path = "../node_modules/react-native/React/React.xcodeproj";
Is there a way to modify this so I could get the path to the react-native folder programatically?
Like, if this were a bash script, I could use an expansion like so:
"$(run-some-script)/React/React.xcodeproj"
I could make a script that the user could run to automatically update the paths in the pbxproj whenever they change, but I am curious if I could have a way to have Xcode run a command to get the path to this React.xcodeproj file whenever it is opened.
Short answer is no, but you can place other source code or a library files inside the toplevel xcode project directory and then reference these files as relative paths. That way, you can link to the project relative files and then update them and the xcode build will just make use of them. For example, you can include source code that is under a completely different git repo in a subdirectory, then you can update that code differently that the toplevel source, and yet still build the whole combined project together.

qmake 4.8.4 has broken custom targets due to capitalisation. How do I work around it?

My .pro file has extra stuff in it:
win32 {
OUT_PWD_SHELL = $$replace(OUT_PWD, /, \\)
autoversion.target = $$OUT_PWD\\autoversioninfo.h
autoversion.depends = FORCE
autoversion.commands = $$PWD/../../AutoBuildVersion.exe $$replace(PWD, /, \\) $$OUT_PWD_SHELL
QMAKE_EXTRA_TARGETS += autoversion
PRE_TARGETDEPS += $$OUT_PWD\\autoversioninfo.h
}
This fails to work as expected because in the generated makefile DESTDIR_TARGET has a new dependency added that starts d:\ but the rule generated for autoversion starts with D:/. I can improve this slightly by replacing all / with \, but the case sensitivity still breaks it and the target is not built.
If I remove the full path from autoversion.target and PRE_TARGETDEPS then it solves that problem, but then when calculating dependencies, the rule for the cpp file that includes the generated header changes to give an explicit path to the header in the dependencies, and that path points to the source directory and not the output directory where the generated file is produced. This causes make to barf and not produce the generated file.
I don't know why qmake changes the case handling of the drive, it is very irritating, but how do I get this all to work correctly?
There is no good solution. The best I came up with is to use a phony target that always runs to generate the header file. On the downside this slows the build when the header file already exists, but on the upside, it allows the build to complete.
win32 {
OUT_PWD_SHELL = $$replace(OUT_PWD, /, \\)
gen_autoversion.target = GENERATE_AUTOVERSIONINFO
gen_autoversion.commands = $$PWD/../../AutoBuildVersion.exe $$replace(PWD, /, \\) $$OUT_PWD_SHELL
QMAKE_EXTRA_TARGETS += gen_autoversion
PRE_TARGETDEPS += GENERATE_AUTOVERSIONINFO
}
I am not sure that PRE_TARGETDEPS is actually needed here.

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

qmake: How to have longer version numbers in .so file name

I'm trying to build a dynamic library on Linux using qmake. Here is my .pro file:
TEMPLATE = lib
TARGET = soTest
DEPENDPATH += .
INCLUDEPATH += .
VERSION = 3.5.2.1
The problem is that when I use qmake to make the so file I get soTest.so.3.5.2, but what I need is soTest.3.5.2.1.
How can I get qmake to use the fourth number? (build number)
Thanks.
Ok,
I figured it out. I used "VER_PAT" which allowed me to put in the last octet.
Thanks.

Copy a file to the build directory after compiling project with Qt

I have a file "settings.ini" which needs to reside next to the Qt executable.
I can add a custom build step for this in Qt Creator which calls something like this:
copy %{sourceDir}/settings.ini %{buildDir}/settings.ini
This works great so far, but I'd like to include this in the *.pro file so I can put this up in our SVN too.
How can I do this using qmake/.pro-files only?
To copy %{sourceDir}/settings.ini to the build directory without requiring to call make install use:
copydata.commands = $(COPY_DIR) $$PWD/settings.ini $$OUT_PWD
first.depends = $(first) copydata
export(first.depends)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first copydata
$$PWD is the path of current .pro file. If your settings.ini file is not located in the same directory than the project file, then use something like $$PWD/more_dirs_here/settings.ini
Note: I found this solution here. I recommend to read the whole article as it explains how it works.
You probably want to use the INSTALLS keyword in QMake. It will require you to run make install after your build, but it does work cross-platform.
install_it.path = %{buildDir}
install_it.files += %{sourceDir}/settings.ini
INSTALLS += install_it
for osx bundles you can handle it this way
see Resource files in OS X bundle
add this to you project file:
APP_QML_FILES.files = path/to/file1.qml path/to/file2.qml
APP_QML_FILES.path = Contents/Resources
QMAKE_BUNDLE_DATA += APP_QML_FILES
this example copies the files to Contents/Resources
Compatible with Windows and Mac OSX Dev environments:
Change {AppName} to respective application name
# Define mac/windows specific target dirs
TARGETDIR = ''
macx {
TARGETDIR += $$OUT_PWD/{AppName}.app/Contents/MacOS/
}
else {
TARGETDIR += $$OUT_PWD
}
# Directories do not exist for the first build
# Without mkdata, build is successful after 5 tries. To avoid, use mkdata
mkdata.commands = $(MKDIR) $${TARGETDIR}
copydata.commands = $(COPY_FILE) $$PWD/settings.ini $${TARGETDIR}
first.depends = $(first) mkdata copydata
export(first.depends)
export(mkdata.commands)
export(copydata.commands)
QMAKE_EXTRA_TARGETS += first mkdata copydata
Happy to add Unix support if someone posts Unix solution in the comments.

Resources