[QBS] propagate compiler options

Marcel Mulder marcel.mulder at xs4all.nl
Sat Jan 17 21:25:12 CET 2015


Hi Thomas,

Many thanks for your input.
Your solution works but I bumped into a few problems.

The include path. 

In YourProject.qbs I also added a property MyIncludePaths like 
	property stringList myIncludePaths: [ ”." ]
But if I use that in for example product A, than “.” is expanded to the directory location of A.qbs. This is quite logical. So I changed it into:
	property stringList myIncludePaths: [ path ]
But I read in the mail list that using path is deprecated. What is the future way to go? Using sourceDirectory?

Dependenties

I have for example application A which depend on static library B and C. Static library B depends on static library C. No problem yet but now static library C depends on B. Now we have a problem because of creating a loop. This is however not uncommon. Most RTOSes will have such kind of dependencies. Not dependent on code but depended on header files. E.g.: De kernel depends on the board configuration and the board configuration is depending on the kernel. Mostly they are configuration dependenties. An RTOS exist of several modules like kernel, hal, ports, compiler configuration, linker files, board files, processor target files. They all have a relationship with each other. The end result should however be defined in the top level application. I can have 20 different applications using a different set of compiler, processor, board, memory configuration etc. So it must be defined at top level. Using all dependencies.
The solution is to propagate source files to the top level files list. Then all files are compiled with the same compiler option and flags. This is how qmake and good old Makefiles are used.
Another solution is to define everything in one qbs file. But if something changes in de libraries used than I also have to change my build file. Even though the maker of the library supplies qbs files.

The property names

The property as you proposed is a nice solution with the current implementation of qbs. The drawback is that independent projects like a RTOS, or libraries supporting qbs have to also support my naming convention of the properties. This is kind of strange that a library project is dependent of a user project file. This does not work in the real world.

And a question

What if you have application A which is depending on static library B. Now you have a define in your code and in the library code to disalbe a certain feature like:
	#ifndef DISABLE_FEATURE_A
		some code here
	#endif
So somewhere in an qbs file you have to define:
	cpp.define: [ “DISABLE_FEATURE_A” ]
How does your A.qbs and B.qbs file looks like.

I hope you understand my problem with qbs and I really want to use it. Private I will, but I don’t think we can use this at work. Which is a shame but with this kind of limitations I can’t convince my colleague's to use it.

I will do some more experimenting. Lacking time at the moment.

Regards, Marce

> 
> On 17 Jan 2015, at 13:34, Thomas Epting <thomas.epting.stryker at gmail.com> wrote:
> 
> Quick addendum:
> 
> 
> 
> You won't even need to use your own base application types, and to extend your qbsSearchPath (but providing such own types might be helpful in larger projects).
> 
> 
> 
> Just do it like this:
> 
> 
> 
> --- A.qbs ---
> 
> import qbs 1.0
> 
> Application {
> 
>     Depends { name: "cpp" }
>     cpp.cxxFlags: project.myCxxFlags.concat([ "--cxx-extra-flag" ])
> 
>     // …
> 
> }
>  
> --- L.qbs ---
> 
> import qbs 1.0
> 
> StaticLibary {
> 
>      Depends { name: "cpp" }
> 
>      cpp.cxxFlags: project.myCxxFlags.concat([ "--cxx-other-extra-flag" ])
> 
>      // …
> }
> 
>  
> --- YourProject.qbs ---
> import qbs 1.0
> 
> Project {
> 
>     references: [ "A.qbs", "L.qbs" ]
> 
>     property stringList myCxxFlags: [ "--cxx-flag1", "--cxx-flag2" ]
> 
> }
> 
> 
> 
> Regards,
> 
> Thomas
> 
> 
> 2015-01-17 13:15 GMT+01:00 Thomas Epting <thomas.epting.stryker at gmail.com <mailto:thomas.epting.stryker at gmail.com>>:
> 
> No, you don’t get it right. I want to propagate down, not up. So the parent product determines the compile options of the siblings.
> In your case Product A defines the compile options for Product C when building A and Product B defines the compile option for Product C when building B.
> Do you know how I can do that? Because when a build for example product A than product C is build with the cpp module defaults and not with the compile options of product A.
> Product C should however be able to override or add compile options.
> 
> Hi Marcel, 
> 
> Let me try to sketch a solution for your problem, which provides project-level compiler options for all references products.
> 
>  
> First, I suggest to derive from all base items you need (like Application and StaticLibrary products), and to use your own items instead of the standard ones. So instead of using Application, your application products should use MyApplication. Your static libraries should use MyStaticLibrary, and so on. Put all your derived products in a folder “qbs/imports” (you need to extend qbsSearchPaths in your main project later, in order to access these files). Your derived product definitions could look like this:
> 
>  
> --- MyApplication.qbs ---
> 
> import qbs 1.0
> 
> Application {
> 
>     Depends { name: "cpp" }
> 
>     cpp.cxxFlags: project.myCxxFlags
> 
> }
> 
>  
> --- MyStaticLibrary.qbs ---
> 
> import qbs 1.0
> 
> StaticLibrary {
> 
>     Depends { name: "cpp" }
> 
>     cpp.cxxFlags: project.myCxxFlags
> 
> }
> 
>  
> The trick is to extend “cpp.cxxFlags” by a property defined on project level. This means: (1) your project has to define such a property, otherwise loading of the Qbs project will fail. (2) Each project may define a different set of settings, which apply to ALL products referenced by it.
> 
>  
> Now let’s consider your project consists of an application A and a library L.
> 
>  
> --- A.qbs ---
> 
> import qbs 1.0
> 
> MyApplication {
> 
>     // …
> }
> 
>  
> --- L.qbs ---
> 
> import qbs 1.0
> 
> MyStaticLibary {
> 
>     // …
> }
> 
>  
> Here’s how your project definition could look like:
> 
>  
> --- YourProject.qbs ---
> 
> import qbs 1.0
> 
> Project {
> 
>     references: [ "A.qbs", "L.qbs" ]
> 
>     qbsSearchPaths: "path/to/your/qbs-folder"
> 
>     property stringList myCxxFlags: [ "--cxx-flag1", "--cxx-flag2" ]
> 
> }
> 
>  
> Of course you could extend this solution to support extra defines, include paths, or whatever you like. You could even propagate down different settings for each sub-project of your overall project, since project settings are inherited by sub-projects.
> 
>  
> Hope this helps.
> 
> Regards, Thomas
> 
>  
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/qbs/attachments/20150117/5e3e212f/attachment.html>


More information about the Qbs mailing list