void CommandEventHandler::do_rmdr(std::string path, std::ostringstream &out) { std::string ret = isDir(path); const char *p = path.c_str(); // if it's a file, nothing special to do if (ret.compare("TRUE") != 0) { if (ret.compare("FALSE") == 0) { rm(path); return; } // if this does not exist, return out << ret; return; } // recurse for dir contents PRDir *dir = PR_OpenDir(p); PRDirEntry *entry = PR_ReadDir(dir, PR_SKIP_BOTH); while (entry) { do_rmdr(joinPaths(path, std::string(entry->name)), out); entry = PR_ReadDir(dir, PR_SKIP_BOTH); } if (PR_CloseDir(dir) != PR_SUCCESS) { out << "error: could not close dir object" << ENDL; // maybe return; } if (PR_RmDir(p) != PR_SUCCESS) out << std::string("error: could not remove " + path) << ENDL; }
static const char* getVsImporterTemplatesDir() { static String templatesDir = joinPaths(sb_dirname(getBinaryLocation()), "../msvc/vsimporter-templates"); return templatesDir.c_str(); }
bool CMake::writeProject(const String& targetName, Project& project) { Directory::create(String(".CMake/") + targetName); fileOpen(String(".CMake/") + targetName + "/CMakeLists.txt"); fileWrite("cmake_policy(SET CMP0015 NEW)\n\n"); for(const Map<String, ProjectConfiguration>::Node* i = project.configurations.getFirst(); i; i = i->getNext()) { const String& configName = i->key; const ProjectConfiguration& config = i->data; const Target& target = *config.target; if(i == project.configurations.getFirst()) fileWrite(String("if(CMAKE_BUILD_TYPE STREQUAL \"") + configName +"\")\n"); else fileWrite(String("elseif(CMAKE_BUILD_TYPE STREQUAL \"") + configName +"\")\n"); if(!target.includePaths.isEmpty()) fileWrite(String("include_directories(") + joinPaths(target.includePaths) + ")\n"); if(!target.libPaths.isEmpty()) fileWrite(String("link_directories(") + joinPaths(target.libPaths) + ")\n"); List<String> customBuildOutput; for(const List<const File*>::Node* i = config.customBuildFiles.getFirst(); i; i = i->getNext()) { const File& file = *i->data; fileWrite("add_custom_command(\n"); fileWrite(String(" OUTPUT ") + joinPaths(file.output, true) + "\n"); Map<String, void*> outputDirs; for(const List<String>::Node* i = file.output.getFirst(); i; i = i->getNext()) { String dir = ::File::getDirname(i->data); if(dir != "." && !outputDirs.find(dir)) outputDirs.append(dir); } for(Map<String, void*>::Node* i = outputDirs.getFirst(); i; i = i->getNext()) fileWrite(String(" COMMAND ${CMAKE_COMMAND} -E make_directory ") + translatePath(i->key, true) + "\n"); for(const List<String>::Node* i = file.command.getFirst(); i; i = i->getNext()) fileWrite(String(" COMMAND ") + i->data + "\n"); fileWrite(String(" DEPENDS ") + joinPaths(file.input) + "\n"); fileWrite(" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..\n"); if(!file.message.isEmpty()) fileWrite(String(" COMMENT \"") + file.message.getFirst()->data + "\"\n"); fileWrite(" )\n"); for(const List<String>::Node* i = file.output.getFirst(); i; i = i->getNext()) customBuildOutput.append(i->data); } if(config.type == ProjectConfiguration::applicationType) fileWrite(String("add_executable(") + targetName + " " + joinPaths(config.sourceFiles) + " " + joinPaths(customBuildOutput, true) + ")\n"); else if(config.type == ProjectConfiguration::dynamicLibraryType) fileWrite(String("add_library(") + targetName + " SHARED " + joinPaths(config.sourceFiles) + " " + joinPaths(customBuildOutput, true) + ")\n"); else if(config.type == ProjectConfiguration::staticLibraryType) fileWrite(String("add_library(") + targetName + " STATIC " + joinPaths(config.sourceFiles) + " " + joinPaths(customBuildOutput, true) + ")\n"); else if(config.type == ProjectConfiguration::customTargetType) { if(!target.output.isEmpty() && !target.command.isEmpty()) { fileWrite("add_custom_command(\n"); fileWrite(String(" OUTPUT ") + joinPaths(target.output, true) + "\n"); Map<String, void*> outputDirs; for(const List<String>::Node* i = target.output.getFirst(); i; i = i->getNext()) { String dir = ::File::getDirname(i->data); if(dir != "." && !outputDirs.find(dir)) outputDirs.append(dir); customBuildOutput.append(i->data); } for(Map<String, void*>::Node* i = outputDirs.getFirst(); i; i = i->getNext()) fileWrite(String(" COMMAND ${CMAKE_COMMAND} -E make_directory ") + translatePath(i->key, true) + "\n"); for(const List<String>::Node* i = target.command.getFirst(); i; i = i->getNext()) fileWrite(String(" COMMAND ") + i->data + "\n"); fileWrite(String(" DEPENDS ") + joinPaths(target.input) + "\n"); fileWrite(" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../..\n"); if(!target.message.isEmpty()) fileWrite(String(" COMMENT \"") + target.message.getFirst()->data + "\"\n"); fileWrite(" )\n"); } fileWrite(String("add_custom_target(") + targetName + " ALL\n"); fileWrite(String(" DEPENDS ") + joinPaths(customBuildOutput, true) + "\n"); fileWrite(String(" SOURCES ") + joinPaths(config.sourceFiles) + "\n"); fileWrite(" )\n"); } /* if(!config.libs.isEmpty()) { List<String> libs; for(const List<Library>::Node* i = config.libs.getFirst(); i; i = i->getNext()) { const Library& lib = i->data; if(lib.type == Library::localType) libs.append(lib.name); else { fileWrite(String("find_library(") + lib.name + "_LIBRARY " + lib.name + " PATHS " + join(target.libPaths) + ")\n"); libs.append(String("${") + lib.name + "_LIBRARY}"); } } fileWrite(String("target_link_libraries(") + targetName + " " + join(libs) + ")\n"); } */ if(!config.libs.isEmpty()) { List<String> libs; for(const List<Library>::Node* i = config.libs.getFirst(); i; i = i->getNext()) libs.append(i->data.name); fileWrite(String("target_link_libraries(") + targetName + " " + join(libs) + ")\n"); } if(!target.cppCompiler.isEmpty()) { String cppCompiler; for(const List<String>::Node* i = target.cppCompiler.getFirst(); i; i = i->getNext()) { const String& word = i->data; size_t sep; if(word.find('=', sep)) fileWrite(String("set(ENV{") + word.substr(0, sep) + "} \"" + word.substr(sep + 1) + "\")\n"); else { cppCompiler = word; break; } } if(!cppCompiler.isEmpty()) { if(!::File::isPathAbsolute(cppCompiler) && ::File::exists(cppCompiler)) fileWrite(String("set(CMAKE_CXX_COMPILER \"${CMAKE_CURRENT_SOURCE_DIR}/../../") + cppCompiler + "\")\n"); else fileWrite(String("set(CMAKE_CXX_COMPILER \"") + cppCompiler + "\")\n"); } } if(!target.cCompiler.isEmpty()) { String cCompiler; for(const List<String>::Node* i = target.cCompiler.getFirst(); i; i = i->getNext()) { const String& word = i->data; size_t sep; if(word.find('=', sep)) fileWrite(String("set(ENV{") + word.substr(0, sep) + "} \"" + word.substr(sep + 1) + "\")\n"); else { cCompiler = word; break; } } if(!cCompiler.isEmpty()) { if(!::File::isPathAbsolute(cCompiler) && ::File::exists(cCompiler)) fileWrite(String("set(CMAKE_C_COMPILER \"${CMAKE_CURRENT_SOURCE_DIR}/../../") + cCompiler + "\")\n"); else fileWrite(String("set(CMAKE_C_COMPILER \"") + cCompiler + "\")\n"); } } /* if(!target.cppFlags.isEmpty()) fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY COMPILE_FLAGS \"" + join(target.cppFlags) + "\")\n"); */ if(!target.cppFlags.isEmpty()) fileWrite(String("set(CMAKE_CXX_FLAGS \"") + join(target.cppFlags) + "\")\n"); if(!target.cFlags.isEmpty()) fileWrite(String("set(CMAKE_C_FLAGS \"") + join(target.cFlags) + "\")\n"); if(!target.output.isEmpty()) { String outputDirectory = ::File::getDirname(target.output.getFirst()->data); // Hi cmake devs! I do not know whats considered to be an ARCHIVE, LIBRARY or RUNTIME. So I will set all properties to be sure. fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY ARCHIVE_OUTPUT_DIRECTORY \"" + translatePath(outputDirectory) + "\")\n"); fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY LIBRARY_OUTPUT_DIRECTORY \"" + translatePath(outputDirectory) + "\")\n"); fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY RUNTIME_OUTPUT_DIRECTORY \"" + translatePath(outputDirectory) + "\")\n"); String outputName = ::File::getWithoutExtension(::File::getBasename(target.output.getFirst()->data)); outputName.patsubst("lib%", "%"); fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY OUTPUT_NAME \"" + outputName + "\")\n"); } if(!target.linkFlags.isEmpty()) { if(config.type == ProjectConfiguration::staticLibraryType) fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY STATIC_LIBRARY_FLAGS " + join(target.linkFlags) + ")\n"); else fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY LINK_FLAGS \"" + join(target.linkFlags) + "\")\n"); } if(!target.defines.isEmpty()) fileWrite(String("set_property(TARGET ") + targetName + " PROPERTY COMPILE_DEFINITIONS " + join(target.defines) + ")\n"); if(!target.dependencies.isEmpty()) fileWrite(String("add_dependencies(") + targetName + " " + join(target.dependencies) + ")\n"); } fileWrite("endif()\n"); fileClose(); return true; }
static String makeRelativePath(const String& path, const String& oldProjDir, const String& newProjDir) { String absPath = joinPaths(oldProjDir, path); String relPath = getRelativePath(newProjDir, absPath); return winPath(relPath); }
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; } } // Take into account path override bool useRelativePath = true; if (itemHint && !itemHint->pathOverride.empty()) { sbAssertWithTelemetry(!isVariant, "Unexpected path override for variant file: " + realPath); realPath = itemHint->pathOverride; useRelativePath = false; } // Take into account filter override string filterPath = sb_dirname(virtualPath); if (itemHint && !itemHint->filterOverride.empty()) { filterPath = itemHint->filterOverride; } // Add the item to the project VCProjectItem* item = NULL; if (useRelativePath) { item = addRelativeFilePathToVS(vsType, realPath, filterPath, proj, bs); } else { item = proj.addItem(vsType, realPath, filterPath); } // Handle Variant files if (isVariant) { String variantDir = sb_basename(sb_dirname(realPath)); item->setDefinition("VariantDir", variantDir); } return item; }
String SBTarget::makeAbsolutePath(const String& path) const { const BuildSettings& projBS = m_parentProject.getBuildSettings(); return joinPaths(m_parentProject.getProjectDir(), projBS.expand(path, PathValue)); }
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 genProjectionsFlag = 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}, { "genprojections", no_argument, &genProjectionsFlag, 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(EXIT_FAILURE); } // Process options switch (option_index) { case 0: printVersion(argv[0]); exit(EXIT_SUCCESS); break; case 1: printUsage(argv[0], false); exit(EXIT_SUCCESS); break; case 2: printUsage(argv[0], true); exit(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", getProductVersion().c_str()); // 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_EVENT_DATA(L"VSImporterIncomplete", "printUsage"); TELEMETRY_FLUSH(); printUsage(argv[0], true); exit(EXIT_SUCCESS); } else if (arg.find_first_of('=') != String::npos) { settingsManager.processGlobalAssignment(arg); } else { sbValidateWithTelemetry(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()) { sbValidateWithTelemetry(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()) { sbValidateWithTelemetry(workspaces.size() == 1, "Multiple workspaces found. Select the workspace to use with the -workspace option."); workspacePath = workspaces.front(); workspaceSet = 1; } else if (!projects.empty()) { sbValidateWithTelemetry(projects.size() == 1, "Multiple projects found. Select the project to use with the -project option."); projectPath = projects.front(); projectSet = 1; } else { sbValidateWithTelemetry(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) { sbValidateWithTelemetry(!projectSet, "Cannot specify both a project and a workspace."); } // Disallow specifying schemes and targets together sbValidateWithTelemetry((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()); sbValidateWithTelemetry(!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; sbValidateWithTelemetry(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 { sbAssertWithTelemetry(0); // non-reachable } if (mode == ListMode) { mainWorkspace->printSummary(); } else if (mode == GenerateMode) { if (!schemes.empty() || allSchemes) { mainWorkspace->queueSchemes(schemes, configurations); } else { mainWorkspace->queueTargets(targets, configurations); } mainWorkspace->generateFiles(genProjectionsFlag); } else { sbAssertWithTelemetry(0); // non-reachable } TELEMETRY_EVENT_DATA(L"VSImporterComplete", getProductVersion().c_str()); TELEMETRY_FLUSH(); return EXIT_SUCCESS; }
static int validateTestDir1_renamed( const char *parentDir, const char *dirName) { int exitStatus = 0; char *dirpath = joinPaths(parentDir, dirName); if (0 == directoryExists(dirpath)) { fprintf(stdout, "FOUND directory: '%s'\n", dirpath); /* check for files within directory */ { char *path = joinPaths(dirpath, "file1.txt"); if (0 == fileExists(path)) { fprintf(stdout, "FOUND file: '%s'\n", path); } else { fprintf(stderr, "Unable to locate file '%s'\n", path); ++exitStatus; } free(path); } { char *path = joinPaths(dirpath, "file2.txt"); if (0 == fileExists(path)) { fprintf(stdout, "FOUND file: '%s'\n", path); } else { fprintf(stderr, "Unable to locate file '%s'\n", path); ++exitStatus; } free(path); } /* check for subdirectory */ { char *subdirPath = joinPaths(dirpath, "subdir"); if (0 == directoryExists(subdirPath)) { fprintf(stdout, "FOUND directory: '%s'\n", subdirPath); /* check for file in subdir */ { char *path = joinPaths(subdirPath, "file3.txt"); if (0 == fileExists(path)) { fprintf(stdout, "FOUND file: '%s'\n", path); } else { fprintf(stderr, "Unable to locate file '%s'\n", path); ++exitStatus; } free(path); } } else { fprintf(stderr, "Unable to directory file '%s'\n", subdirPath); ++exitStatus; } free(subdirPath); } } else { fprintf(stderr, "Unable to locate directory '%s'\n", dirpath); ++exitStatus; } free(dirpath); return exitStatus; }
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(); }
String PBXProject::getProjectDir() const { return joinPaths(m_pbxDoc->getDir(), m_projectDirPath); }