[ create a new paste ] login | about

Link: http://codepad.org/u11XS6PM    [ raw code | fork ]

C++, pasted on May 27:
// ^^^^^^^^^^^^^^^^ this is module part, this goes somewhere into your global project files ^^^^^^^^^^^^^^^^^^^^
import qbs
import qbs.FileInfo
import qbs.File
import qbs.Utilities

Module {
        // this uses an external dependency "conditionals " to inject some properties 
        // will vary depending on where you store it or you can drop it altogether
	qbsSearchPaths: product.sourceDirectory + "/../../modules"
        // protobuf is very finicky about where you invoke it from. 
	// can't just do it from where its executable, or .proto files are stored
	// this varable needs to be passed from outside
	property string rootDir: ""
        // to disable some compiler warnings we need to know which is used on .cpp files
	property var toolchain: []
        // see rootDir comment
	property string generationDir: ""
        // path to where protobuf stores its custom types
	property string protobufDependencyDir: ""

    Rule {
                // this is what makes a rule pick up your proto files in files where 
		// this module is referenced
		inputs: ["proto"]
        
		Artifact {
                    // this is the name for the resulting artifact.  
                    filePath: FileInfo.path(input.filePath)  + '/' + FileInfo.baseName(input.fileName) + '.pb.cc'
		
                    // flags: "cpp" makes them auto picked up  by further modules to be automatically compiled into your project 
                    fileTags: "cpp"
            
                    // disabling some gcc whining
		    cpp.cxxFlags: {
                    var flags = []
                    if(!input.moduleProperty('proto_generation', 'toolchain').contains("msvc"))
                        flags = [ "-Wno-unused-variable", "-Wno-unused-parameter"]
                    return flags
            }
        }

        prepare: {
            // we need to know where protoc is stored if it isn't in the PATH
            // I prefer to manually set this path in .qbs anyway
	    var protoc = product.moduleProperty('conditionals', 'protoc');

            // use of canonicalFilePath is discourage because it might break on symlinks
            // iirc canonicalFilePath transforms ../ relative file paths into absolute which is important
	    // since your .proto files are liekly to use relative 
            // note that we can't directly reference proto_generation module properties here and have to pick them up via input.
            var rootDir = File.canonicalFilePath(input.moduleProperty('proto_generation', 'rootDir'))
            var generationDir = File.canonicalFilePath(input.moduleProperty('proto_generation', 'generationDir'))
            var pbDependencyDir = File.canonicalFilePath(input.moduleProperty('proto_generation', 'protobufDependencyDir'))
			
            // the rest is more or less self explanatory 
	    if(generationDir === "")
                generationDir = rootDir

            var protoArgs = [];
            protoArgs = protoArgs.concat(["--proto_path=" + rootDir]);
            protoArgs = protoArgs.concat(["--proto_path=" + pbDependencyDir]);
            protoArgs = protoArgs.concat(["--cpp_out=" + generationDir]);
            protoArgs = protoArgs.concat(input.filePath);

            var protoCommand = new Command(protoc, protoArgs);
            protoCommand.description = 'Generating classes from: ' + input.fileName;

            return [protoCommand];
        }
    }
}




// then in the Product
// this reference basically plugs in generation module and automatically makes qbs know what to do with .proto files
Depends { name: "proto_generation" }

// you reference the files that are used for generation, slap a tag that module knows onto them
// and when the build starts they are pick automatically and the results are _automatically_ injected  
// into your sources. no further referencing of resulting .cpp files in .qbs file is needed
Group{
        name:"proto files"
        files: [
            "../ParserLib/proto/error.proto",
        ]
        // note that module settign are on a PER GROUP basis
	// you can totally have different groups with different settings within a single product
	proto_generation.rootDir:sourceDirectory + "/proto"
        proto_generation.protobufDependencyDir: sourceDirectory + "/../../external"
        proto_generation.toolchain:  qbs.toolchain
        fileTags: ["proto"]
    }


Create a new paste based on this one


Comments: