XCScheme::XCScheme(const String& absSchemePath, const PBXProject* owner) : m_absPath(absSchemePath), m_parentProject(owner) { // Record the scheme name m_name = sb_fname(sb_basename(m_absPath)); #if defined(_MSC_VER) // Disambiguate scheme names from different users String userDir = sb_basename(sb_dirname(sb_dirname(m_absPath))); if (strEndsWith(userDir, ".xcuserdatad")) m_name = m_name + " (" + sb_fname(userDir) + ")"; #endif }
VCProject* SBTarget::constructVCProject(VSTemplateProject* projTemplate) { // Create the project VCProject* proj = new VCProject(projTemplate); // Set global properties on the project const BuildSettings& projBS = m_parentProject.getBuildSettings(); String sdkDir = projBS.getValue("WINOBJC_SDK_ROOT"); proj->setGlobalProperty("WINOBJC_SDK_ROOT", sdkDir); // Set configuration properties for (auto configBS : m_buildSettings) { VCProjectConfiguration *projConfig = proj->addConfiguration(configBS.first); String execName = configBS.second->getValue("EXECUTABLE_NAME"); if (getProductType() == TargetStaticLib) execName = sb_fname(execName); if (!execName.empty()) projConfig->setProperty("TargetName", execName); } // Write files associated with each build phase SBBuildPhaseList::const_iterator phaseIt = m_buildPhases.begin(); for (; phaseIt != m_buildPhases.end(); ++phaseIt) (*phaseIt)->writeVCProjectFiles(*proj); return proj; }
void SBWorkspace::generateFiles(bool genProjectionsProj) { // Detect and warn about about any collisions detectProjectCollisions(); // Get a set of all configurations appearing in all projects StringSet slnConfigs; for (auto project : m_openProjects) { const StringSet& configs = project.second->getSelectedConfigurations(); slnConfigs.insert(configs.begin(), configs.end()); } // Create a solution BuildSettings globalBS(NULL); String outputFormat = globalBS.getValue("VSIMPORTER_OUTPUT_FORMAT"); String solutionPath = sb_fname(getPath()) + "-" + outputFormat + ".sln"; VSSolution* sln = new VSSolution(solutionPath); // Register all configurations with the solution for (auto configName : slnConfigs) { sln->addConfiguration(configName); } // Construct VS Projects std::multimap<SBTarget*, VCProject*> vcProjects; for (auto project : m_openProjects) { project.second->constructVCProjects(*sln, slnConfigs, vcProjects); } // Construct a projections project, if required VCProject* glueProject = nullptr; if (genProjectionsProj) { glueProject = generateGlueProject(); sln->addProject(glueProject); } // Resolve dependencies for (auto proj : vcProjects) { proj.first->resolveVCProjectDependecies(proj.second, vcProjects); // Add a dependency on all static/framework target projects if (glueProject && proj.first->getProductType() == TargetStaticLib) { glueProject->addProjectReference(proj.second); } } // Write solution/projects to disk sbValidateWithTelemetry(!vcProjects.empty(), "No valid targets to import."); sln->write(); }
void PBXNativeTarget::getBuildSettings(VariableCollection& settings) const { PBXTarget::getBuildSettings(settings); String productFileType = getProductFileType(); String productPath = getProductFileName(); String productNameFull = sb_basename(productPath); String productName = sb_fname(productNameFull); if (m_productType == "com.apple.product-type.library.static") { if (productFileType != "archive.ar") SBLog::warning() << "Unexpected product file type \"" << productFileType << "\" for \"" << getName() << "\" static lib target." << std::endl; settings.insert("EXECUTABLE_NAME", productNameFull); settings.insert("EXECUTABLE_PATH", productNameFull); } else if (m_productType == "com.apple.product-type.framework") { if (productFileType != "wrapper.framework") { SBLog::warning() << "Unexpected product file type \"" << productFileType << "\" for \"" << getName() << "\" framework target." << std::endl; } settings.insert("EXECUTABLE_NAME", productName); settings.insert("EXECUTABLE_PATH", joinPaths(productNameFull, productName)); } else if (m_productType == "com.apple.product-type.application") { // Fix up product name, when necessary if (productFileType == "compiled.mach-o.executable") productNameFull = productName + ".app"; else if (productFileType != "wrapper.application") SBLog::warning() << "Unexpected product file type \"" << productFileType << "\" for \"" << getName() << "\" app target." << std::endl; settings.insert("EXECUTABLE_NAME", productName); settings.insert("EXECUTABLE_FOLDER_PATH", productNameFull); } else if (m_productType == "com.apple.product-type.bundle") { if (productFileType != "wrapper.cfbundle") { SBLog::warning() << "Unexpected product file type \"" << productFileType << "\" for \"" << getName() << "\" bundle target." << std::endl; } settings.insert("EXECUTABLE_NAME", productName); settings.insert("EXECUTABLE_FOLDER_PATH", productNameFull); } settings.insert("PRODUCT_NAME", productName); settings.insert("FULL_PRODUCT_NAME", productNameFull); settings.insert("PRODUCT_TYPE", m_productType); }
void SBFrameworksBuildPhase::writeVCProjectFiles(VCProject& proj) const { // We don't support linking with frameworks when building bundles TargetProductType productType = m_parentTarget.getProductType(); if (productType == TargetBundle) { if (!m_phase->getBuildFileList().empty()) { SBLog::warning() << "Ignoring all frameworkss in \"" << m_parentTarget.getName() << "\" bundle target." << std::endl; } return; } String linkTarget; if (productType == TargetApplication) linkTarget = "Link"; else if (productType == TargetStaticLib) linkTarget = "Lib"; // Get paths to all the build files (frameworks) StringVec buildFilePaths; if (m_phase) { const BuildFileList& buildFiles = m_phase->getBuildFileList(); sbAssert(buildFiles.size() == m_buildFileTargets.size()); for (size_t i = 0; i < buildFiles.size(); i++) { const PBXFile* file = buildFiles[i]->getFile(); // Ignore any frameworks build from source (they will be added as project references) if (file && !m_buildFileTargets[i]) buildFilePaths.push_back(file->getFullPath()); } } for (auto bs : m_parentTarget.getBuildSettings()) { VCProjectConfiguration* config = proj.addConfiguration(bs.first); // Extrace libs/frameworks from OTHER_LDFLAGS StringVec buildFilePaths(buildFilePaths); processLDFlags(bs.second->getValue("OTHER_LDFLAGS"), buildFilePaths); // Construct a list of libraries to link against StringSet linkedLibs; linkedLibs.insert("%(AdditionalDependencies)"); for (auto filePath : buildFilePaths) { if (productType == TargetStaticLib && !strEndsWith(filePath, ".a")) continue; String winLibName = sb_fname(sb_basename(filePath)) + ".lib"; // If the library is blocked then add the replacement library to our additional dependencies auto it = s_blockedLibraries.find(winLibName); while (it != s_blockedLibraries.end()) { // get the replacement library. winLibName = it->second; // follow any transitive replacement. it = s_blockedLibraries.find(winLibName); } if (!winLibName.empty()) { linkedLibs.insert(winLibName); } } // AdditionalDependencies String additionalDeps = joinStrings(linkedLibs, ";"); if (!additionalDeps.empty()) { config->setItemDefinition(linkTarget, "AdditionalDependencies", additionalDeps); } } }
void SBWorkspace::generateFiles(bool genProjectionsProj, bool genPackagingProj) { // Detect and warn about about any collisions detectProjectCollisions(); // Don't generate packaging project if the solution only contains an app bool solutionContainsPackagebleProject = false; for (auto project : m_openProjects) { solutionContainsPackagebleProject = solutionContainsPackagebleProject || project.second->containsPackagebleProject(); } genPackagingProj = genPackagingProj && solutionContainsPackagebleProject; // Get a set of all configurations appearing in all projects StringSet slnConfigs; for (auto project : m_openProjects) { const StringSet& configs = project.second->getSelectedConfigurations(); slnConfigs.insert(configs.begin(), configs.end()); } // Create a solution BuildSettings globalBS(NULL); String outputFormat = globalBS.getValue("VSIMPORTER_OUTPUT_FORMAT"); String solutionPath = sb_fname(getPath()) + "-" + outputFormat + ".sln"; VSSolution* sln = new VSSolution(solutionPath); // Register all configurations with the solution for (auto configName : slnConfigs) { sln->addConfiguration(configName); } // Construct VS Projects std::multimap<SBTarget*, VCProject*> vcProjects; for (auto project : m_openProjects) { project.second->constructVCProjects(*sln, slnConfigs, vcProjects, genPackagingProj); } VCProject* glueProject = nullptr; if (genProjectionsProj) { // Construct a WinRT projections project glueProject = generateGlueProject(genPackagingProj); sln->addProject(glueProject); } VCProject* packageProject = nullptr; if (genPackagingProj) { // Construct a packaging project packageProject = generatePackageProject(); packageProject->addProjectReference(glueProject); sln->addProject(packageProject); sln->addPlatform("AnyCPU"); // Copy nuget.config into the solution directory String templatesDir = globalBS.getValue("VSIMPORTER_TEMPLATES_DIR"); String nugetConfigSource = joinPaths(templatesDir, "nuget.config"); String nugetConfigDest = joinPaths(sb_dirname(getPath()), "nuget.config"); CopyFile(nugetConfigSource.c_str(), nugetConfigDest.c_str(), false); } // Resolve dependencies for (auto proj : vcProjects) { proj.first->resolveVCProjectDependecies(proj.second, vcProjects); TargetProductType productType = proj.first->getProductType(); // Add a dependency on all static/framework target projects if (glueProject && productType == TargetStaticLib) { glueProject->addProjectReference(proj.second); } // Make the packaging project dependent on all framework components if (packageProject && productType != TargetProductUnknown && productType != TargetApplication) { packageProject->addProjectReference(proj.second); } } // Write solution/projects to disk sbValidateWithTelemetry(!vcProjects.empty(), "No valid targets to import."); sln->write(); }