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
}
Exemple #2
0
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;
}
Exemple #3
0
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);
    }
  }
}
Exemple #6
0
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();
}