Skip to content

Instantly share code, notes, and snippets.

@j-ulrich
Last active February 11, 2023 16:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j-ulrich/a8175e8f0db404d452c3314c28af1b81 to your computer and use it in GitHub Desktop.
Save j-ulrich/a8175e8f0db404d452c3314c28af1b81 to your computer and use it in GitHub Desktop.
Qbs Conan ModuleProvider
[requires]
poco/1.6.1
yajl/2.1.0
expat/2.2.0
import qbs
import qbs.File
import qbs.FileInfo
import qbs.TextFile
ModuleProvider {
relativeSearchPaths: {
var conanPackageDir = FileInfo.cleanPath(FileInfo.joinPaths(outputBaseDir, "../../..", "genconan"));
var dirs = File.directoryEntries(conanPackageDir, File.AllDirs | File.NoDotAndDotDot);
var packageVersions = {};
/*
* The generated conanbuildinfo.json files are inside of the 'genconan' folder in the build directory.
* Since there might be more than one, they're placed inside of folders with a hashed name to avoid conflicts.
* Here we have to iterate over those folders and process the json files within.
*/
for(d in dirs){
var conanbuildinfo = FileInfo.joinPaths(conanPackageDir, dirs[d], "conanbuildinfo.json");
if(!File.exists(conanbuildinfo))
continue;
var file = new TextFile(conanbuildinfo, TextFile.ReadOnly);
var fileContent = JSON.parse(file.readAll());
file.close();
var deps = fileContent.dependencies;
for(i in deps){
if(packageVersions[deps[i].name]){
if(deps[i].version != packageVersions[deps[i].name]){
console.error("Conan package '" + deps[i].name + "' found in multiple conanfile.txt's with different versions: " +
packageVersions[deps[i].name] + " and " + deps[i].version);
return [];
}
console.info("Already generated module for conan package '" + deps[i].name + "', skipping...")
continue;
}
console.info("Generating module for conan package '" + deps[i].name + "'");
packageVersions[deps[i].name] = deps[i].version;
var moduleDir = FileInfo.joinPaths(outputBaseDir, "modules", name, deps[i].name);
File.makePath(moduleDir);
var moduleFile = new TextFile(FileInfo.joinPaths(moduleDir, deps[i].name + ".qbs"), TextFile.WriteOnly);
moduleFile.write("import qbs\n" +
"Module {\n" +
"\tproperty bool installBin: false\n" +
"\tproperty bool installLib: false\n" +
"\tproperty bool installRes: false\n" +
"\tproperty bool installInclude: false\n" +
"\tproperty string binInstallDir: \"bin\"\n" +
"\tproperty string libInstallDir: \"lib\"\n" +
"\tproperty string resInstallDir: \"res\"\n" +
"\tproperty string includeInstallDir: \"include\"\n" +
"\tproperty stringList binFilePatterns: [\"**/*\"]\n" +
"\tproperty stringList libFilePatterns: [\"**/*\"]\n" +
"\tproperty stringList resFilePatterns: [\"**/*\"]\n\n" +
"\tproperty stringList includeFilePatterns: [\"**/*\"]\n\n" +
"\tDepends { name: \"cpp\" }\n\n" +
"\tcpp.includePaths: " + JSON.stringify(deps[i].include_paths) + "\n" +
"\tcpp.libraryPaths: " + JSON.stringify(deps[i].lib_paths) + "\n" +
"\tcpp.dynamicLibraries: " + JSON.stringify(deps[i].libs) + "\n" +
"\tcpp.defines: " + JSON.stringify(deps[i].defines) + "\n\n");
function writeGroups(file, moduleName, prefix, pathList){
for(j in pathList){
file.write("\tGroup {\n" +
"\t\tname: \"" + prefix + (j > 0 ? j : "") + "\"\n" +
"\t\tprefix: \"" + FileInfo.fromNativeSeparators(pathList[j]) + "/\"\n" +
"\t\tfilesAreTargets: true\n" +
"\t\tqbs.install: product.conan." + moduleName + ".install" + (prefix.charAt(0).toUpperCase() + prefix.substring(1)) + "\n" +
"\t\tqbs.installPrefix: \"\"\n" +
"\t\tqbs.installDir: product.conan." + moduleName + "." + prefix + "InstallDir\n" +
"\t\tqbs.installSourceBase: \"" + FileInfo.fromNativeSeparators(pathList[j]) + "\"\n");
file.write("\t\tfiles: product.conan." + moduleName + "." + prefix + "FilePatterns\n" +
"\t}\n");
}
}
writeGroups(moduleFile, deps[i].name, "bin", deps[i].bin_paths);
writeGroups(moduleFile, deps[i].name, "lib", deps[i].lib_paths);
writeGroups(moduleFile, deps[i].name, "res", deps[i].res_paths);
writeGroups(moduleFile, deps[i].name, "include", deps[i].include_paths);
moduleFile.writeLine("}");
moduleFile.close();
}
}
return [""];
}
}
import qbs.Probes
import qbs.FileInfo
Project {
/* Define the path to the conanfile via a Probe */
Probes.ConanfileProbe {
id: thirdPartyConanPackages
conanfilePath: FileInfo.joinPaths(path, "conanfile.txt")
}
/* Controls which and how conan packages are copied to the install-root */
Product {
name: "install-conan-packages"
Depends { name: "conan.poco" }
conan.poco.installBin: true
}
/* A product that uses a conan package */
Product {
name: "my-product"
Depends { name: "conan.poco" }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment