Click here to Skip to main content
15,354,434 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
How do we implement some buildTypes and flavors configs for our project(library or an application).

I had a hard time finding tutorials or references about it, especially if it is implemented in kotlin-dsl. I tried to simulate the concepts from groovy and convert it to a dsl that I want, but it doesn't work well, and I'm using todays latest pre-build gradle plugin for c++(cpp-application & cpp-library). I'm not using a native-plugins such as c, windows-resouces, assember and etc.

I really want to see and Implement it to my project properly.
gradle-verion: 7.2
toolChain: MSVC-2019

What I want to had look liked this:
plugins {
    `cpp-application`
    // `cpp-library`
    // `cpp-unit-test`
}
...
application {
    ...
    //REM: how about CppStaticLibrary and others, are they have the same 
    //REM: properties and members with the CppBinary but different 
    //REM: Definition/implementation?
    binaries.configureEach(CppBinary::class.java) {
        when(toolChain) {
            is VisualCpp -> {
                //REM: I know this will not work cuz it will only 
                //REM: overwrite every iteration, But we could see what I want.
                // if(buildTypes.names.contains("DEBUG_OPTIMIZED"))
                //     this.compileTask.get().compilerArgs.set(listOf(...));
                // if(buildTypes.contains( buildTypes["RELEASE_OPT"]) && 
                //                          flavors.contains(flavors["trial"])
                //     this.compileTask.get().compilerArgs.set(listOf(...));
            }
            // is Gcc, is Clang -> {...}
        }
    }
}

buildTypes {
    // this.create("DEBUG_OPTIMIZED")
    // this.create("RELEASE_OPT")
    // this.create("RELEASE_OPT_LEVEL_7")
}

flavors {
    // this.create("paid")
    // this.create("trial")
    // this.create("open-source")
}


What I have tried:

I don't have a concrete structure of it that would work correctly...
And I'm still learning/studying every compilers inner-outer working.(most of it are the outer implementations such as the command-line args, options, and so on)
Posted
Updated 27-May-22 6:59am
v3

1 solution

I am not entirely clear on what you are asking but I'll take a shot. First, there are two kinds of libraries you can build - statically linked and dynamically lined. You define which kind(s) in the project settings of the library's solution. One project file can be configured to build both of them. There are also options for debug and release mode, 32-bit or 64-bit mode, and dynamic or static linking of the run-time libraries. There is also the possibility of multi-byte character set or Unicode. In total, that is five options with two choices for each so that means you have thirty-two possibilities with just those and there can be more that you define through your own macro definitions. Enabling logging or not is one potential option you can use.

The next issue is how you tell your program which version of the library(s) to link with. I do this through what I call a library selection header file. Here is what one of mine looks like for what I call my Extension Library :
C++
//
// ExtensionLibSel.h - header to facilitate library version selection
//

#pragma once
#define EXTENSIONLIBSEL_H
//#include "ExtensionLibSel.h"

/***
Naming convention is ExtensionWWXYZZ where :
	VV	= compiler version	: just 19 for now
	W	= build type		: D is debug,	R is release
	X	= character set		: U is unicode,	M is mult-byte
	Y	= library type		: N is dynamic,	S is static
	ZZ	= word width		: 32 or 64
 ***/

#if( _MSC_VER >= 1926 )			// VS 2019

#ifdef USE_STATIC_RTLS			// using static libraries
	#ifdef _M_X64
		#ifdef _DEBUG
			#pragma message( "linking with Extension19DMS64\n" )
			#pragma comment( lib, "Extension19DMS64" )
		#else // _DEBUG
			#pragma message( "linking with Extension19RMS64\n" )
			#pragma comment( lib, "Extension19RMS64" )
		#endif // _DEBUG
	#else // ! _M_X64 -> 32-bit X86
		#error sorry, 32-bit mode is not supported
	#endif // _M_X64
#else // USE_STATIC_RTLS		// using dynamic libraries
	#ifdef _M_X64
		#ifdef _DEBUG
			#pragma message( "linking with Extension19DMN64\n" )
			#pragma comment( lib, "Extension19DMN64" )
		#else // _DEBUG
			#pragma message( "linking with Extension19RMN64\n" )
			#pragma comment( lib, "Extension19RMN64" )
		#endif // _DEBUG
	#else // ! _M_X64 -> 32-bit X86
		#error sorry, 32-bit mode is not supported
	#endif // _M_X64
#endif	// USE_STATIC_RTLS

#else
	#error this version of Visual Studio is currently not supported
#endif
I usually use dynamic RTLs so to use this library with static RTLs, one must define the macro USE_STATIC_RTLS prior to including this file. Also, _M_X64 must defined to use that library. I don't have options for Unicode or 32-bit more builds in this file because I never use them. Those are just implementation details for using this library. Yours can be entirely different if you want them to be - that is up to you.

Using this library with the appropriate definitions allows your application to link with which ever versions of the library(s) you use is appropriate and it does so automatically through the #pragma statements. I use ten different libraries and they are all set up like this and it works very well for the fifty or so programs I work on. BTW - I first saw this technique used in the UltimateGrid library that is available at this site and it is one of the libraries I use.

Hopefully this answers the question you asked.
   
Comments
Phoenix Liveon 28-May-22 5:38am
   
Oh! It is a MACRO way of initializing/building things, it is for linking either 'dynamic' and 'static' libraries into your project using a 'toolChain: MSVC-2019 | n >=1926' and we could provide two separate sets of specific lib for DEBUG or RELEASE.

I'm really grateful for this wonderful informative solutions; this is really new to me, because I rarely read this type of pre-processor script, because if it gets bloated, it takes time to read it, but once we're done reading it, it's really easy to follow up and also just don't mind the pre-define MACRO, it is one of the main reasons I don't want to read it is that trailing those pre-defined MACROS is quite painful work of arts.

However, it is an alternative solution to my problem of looking for a Gradle build script and by using a kotlin domain specific-language. The core problem is how do we properly utilize these Gradle plugins; "cpp-application" with its features such as buildtypes and flavor extensions?

PS: double-check; can we include/push your solution within a (PCH) PreCompiled Header?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900