void addBuildFileToVS(const PBXBuildFile* buildFile, VCProject& proj, const BuildSettings& bs, const VCItemHint* itemHint) { const String& compilerFlags = buildFile->getCompilerFlags(); int attribs = buildFile->getAttributes(); const PBXFile* file = buildFile->getFile(); if (!file) return; VCProjectItem* item = addFileToVSInternal(file, proj, bs, false, itemHint); // If the filetype doesn't match the file extension, specify the actual type String filePath = file->getFullPath(); String fileType = file->getFileType(); String inferredType = PBXFile::getFileType(filePath); String compileAs = getVSCompileAsType(fileType); if (item && !compileAs.empty() && (fileType != inferredType || fileType == "sourcecode.c.c" || fileType == "sourcecode.cpp.cpp")) { item->setDefinition("CompileAs", compileAs); } // Record file compiler flags if (item && !compilerFlags.empty()) { String fixedFlags = "$(AdditionalOptions) " + compilerFlags; String xcProjectDir = bs.getValue("PROJECT_DIR"); String vsProjectDir = sb_dirname(proj.getPath()); processClangFlags(fixedFlags, xcProjectDir, vsProjectDir); item->setDefinition("AdditionalOptions", fixedFlags); } // Mark public headers if ((attribs & ATTR_PUBLIC) && (fileType == "sourcecode.c.h" || fileType == "sourcecode.cpp.h")) { item->setDefinition("PublicHeader", "true"); } }
VCProject* SBNativeTarget::constructVCProject(VSTemplateProject* projTemplate) { VCProject* proj = SBTarget::constructVCProject(projTemplate); String vsProjDir = sb_dirname(proj->getPath()); // Write variables file for App targets for (auto bs : m_buildSettings) { if (getProductType() == TargetApplication || getProductType() == TargetBundle) { String configName = bs.first; BuildSettings* configBS = bs.second; // Figure out where the file should go String varsFilePath = joinPaths(vsProjDir, getName() + "-" + configName + "-xcvars.txt"); // Open a file stream to write to OFStream varsOut; openOutputFileStream(varsOut, varsFilePath); // Write the build settings out XCConfigPrinter varsPrinter(varsOut); configBS->print(varsPrinter); // Add the variables file to the project VCProjectItem* xcvarsFile = addRelativeFilePathToVS("Text", varsFilePath, "Xcode Variable Files", *proj, *configBS); // Mark the file as non-deployable xcvarsFile->setDefinition("DeploymentContent", "false"); } } return proj; }
static VCProjectItem* addFileToVSInternal(const PBXFile* file, VCProject& proj, const BuildSettings& bs, bool isVariant, const VCItemHint* itemHint) { // Add all children of any PBXVariantGroup const PBXVariantGroup* variantGroup = dynamic_cast<const PBXVariantGroup*>(file); if (variantGroup) { const ConstFileList& children = variantGroup->getChildren(); for (auto child : children) { addFileToVSInternal(child, proj, bs, true, itemHint); } return NULL; } // Get the real and virtual paths for the file in Xcode String realPath = file->getFullPath(); String virtualPath = file->getVirtualPath(); // Fix up virtual path for variant files // Resources/MainStoryboard.storyboard/en => Resources/en/MainStoryboard.storyboard if (isVariant) { String variantLang = sb_basename(virtualPath); String filePath = sb_dirname(virtualPath); String fixedDir = joinPaths(sb_dirname(filePath), variantLang); virtualPath = joinPaths(fixedDir, sb_basename(filePath)); } // Compute the VS ItemType for the file String fileType = file->getFileType(); String vsType = getVSItemType(fileType); if (vsType == "Unknown") { if (itemHint && !itemHint->defaultType.empty()) { vsType = itemHint->defaultType; } } // Add the item to the project, taking into account path overrides VCProjectItem* item = NULL; if (itemHint && !itemHint->pathOverride.empty()) { sbAssert(!isVariant, "Unexpected path override for variant file: " + realPath); item = proj.addItem(vsType, itemHint->pathOverride, sb_dirname(virtualPath)); } else { item = addRelativeFilePathToVS(vsType, realPath, sb_dirname(virtualPath), proj, bs); } // Handle Variant files if (isVariant) { String variantDir = sb_basename(sb_dirname(realPath)); item->setDefinition("VariantDir", variantDir); } return item; }