Qt5 is it possible to define more than one build configuration? - qt

I am working on application for Mac OS written in C++ using Qt5.7.1, which is distributed both as direct download from website and through App Store.
Now I have a new requirement to add self-update to the application. Which would require building two different versions of application - one for App Store (without self-update mechanism) and one for direct download (with self-update).
I have no problem to implement the self-update, but I am stuck with making a separate build configuration. So the question is -- in Qt5 is it possible to define two separate Release configurations (in a single .pro file) and if yes, then how? It also needs to work with qmake since the builds are automatic (with Jenkins).

You cannot really define 2 Release configurations in a .pro file.
However you can define different configuration options in your .pro file like this:
foo {
#something
DEFINES += FOO
} else {
#something else
DEFINES += NOT_FOO
}
bar {
#another thing
DEFINES += BAR=42
}
And then when you run qmake, add either CONFIG+=foo or CONFIG+=bar or both.
Finally in QtCreator you can define as many build profile as you want and customize the call to qmake for each profile by adding or not CONFIG+=foo options.
For more information check qmake's CONFIG documentation, especially the last example.

Related

How to have QFileSelector select files based on device

Reading the QFileSelector Class documentation, I see:
QFileSelector is a convenience for selecting file variants based on platform or device characteristics
I am successfully using the related QQmlFileSelector class to select a set of files based on if I am building for Mac (a +mac directory).
However, I need to also build for Ubuntu Desktop and an embedded device which is also running Ubuntu. Therefore, I cannot just add another platform directory directly related to ubuntu.
Based on the reference to device characteristics in the documentation, I figure I can create a folder directly related to the device.
I have a Kit setup for the embedded device and a Device used by the kit named Ansible.
Can anyone provide further details on how I can have QQmlFileSelector select the files in a + folder when building for Ansible?
You can add your own selectors using any name you want. Here's an example:
QQmlFileSelector *selector = QQmlFileSelector::get(engine);
QStringList options;
if (usingAnsible())
{
options << "ansible";
}
else
{
options << "x86";
}
selector->setExtraSelectors(options);
Then your files would be in either the +ansible or +x86 directory.

Yaml pipeline. How to swap connstrings in Builds with Console App

I built a console app with .Net Core 3.1. I have it building using Yaml leaning heavily on the learn.microsoft.com documentation. The release is pushing to the correct box. But I have an appsettings.json file that has a conn string variable that is different between my TEST, QA and PROD regions. I knew how to do this with the xml file transforms in .NET and MVC but I can't get this to work. Any help would be great since I don't even know the term for what I am trying to do here.
How do you change the connectionstring in the appsettings.json based on a variable or do I have to create 3 branches each with settings and create 3 build and release pipelines?
Thank you.
In order to push to different environments you usually
Have seperate release pipelines that trigger from different branches.
You have one release pipeline with different stages that need pre-approval to move to the next stage TEST -> QA -> PROD.
In both cases you will make use of Stage.
There you need to add a task named "File transformation"
In the File Format select JSON
Now, any variable found in the appsettings.json file will be replaced by the variables you set in the pipeline.
Be careful because nested variables like
{
SerilogSettings: {
BatchSize: 100
}
}
need to be set with a "." instead like
SerilogSettings.BatchSize

SBT - watch different sources depending on Task

In a cross Scala JS server / client project, I want changes of some sources to restart the server and other sources to trigger the packaging process, but without the restart. Different tasks will not help because they will simply do one or the other and I want both at the same time.
In more detail:
I've got a Scala.js crossProject. I'm using the following to ensure the server can serve the built JavScript:
val app = crossProject.settings(...)
lazy val appJS = app.js
lazy val jsFile = fastOptJS in(appJS, Compile)
lazy val appJVM = app.jvm.settings(
(resources in Compile) += jsFile.value.data,
(resources in Compile) += jsFile.value.data.toPath.resolveSibling(jsFile.value.data.name+".map").toFile,
(resources in Compile) += (packageJSDependencies in(appJS, Compile)).value
)
If I run ~ appJVM/compile:packageBin::packageConfiguration then changes to the JavaScript source are immediately compiled and placed in the appJVM target/classes dir, so a refresh of the browser gets my new code - brilliant.
However, I would also like to use the sbt-revolver plugin to restart the server if I edit server-side code. But there's the rub - if I use ~ ;appJVM/compile:packageBin::packageConfiguration;appJVM/reStart then changes to the client side source restart the server, which I don't want. But if I remove the client side project from the transitive watch then it no longer notices if I change the client side project.
Is there a way to define watchTransitiveSources differently per task?
~ is actually a command that watches the transitive sources of the base project and then synchronously runs everything passed as an argument to it when those change, before re-running the original input (including ~). It does not make any information about what has changed available to those command line inputs (difficult to see how it could).
Consequently the solution I came to is to write a new watch command. It also needs to watch all sources, but then conditionally choose what to do based on which files have changed.
I've hacked something ugly as anything together that does this, but will look at making it more legible, general, tested and a Plugin. However, in the meantime anyone trying to follow my path can use this public gist: https://gist.github.com/LeisureMonitoringAdmin/0eb2e775e47b40f07d9e6d58d17b6d52
Are you sure you are using sbt-resolver not sbt-revolver ?
Because the second one allows controlling the triggered resources using
watchSources - defines the files for a single project that are
monitored for changes. By default, a project watches resources and
Scala and Java sources.
watchTransitiveSources - then combines the
watchSources for the current project and all execution and classpath
dependencies (see .scala build definition for details on interProject
dependencies).
Source: http://www.scala-sbt.org/0.13/docs/Triggered-Execution.html

sbt-native-packager bashScriptExtraDefines profiles

I want to create some kind of "branding" for scala application using sbt-native-packager.
The idea is to configure two profiles in sbt (aprofile and bprofile) and when calling specific
target it defines correct configuration file to be used when starting application.
Two configuration files
conf/a.config
conf/b.config
I want to package application using following keys
sbt aprofile:stage
sbt bprofile:stage
Sbt-native-profile defines
bashScriptExtraDefines += """addJava "-Dconfig.file=${app_home}/../conf/app.config""""
Now the question is how to create those two profiles in sbt to define bashScriptExtraDefines property accordingly. I am trying to use https://stackoverflow.com/a/20573422/289043 somehow, however I don't know how to correctly overwrite bashScriptExtraDefines.

The workspace with the iOS project and related a static library project

I am fighting with Xcode 4 workspaces. Currently Xcode 4 wins. Thus, my situation:
I have the workspace with the iOS app project. There is also static library project iOS app depends on in the this workspace.
Solution #1
I try to configure like this:
the app project:
add to target's Build Phases > Link Binary With Library a product (libmystaticlib.a);
set USER_HEADER_SEARCH_PATHS to $(TARGET_BUILD_DIR)/usr/local/include $(DSTROOT)/usr/local/include;
the static library project:
add some header files to target's Build Phases > Copy Headers > Public;
set SKIP_INSTALL to YES.
And important thing: both projects must have configurations named the same. Otherwise, if I have, e.g., configuration named Distribution (Ad Hoc) for the app and Release for the static library, Xcode can't link the app with the library.
With this configuration archiving results to an archive with the application and public headers from static library projects. Of course, I am not able to share *.ipa in this case. :(
Solution #2
I have also tried another configuration:
Xcode preferences:
set source tree for the static library, e.g, ADDITIONS_PROJECT;
the app project:
add to target's Build Phases > Link Binary With Library a product (libmystaticlib.a);
set USER_HEADER_SEARCH_PATHS to $(ADDITIONS_PROJECT)/**;
the static library project:
don't add any header files to Public!;
set SKIP_INSTALL to YES.
I still need to care about configuration names for both projects. But in result I can build and archive successfully. In the result I get archive and I can share *.ipa.
I don't like the second solutions, because in this case I don't get any real advantage of the Xcode 4 workspace. The same effect I can add get, if I add the static lib project inside the app project. Therefore, I think something is wrong with my solution.
Any suggestion how better to link a static libraries?
I also found a solution that works with build and with archive.
In your static library set the Public Headers Folder Path to ../../Headers/YourLib
In your app config set the Header Search Paths to $(BUILT_PRODUCTS_DIR)/../../Headers
In your app you will be able to code #import <YourLib/YourFile.h>
Don't forget the Skip Install = YES option in your static lib.
We've found an answer, finally. Well, kind of. The problem occurred because Xcode 4 places public headers into InstallationBuildProductsLocation folder during build for archive. Apparently, when archiving it sees the headers and tries to put them into archive as well. Changing Public Headers Folder Path of the lib to somewhere outside of InstallationBuildProductsLocation, for example, to $(DSTROOT)/../public_folders and adding this path to Header Search Path solve the problem.
This solution doesn't look very elegant, but for us it seems to be the only option. May be you'll find this useful.
Here is a solution a get from Apple DTS. I don't like it, because it is suggests to use absolute path. But I still publish it here, maybe someone feels it is right for him.
How to set up the static library:
Add a build configuration named "Archive" by copying the Release Configuration.
Move your headers to the Project group of the Copy Headers build phase.
Set the Per-configuration Build Products Path of the "Archive" configuration to $(BUILD_DIR)/MyLibBuildDir. Xcode will create the MyLibBuildDir folder inside the BuildProductsPath, then add your static library into that folder. You can use "MyLibBuildDir" or provide another name for the above folder.
Set Skip Install to YES for all configurations.
Set Installation Directory of "Archive" to $(TARGET_TEMP_DIR)/UninstalledProducts.
Edit its scheme, set the Build Configuration of its Archive action to "Archive."
How to set up the project linking against the library:
Add a build configuration named "Archive" by copying the Release Configuration.
Set the Library Search Paths of "Archive" to $(BUILD_DIR)/MyLibBuildDir.
Set the User Header Search Paths to the recursive absolute path of your root of your workspace directory for all configurations.
Set Always Search User Paths of "Archive" to YES.
Set Skip_Install to NO for all configurations.
Edit its scheme, set the Build Configuration of its Archive action to "Archive."
I was not real happy with any of the other solutions that were provided, so I found another solution that I prefer. Rather than having to use relevant paths to put the /usr/local/include folder outside of the installation directory, I added a pre-action to the Archive step in my scheme. In the pre-action I provided a script that removed the usr directory prior to archiving.
rm -r "$OBJROOT/ArchiveIntermediates/MyAppName/InstallationBuildProductsLocation/usr"
This removes the usr directory before archiving so that it does not end up in the bundle and cause Xcode to think it has multiple modules.
so far I also struggled with the same problem, but did come to a solution with a minimal tradeoff:
This requires Dervied Data to be your Build Location.
I set the Public Headers Folder path to ../usr/local/include
This will ensure, that the headers will not be placed into the archive.
For the app, I set the Header Search Path to:
$(OBJROOT)/usr/local/include
$(SYMROOT)/usr/local/include
There are 2 entries necessary since the paths slightly change when building an archive and I haven't figured out how to describe it with only one variable.
The nice thing here is, that it doesn't break code sense. So except for having 2 entries rather than one, this works perfectly fine.
I'm struggling with the same problem at the moment. I didn't progress much farther than you. I can only add that in the second solution you can drag headers you need to use from the library to the app project, instead of setting ADDITIONS_PROJECT and USER_HEADER_SEARCH_PATH. This will make them visible in app project. Value of SKIP_INSTALL flag doesn't matter in this case.
Still, this solution isn't going to work for me, because I'm moving rather big project, with dozens of libraries, from Xcode 3 to Xcode 4, and it means really a lot of drag and drop to make my project build and archive correctly. Please let us know if you find any better way out of this situation.
I could use Core Plot as a static library and workspace sibling, with two build configurations:
Release:
in project, Header Search Path: "$(BUILT_PRODUCTS_DIR)"
in CorePlot-CocoaTouch, Public Headers Folder Path: /usr/local/include
AdHoc (build configuration for "Archive" step in Scheme, produces a shareable .ipa):
in project, Header Search Path: "$(BUILT_PRODUCTS_DIR)"/../../public_folders/**
in CorePlot-CocoaTouch, Public Headers Folder Path: ../../public_folders
Hope it will help someone to not waste a day on this.

Resources