VCProject::VCProject(VSTemplateProject* projTemplate, const std::string& id) : m_template(projTemplate) { sbAssert(projTemplate); sbAssert(isAbsolutePath(projTemplate->getPath())); // Determine subtype (shared or not) m_subType = projTemplate->isShared() ? VCShared : VCNone; // TODO: validate passed in id if (!id.empty()) m_id = id; else m_id = sole::uuid4().str(); string guid = formatVSGUID(m_id); if (m_subType == VCShared) { TELEMETRY_EVENT_GUID(L"VSImporterSharedProjectGuid", guid); } else { TELEMETRY_EVENT_GUID(L"VSImporterProjectGuid", guid); } addGlobalProperty("ProjectGuid", guid); }
SBTarget::SBTarget(const PBXTarget* target, const StringSet& configNames, SBProject& parentProject) : m_target(target), m_parentProject(parentProject) { sbAssert(target); sbAssert(!configNames.empty()); for (auto configName : configNames) { m_buildSettings[configName] = new BuildSettings(target, configName); } }
void SBTarget::resolveVCProjectDependecies(VCProject* proj, std::multimap<SBTarget*, VCProject*>& vcProjects) { // Get the VCProject's platforms StringSet platforms; proj->getPlatforms(platforms); // Iterate over the target's dependencies for (auto dep : m_dependencies) { // Find all VCProjects generated from the SBTarget auto possibleDeps = vcProjects.equal_range(dep); // Look for the best-matching VCProject // BIG ASSUMPTION: Projects will have distinct platform sets, so only one match exists VCProject* match = NULL; for (auto it = possibleDeps.first; it != possibleDeps.second; ++it) { VCProject* depVCProject = it->second; StringSet depPlatforms; depVCProject->getPlatforms(depPlatforms); if (isSubset(platforms, depPlatforms)) { match = depVCProject; break; } } sbAssert(match); proj->addProjectReference(match); } }
void Renderer::drawAll() { if (mDrawablesBuffer.size() == 0) { return; } #if 0 std::sort(mDrawablesBuffer.begin(), mDrawablesBuffer.end(), [](const std::shared_ptr<Drawable>& a, const std::shared_ptr<Drawable>& b) { return *a < *b; }); #endif State rendererState(mCamera, mAmbientLightColor, mLights); for (const Light& light: mLights) { if (light.makesShadows) { sbAssert(light.type == Light::Type::Parallel, "TODO: shadows for point lights"); Camera camera = Camera::orthographic(-100.0, 100.0, -100.0, 100.0, -1000.0, 1000.0); camera.lookAt(-light.pos, Vec3(0.0, 0.0, 0.0)); IntRect savedViewport = mViewport; Vec2i shadowFbSize = light.shadowFramebuffer->getSize(); setViewport(0, 0, shadowFbSize.x, shadowFbSize.y); drawTo(*light.shadowFramebuffer, camera); setViewport(savedViewport); rendererState.shadows.push_back({ light.shadowFramebuffer->getTexture(), math::matrixShadowBias() * camera.getViewProjectionMatrix() }); } } GL_CHECK(glClearColor(mClearColor.r, mClearColor.g, mClearColor.b, mClearColor.a)); clear(); for (const std::shared_ptr<Drawable>& d: mDrawablesBuffer) { if (d->mProjectionType == ProjectionType::Perspective) { rendererState.camera = &mCamera; } else { rendererState.camera = &mSpriteCamera; } d->draw(rendererState); } mAmbientLightColor = Color::White; mLights.clear(); mDrawablesBuffer.clear(); }
String SBWorkspace::getName() const { if (m_mainProject) { return m_mainProject->getName(); } else if (m_workspace) { return m_workspace->getName(); } else { sbAssert(0); // unreachable return ""; } }
void SBResourcesBuildPhase::writeVCProjectFiles(VCProject& proj) const { TargetProductType productType = m_parentTarget.getProductType(); if (productType != TargetApplication && productType != TargetBundle) { return; } // Process build files const BuildSettings& projBS = m_parentTarget.getProject().getBuildSettings(); const BuildFileList& buildFiles = m_phase->getBuildFileList(); sbAssert(buildFiles.size() == m_buildFileTargets.size()); for (size_t i = 0; i < buildFiles.size(); i++) { // Construct a path for Bundle build products, relative to the SolutionDir, // instead of using the Xcode path String pathOverride; if (m_buildFileTargets[i]) { String productFileName = sb_basename(buildFiles[i]->getFile()->getFullPath()); String productFileType = buildFiles[i]->getFile()->getFileType(); if (productFileType == "wrapper.cfbundle") { pathOverride = "$(SolutionDir)$(Configuration)\\" + productFileName; } else { SBLog::warning() << "Unexpected build product in ResourceBuildPhase: " << productFileName << std::endl; } } VCItemHint itemHint = { "SBResourceCopy" , pathOverride }; addBuildFileToVS(buildFiles[i], proj, projBS, &itemHint); } // Process all Info.plist files std::map<std::string, VCProjectItem*> infoPlistMap; for (auto bs : m_parentTarget.getBuildSettings()) { VCProjectConfiguration* config = proj.addConfiguration(bs.first); // Exclude all plist from building, by default config->setItemDefinition("SBInfoPlistCopy", "ExcludedFromBuild", "true"); // Get absolute path to plist String plistPath = bs.second->getValue("INFOPLIST_FILE"); plistPath = m_parentTarget.makeAbsolutePath(plistPath); // Add plist file to project (only once) if (infoPlistMap.find(plistPath) == infoPlistMap.end()) { infoPlistMap[plistPath] = addRelativeFilePathToVS("SBInfoPlistCopy", plistPath, "", proj, *bs.second); } // Un-exclude building plist for configuration String condition = "'$(Configuration)'=='" + bs.first + "'"; infoPlistMap[plistPath]->setDefinition("ExcludedFromBuild", "false", condition); // Specify which variables files to use String varsFile = m_parentTarget.getName() + "-" + bs.first + "-xcvars.txt"; infoPlistMap[plistPath]->setDefinition("VariableFile", varsFile, condition); } }
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; }
bool Renderer::init(::Display* display, ::Window window, GLXFBConfig& fbc) { sbAssert(display, "display is null"); mDisplay = display; gLog.info("creating GL context...\n"); int contextAttribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, 0 }; GLXCREATECTXATTRSARBPROC glXCreateContextAttribsARB = (GLXCREATECTXATTRSARBPROC)glXGetProcAddress((GLubyte*)"glXCreateContextAttribsARB"); if (!glXCreateContextAttribsARB) { gLog.err("glXCreateContextAttribsARB not present\n"); return false; } GL_CHECK(mGLContext = glXCreateContextAttribsARB(mDisplay, fbc, 0, True, contextAttribs)); if (!mGLContext) { gLog.err("glXCreateContextAttribsARB failed\n"); return false; } GL_CHECK(glXMakeCurrent(mDisplay, window, mGLContext)); printGLVersion(); if (!initGLEW()) { return false; } GL_CHECK(glEnable(GL_DEPTH_TEST)); GL_CHECK(glDepthFunc(GL_LESS)); GL_CHECK(glEnable(GL_CULL_FACE)); GL_CHECK(glCullFace(GL_BACK)); GL_CHECK(glEnable(GL_BLEND)); GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); #if 0 GL_CHECK(glEnable(GL_TEXTURE_2D)); String::init(mDisplay); #endif return true; }
void Camera::lookAt(Vec3 pos, Vec3 at, Vec3 up) { mEye = pos; mAt = at; mUp = up.normalized(); mFront = (mAt - mEye).normalized(); Vec3 oldRight = mRight; mRight = mFront.cross(mUp); if (mRight.isZero()) { oldRight.y = 0; mRight = oldRight; gLog.trace("right was zero, reverted to %s\n", utils::toString(mRight).c_str()); } mRight = mRight.normalized(); mUpReal = mRight.cross(mFront).normalized(); sbAssert(mFront.dot(mFront) > 0.0f, "zero front vector"); sbAssert(mRight.dot(mRight) > 0.0f, "zero right vector"); sbAssert(mUpReal.dot(mUpReal) > 0.0f, "zero upReal vector"); sbAssert(std::abs(mRight.length() - 1.0f) < 0.001f, "mRight (%f, %f, %f; length = %f) not normalized", mRight.x, mRight.y, mRight.z, mRight.length()); sbAssert(std::abs(mUpReal.length() - 1.0f) < 0.001f, "mUpReal (%f, %f, %f; length = %f) not normalized", mUpReal.x, mUpReal.y, mUpReal.z, mUpReal.length()); sbAssert(std::abs(mFront.length() - 1.0f) < 0.001f, "mFront (%f, %f, %f; length = %f) not normalized", mFront.x, mFront.y, mFront.z, mFront.length()); mMatrixUpdateFlags |= MatrixTranslationUpdated | MatrixRotationUpdated; updateAngles(); }
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); } } }
const std::string& VSTemplateProject::getPath() const { sbAssert(!m_items.empty()); return m_items.front()->outFile; }
String getcwd() { char cwd[PATH_MAX+1]; sbAssert(getcwd(cwd, sizeof(cwd)), "Failed to get CWD"); return posixPath(cwd); }
SBTarget* SBTarget::getPossibleTarget(const PBXBuildFile* buildFile) { static const char* const _productWildcards[] = {"lib*.a", "*.app", "*.framework"}; static StringVec productWildcards(_productWildcards, _productWildcards + sizeof(_productWildcards) / sizeof(char*)); sbAssert(buildFile); const PBXFile* file = buildFile->getFile(); String filePath, fileName; if (file) { filePath = file->getFullPath(); fileName = sb_basename(filePath); } SBTarget* depTarget = NULL; const PBXReferenceProxy* proxyFile = NULL; // We are interested in any potential Xcode build products if (!matchWildcardList(fileName, productWildcards)) { // Do nothing } else if ((proxyFile = dynamic_cast<const PBXReferenceProxy*>(file))) { // Construct base error string, to hopefully never be used String errStr = "Failed to process PBXBuildFile (" + buildFile->getId() + ") for " + getName() + " target. "; // Get remote proxy container const PBXContainerItemProxy* container = proxyFile->getContainer(); // Ignore build file, if necessary if (!container) { SBLog::warning() << errStr << "Unable to get the PBXContainerItemProxy."; return NULL; } // Get remote project and target identifier from the proxy const String& remoteId = container->getRemoteId(); String projectPath = container->getPortalPath(); // Expand the project path const BuildSettings& projBS = m_parentProject.getBuildSettings(); String absProjectPath = projBS.expand(projectPath, PathValue); // Try to open the remote project SBProject* remoteProject = SBWorkspace::get()->openProject(absProjectPath); // Try to queue up the target with the given product reference if (remoteProject) { depTarget = remoteProject->queueTargetWithProductReference(remoteId); if (!depTarget) SBLog::warning() << errStr << "Unable to create proxy target " << remoteId << " from the \"" << remoteProject->getName() << "\" project." << std::endl; } else { SBLog::warning() << errStr << "Unable to open referenced project path: " << projectPath << std::endl; } } else { // Look for target in current project first depTarget = m_parentProject.queueTargetWithProductName(fileName); // Look for target in workspace, if it hasn't been found already if (!depTarget) depTarget = SBWorkspace::get()->queueTargetWithProductName(fileName); } // Add the target to the dependency set addDependency(depTarget); // Indicate whether this was a dependency or not return depTarget; }
int main(int argc, char* argv[]) { StringSet targets, configurations, schemes; String sdkRoot, projectPath, xcconfigPath, workspacePath; String logVerbosity("warning"); int projectSet = 0; int workspaceSet = 0; int interactiveFlag = 0; int relativeSdkFlag = 0; int allTargets = 0; int allSchemes = 0; int mode = GenerateMode; static struct option long_options[] = { {"version", no_argument, 0, 0}, {"usage", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {"interactive", no_argument, &interactiveFlag, 1}, {"loglevel", required_argument, 0, 0}, {"sdk", required_argument, 0, 0}, {"list", no_argument, &mode, ListMode}, {"project", required_argument, &projectSet, 1}, {"target", required_argument, 0, 0}, {"alltargets", no_argument, &allTargets, 1}, {"configuration", required_argument, 0, 0}, {"xcconfig", required_argument, 0, 0}, {"workspace", required_argument, &workspaceSet, 1}, {"scheme", required_argument, 0, 0}, {"allschemes", required_argument, &allSchemes, 1}, {"relativepath", no_argument, &relativeSdkFlag, 1}, {0, 0, 0, 0} }; int numOptions = sizeof(long_options) / sizeof(struct option) - 1; while (1) { int option_index = 0; int c = getopt_long_only(argc, argv, "", long_options, &option_index); if (c == -1) break; else if (c || option_index < 0 || option_index >= numOptions) printUsage(argv[0], false, EXIT_FAILURE); // Process options switch (option_index) { case 0: printVersion(argv[0]); break; case 1: printUsage(argv[0], false, EXIT_SUCCESS); break; case 2: printUsage(argv[0], true, EXIT_SUCCESS); break; case 4: logVerbosity = strToLower(optarg); break; case 5: sdkRoot = optarg; break; case 7: projectPath = optarg; break; case 8: targets.insert(optarg); break; case 10: configurations.insert(optarg); break; case 11: xcconfigPath = optarg; break; case 12: workspacePath = optarg; break; case 13: schemes.insert(optarg); break; default: // Do nothing break; } } // Set AI Telemetry_Init TELEMETRY_INIT(L"AIF-23c336e0-1e7e-43ba-a5ce-eb9dc8a06d34"); if (checkTelemetryOptIn()) { TELEMETRY_ENABLE(); } else { TELEMETRY_DISABLE(); } TELEMETRY_SET_INTERNAL(isMSFTInternalMachine()); String machineID = getMachineID(); if (!machineID.empty()) { TELEMETRY_SET_MACHINEID(machineID.c_str()); } TELEMETRY_EVENT_DATA(L"VSImporterStart", "WinStore10"); // Process non-option ARGV-elements VariableCollectionManager& settingsManager = VariableCollectionManager::get(); while (optind < argc) { String arg = argv[optind]; if (arg == "/?") { // Due to issue 6715724, flush before exiting TELEMETRY_FLUSH(); printUsage(argv[0], true, EXIT_SUCCESS); } else if (arg.find_first_of('=') != String::npos) { settingsManager.processGlobalAssignment(arg); } else { sbValidate(0, "Unsupported argument: " + arg); } optind++; } // Set output format settingsManager.setGlobalVar("VSIMPORTER_OUTPUT_FORMAT", "WinStore10"); // Set logging level SBLogLevel logLevel; if (logVerbosity == "debug") logLevel = SB_DEBUG; else if (logVerbosity == "info") logLevel = SB_INFO; else if (logVerbosity == "warning") logLevel = SB_WARN; else if (logVerbosity == "error") logLevel = SB_ERROR; else if (!logVerbosity.empty()) sbValidate(0, "Unrecognized logging verbosity: " + logVerbosity); SBLog::setVerbosity(logLevel); // Look for a project file in current directory, if one hasn't been explicitly specified if (!projectSet && !workspaceSet) { StringList projects; findFiles(".", "*.xcodeproj", DT_DIR, false, projects); StringList workspaces; findFiles(".", "*.xcworkspace", DT_DIR, false, workspaces); if (!workspaces.empty()) { sbValidate(workspaces.size() == 1, "Multiple workspaces found. Select the workspace to use with the -workspace option."); workspacePath = workspaces.front(); workspaceSet = 1; } else if (!projects.empty()) { sbValidate(projects.size() == 1, "Multiple projects found. Select the project to use with the -project option."); projectPath = projects.front(); projectSet = 1; } else { sbValidate(0, "The current directory does not contain a project or workspace."); } } // Set the architecture String arch = "msvc"; settingsManager.setGlobalVar("ARCHS", arch); settingsManager.setGlobalVar("CURRENT_ARCH", arch); // Make sure workspace arguments are valid if (workspaceSet) { sbValidate(!projectSet, "Cannot specify both a project and a workspace."); sbValidate(targets.empty(), "Cannot specify target(s) when specifying a workspace."); } // Disallow specifying schemes and targets together sbValidate((schemes.empty() && !allSchemes) || (targets.empty() && !allTargets), "Cannot specify schemes and targets together."); // Process allTargets and allSchemes flags if (allSchemes) schemes.clear(); if (allTargets) targets.clear(); // Initialize global settings String binaryDir = sb_dirname(getBinaryLocation()); sbValidate(!binaryDir.empty(), "Failed to resolve binary directory."); settingsManager.setGlobalVar("VSIMPORTER_BINARY_DIR", binaryDir); settingsManager.setGlobalVar("VSIMPORTER_INTERACTIVE", interactiveFlag ? "YES" : "NO"); settingsManager.setGlobalVar("VSIMPORTER_RELATIVE_SDK_PATH", relativeSdkFlag ? "YES" : "NO"); if (!sdkRoot.empty()) { sdkRoot = joinPaths(getcwd(), sdkRoot); } else { sdkRoot = joinPaths(binaryDir, ".."); } settingsManager.setGlobalVar("WINOBJC_SDK_ROOT", sdkRoot); // Add useful environment variables to global settings String username; sbValidate(sb_getenv("USERNAME", username), "Failed to get current username."); settingsManager.setGlobalVar("USER", username); // Read xcconfig file specified from the command line if (!xcconfigPath.empty()) settingsManager.processGlobalConfigFile(xcconfigPath); // Read xcconfig file specified by the XCODE_XCCONFIG_FILE environment variable String xcconfigFile; if (sb_getenv("XCODE_XCCONFIG_FILE", xcconfigFile)) settingsManager.processGlobalConfigFile(xcconfigFile); // Validate WinObjC SDK directory checkWinObjCSDK(); // Create a workspace SBWorkspace *mainWorkspace; if (workspaceSet) { mainWorkspace = SBWorkspace::createFromWorkspace(workspacePath); } else if (projectSet) { mainWorkspace = SBWorkspace::createFromProject(projectPath); } else { sbAssert(0); // non-reachable } if (mode == ListMode) { mainWorkspace->printSummary(); } else if (mode == GenerateMode) { if (allTargets) { mainWorkspace->queueAllTargets(configurations); } else if (projectSet) { mainWorkspace->queueTargets(targets, configurations); } else if (workspaceSet) { mainWorkspace->queueSchemes(schemes, configurations); } else { sbAssert(0); // non-reachable } mainWorkspace->generateFiles(); } else { sbAssert(0); // non-reachable } TELEMETRY_EVENT_DATA(L"VSImporterComplete", "WinStore10"); TELEMETRY_FLUSH(); return EXIT_SUCCESS; }