String BuildIOS::GenerateEntitlements() { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); IOSBuildSettings settings = buildSystem->GetBuildSettings()->GetIOSSettings(); String app_identifer = settings.appidPrefix + "."; app_identifer += settings.package; String team_identifier = settings.appidPrefix; String keychain_access_group = app_identifer; String entitlements = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; entitlements += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"; entitlements += "<plist version=\"1.0\">\n"; entitlements += "<dict>\n"; entitlements += "<key>application-identifier</key>\n"; entitlements.AppendWithFormat("<string>%s</string>\n", app_identifer.CString()); entitlements += "<key>com.apple.developer.team-identifier</key>\n"; entitlements.AppendWithFormat("<string>%s</string>\n", team_identifier.CString()); entitlements += "<key>get-task-allow</key>\n"; entitlements += "<true/>\n"; entitlements += "<key>keychain-access-groups</key>\n"; entitlements += "<array>\n"; entitlements.AppendWithFormat("<string>%s</string>\n", keychain_access_group.CString()); entitlements += "</array>\n"; entitlements += "</dict>\n"; entitlements += "</plist>\n"; return entitlements; }
void UIBuildSettingsWeb::StoreSettings() { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); WebGLSettings settings; TBStr text; appNameEdit_->GetText(text); settings.appName = text.CStr(); text.Clear(); appPackageEdit_->GetText(text); settings.package = text.CStr(); text.Clear(); productNameEdit_->GetText(text); settings.productName = text.CStr(); text.Clear(); companyNameEdit_->GetText(text); settings.companyName = text.CStr(); text.Clear(); buildSystem->GetBuildSettings()->SetWebGLSettings(settings); }
void BuildIOS::Build(const String& buildPath) { buildPath_ = buildPath + "/IOS-Build"; Initialize(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem->DirExists(buildPath_)) fileSystem->RemoveDir(buildPath_, true); #ifdef ATOMIC_PLATFORM_WINDOWS String buildSourceDir = fileSystem->GetProgramDir(); #else String buildSourceDir = fileSystem->GetAppBundleResourceFolder(); #endif String buildAppSourceDir = buildSourceDir + "Deployment/IOS/AtomicPlayer.app"; fileSystem->CreateDir(buildPath_); String buildDestDist = buildPath_ + "/AtomicPlayer.app"; fileSystem->CreateDir(buildDestDist); String resourcePackagePath = buildDestDist + "/AtomicResources.pak"; GenerateResourcePackage(resourcePackagePath); fileSystem->Copy(buildAppSourceDir + "/AtomicPlayer", buildDestDist + "/AtomicPlayer"); fileSystem->Copy(buildAppSourceDir + "/PkgInfo", buildDestDist + "/PkgInfo"); BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); IOSBuildSettings settings = buildSystem->GetBuildSettings()->GetIOSSettings(); fileSystem->Copy(settings.provisionFile, buildDestDist + "/embedded.mobileprovision"); String entitlements = GenerateEntitlements(); String plist = GenerateInfoPlist(); File file(context_, buildPath_ + "/AtomicPlayer.app.xcent", FILE_WRITE); if (file.IsOpen()) { file.Write(entitlements.CString(), entitlements.Length()); file.Close(); } File pfile(context_, buildDestDist + "/Info.plist", FILE_WRITE); if (pfile.IsOpen()) { pfile.Write(plist.CString(), plist.Length()); pfile.Close(); } RunConvertPList(); }
String BuildIOS::GenerateInfoPlist() { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); IOSBuildSettings settings = buildSystem->GetBuildSettings()->GetIOSSettings(); String plist = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; plist += "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"; plist += "<plist version=\"1.0\">\n"; plist += "<dict>\n"; plist += "<key>CFBundleDevelopmentRegion</key>\n"; plist += "<string>English</string>\n"; plist += "<key>CFBundleExecutable</key>\n"; plist += "<string>AtomicPlayer</string>\n"; plist += "<key>CFBundleGetInfoString</key>\n"; plist += "<string>\"Atomic Player\"</string>\n"; plist += "<key>CFBundleIconFile</key>\n"; plist += "<string></string>\n"; plist += "<key>CFBundleIdentifier</key>\n"; plist.AppendWithFormat("<string>%s</string>\n", settings.package.CString()); plist += "<key>CFBundleInfoDictionaryVersion</key>\n"; plist += "<string>6.0</string>\n"; plist += "<key>CFBundleLongVersionString</key>\n"; plist += "<string></string>\n"; plist += "<key>CFBundleName</key>\n"; plist += "<string></string>\n"; plist += "<key>CFBundlePackageType</key>\n"; plist += "<string>APPL</string>\n"; plist += "<key>CFBundleShortVersionString</key>\n"; plist += "<string></string>\n"; plist += "<key>CFBundleSignature</key>\n"; plist += "<string>????</string>\n"; plist += "<key>CFBundleVersion</key>\n"; plist += "<string></string>\n"; plist += "<key>CSResourcesFileMapped</key>\n"; plist += "<true/>\n"; plist += "<key>LSRequiresCarbon</key>\n"; plist += "<true/>\n"; plist += "<key>NSHumanReadableCopyright</key>\n"; plist += "<string>\"(c) Your Company\"</string>\n"; plist += "<key>CFBundleIconFiles</key>\n"; plist += "<array>\n"; plist += "<string></string>\n"; plist += "</array>\n"; plist += "</dict>\n"; plist += "</plist>\n"; return plist; }
void UIBuildSettingsWeb::Refresh() { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); const WebGLSettings& settings = buildSystem->GetBuildSettings()->GetWebGLSettings(); appNameEdit_->SetText(settings.appName.CString()); appPackageEdit_->SetText(settings.package.CString()); productNameEdit_->SetText(settings.productName.CString()); companyNameEdit_->SetText(settings.companyName.CString()); }
void BuildAndroid::HandleAntDebugComplete(StringHash eventType, VariantMap& eventData) { int code = eventData[SubprocessComplete::P_RETCODE].GetInt(); if (!code) { RunADBListDevices(); } else { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_, false); } }
void BuildBase::FailBuild(const String& message) { if (buildFailed_) { LOGERRORF("BuildBase::FailBuild - Attempt to fail already failed build: %s", message.CString()); return; } buildFailed_ = true; BuildError(message); BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); buildSystem->BuildComplete(platformID_, buildPath_, false, message); }
void BuildMac::Build(const String& buildPath) { ToolSystem* tsystem = GetSubsystem<ToolSystem>(); buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder(); Initialize(); BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem->DirExists(buildPath_)) fileSystem->RemoveDir(buildPath_, true); String dataPath = tsystem->GetDataPath(); String appSrcPath = dataPath + "Deployment/MacOS/AtomicPlayer.app"; fileSystem->CreateDir(buildPath_); buildPath_ += "/AtomicPlayer.app"; fileSystem->CreateDir(buildPath_); fileSystem->CreateDir(buildPath_ + "/Contents"); fileSystem->CreateDir(buildPath_ + "/Contents/MacOS"); fileSystem->CreateDir(buildPath_ + "/Contents/Resources"); String resourcePackagePath = buildPath_ + "/Contents/Resources/AtomicResources.pak"; GenerateResourcePackage(resourcePackagePath); fileSystem->Copy(appSrcPath + "/Contents/Resources/Atomic.icns", buildPath_ + "/Contents/Resources/Atomic.icns"); fileSystem->Copy(appSrcPath + "/Contents/Info.plist", buildPath_ + "/Contents/Info.plist"); fileSystem->Copy(appSrcPath + "/Contents/MacOS/AtomicPlayer", buildPath_ + "/Contents/MacOS/AtomicPlayer"); #ifdef ATOMIC_PLATFORM_OSX Vector<String> args; args.Push("+x"); args.Push(buildPath_ + "/Contents/MacOS/AtomicPlayer"); fileSystem->SystemRun("chmod", args); #endif buildPath_ = buildPath + "/Mac-Build"; buildSystem->BuildComplete(PLATFORMID_MAC, buildPath_); }
void BuildWindows::Build(const String& buildPath) { ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>(); buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder(); BuildLog("Starting Windows Deployment"); Initialize(); if (!BuildClean(buildPath_)) return; BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); String rootSourceDir = tenv->GetRootSourceDir(); String playerBinary = tenv->GetPlayerBinary(); String d3d9dll = GetPath(playerBinary) + "/D3DCompiler_47.dll"; if (!BuildCreateDirectory(buildPath_)) return; if (!BuildCreateDirectory(buildPath_ + "/AtomicPlayer_Resources")) return; String resourcePackagePath = buildPath_ + "/AtomicPlayer_Resources/AtomicResources" + PAK_EXTENSION; GenerateResourcePackage(resourcePackagePath); if (buildFailed_) return; if (!BuildCopyFile(playerBinary, buildPath_ + "/AtomicPlayer.exe")) return; if (!BuildCopyFile(d3d9dll, buildPath_ + "/D3DCompiler_47.dll")) return; BuildAtomicNET(); BuildLog("Windows Deployment Complete"); buildSystem->BuildComplete(PLATFORMID_WINDOWS, buildPath_); }
bool ExternalCommand::isResultValid(BuildSystem& system, const BuildValue& value) { // Treat the command as always out-of-date, if requested. if (alwaysOutOfDate) return false; // If the prior value wasn't for a successful command, recompute. if (!value.isSuccessfulCommand()) return false; // If the command's signature has changed since it was built, rebuild. if (value.getCommandSignature() != getSignature()) return false; // Check the timestamps on each of the outputs. for (unsigned i = 0, e = outputs.size(); i != e; ++i) { auto* node = outputs[i]; // Ignore virtual outputs. if (node->isVirtual()) continue; // Rebuild if the output information has changed. // // We intentionally allow missing outputs here, as long as they haven't // changed. This is under the assumption that the commands themselves are // behaving correctly when they exit successfully, and that downstream // commands would diagnose required missing inputs. // // FIXME: CONSISTENCY: One consistency issue in this model currently is that // if the output was missing, then appears, nothing will remove it; that // results in an inconsistent build. What would be nice if we supported // per-edge annotations on whether an output was optional -- in that case we // could enforce and error on the missing output if not annotated, and we // could enable behavior to remove such output files if annotated prior to // running the command. auto info = node->getFileInfo(system.getDelegate().getFileSystem()); // If this output is mutated by the build, we can't rely on equivalence, // only existence. if (node->isMutated()) { if (value.getNthOutputInfo(i).isMissing() != info.isMissing()) return false; continue; } if (value.getNthOutputInfo(i) != info) return false; } // Otherwise, the result is ok. return true; }
void BuildAndroid::HandleADBListDevicesComplete(StringHash eventType, VariantMap& eventData) { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); int code = eventData[SubprocessComplete::P_RETCODE].GetInt(); if (!code) { // check if we have any devices attached, otherwise adb install // will hang looking for devices bool noDevices = true; if (deviceListText_.Length()) { MemoryBuffer reader(deviceListText_.CString(), deviceListText_.Length() + 1); while (!reader.IsEof()) { String line = reader.ReadLine(); if (line.Length() && line[0] >= '0' && line[0] <= '9') { noDevices = false; break; } } } if (!noDevices) RunADBInstall(); else { // can't proceed, though success buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_); } } else { buildSystem->BuildComplete(PLATFORMID_ANDROID, buildPath_, false); } }
void BuildIOS::HandleEvent(StringHash eventType, VariantMap& eventData) { if (eventType == E_SUBPROCESSOUTPUT) { } if (eventType == E_SUBPROCESSCOMPLETE) { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); int code = eventData[SubprocessComplete::P_RETCODE].GetInt(); if (!code) { // success if (currentBuildPhase_ == ConvertPList) { RunCodeSign(); } else if (currentBuildPhase_ == CodeSign) { RunDeploy(); } else if (currentBuildPhase_ == Deploy) { buildSystem->BuildComplete(AE_PLATFORM_IOS, buildPath_); } } else { buildSystem->BuildComplete(AE_PLATFORM_IOS, buildPath_, false); } } }
void BuildCmd::Run() { ATOMIC_LOGINFOF("Building project for: %s", buildPlatform_.CString()); ToolSystem* tsystem = GetSubsystem<ToolSystem>(); Project* project = tsystem->GetProject(); Platform* platform = NULL; platform = tsystem->GetPlatformByName(buildPlatform_); if (!platform) { Error(ToString("Unknown build platform: %s", buildPlatform_.CString())); return; } // create the build BuildBase* buildBase = platform->NewBuild(project); if (!assetsBuildTag_.Empty()) { buildBase->SetAssetBuildTag(assetsBuildTag_); } buildBase->SetAutoLog(autoLog_); // add it to the build system BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); buildSystem->QueueBuild(buildBase); SubscribeToEvent(E_BUILDCOMPLETE, ATOMIC_HANDLER(BuildCmd, HandleBuildComplete)); // TODO: parallel/serial builds buildSystem->StartNextBuild(); }
void AtomicTool::Start() { // Subscribe to events SubscribeToEvent(E_COMMANDERROR, HANDLER(AtomicTool, HandleCommandError)); SubscribeToEvent(E_COMMANDFINISHED, HANDLER(AtomicTool, HandleCommandFinished)); SubscribeToEvent(E_LICENSE_EULAREQUIRED, HANDLER(AtomicTool, HandleLicenseEulaRequired)); SubscribeToEvent(E_LICENSE_ACTIVATIONREQUIRED, HANDLER(AtomicTool, HandleLicenseActivationRequired)); SubscribeToEvent(E_LICENSE_ERROR, HANDLER(AtomicTool, HandleLicenseError)); SubscribeToEvent(E_LICENSE_SUCCESS, HANDLER(AtomicTool, HandleLicenseSuccess)); const Vector<String>& arguments = GetArguments(); ToolSystem* tsystem = new ToolSystem(context_); context_->RegisterSubsystem(tsystem); ToolEnvironment* env = new ToolEnvironment(context_); context_->RegisterSubsystem(env); //#ifdef ATOMIC_DEV_BUILD if (!env->InitFromJSON()) { ErrorExit(ToString("Unable to initialize tool environment from %s", env->GetDevConfigFilename().CString())); return; } if (!cliDataPath_.Length()) { cliDataPath_ = env->GetRootSourceDir() + "/Resources/"; } //#endif tsystem->SetCLI(); tsystem->SetDataPath(cliDataPath_); if (activationKey_.Length()) { DoActivation(); return; } else if (deactivate_) { DoDeactivation(); return; } BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); SharedPtr<CommandParser> parser(new CommandParser(context_)); SharedPtr<Command> cmd(parser->Parse(arguments)); if (!cmd) { String error = "No command found"; if (parser->GetErrorMessage().Length()) error = parser->GetErrorMessage(); ErrorExit(error); return; } if (cmd->RequiresProjectLoad()) { FileSystem* fileSystem = GetSubsystem<FileSystem>(); String projectDirectory = fileSystem->GetCurrentDir(); Vector<String> projectFiles; fileSystem->ScanDir(projectFiles, projectDirectory, "*.atomic", SCAN_FILES, false); if (!projectFiles.Size()) { ErrorExit(ToString("No .atomic project file in %s", projectDirectory.CString())); return; } else if (projectFiles.Size() > 1) { ErrorExit(ToString("Multiple .atomic project files found in %s", projectDirectory.CString())); return; } String projectFile = projectDirectory + "/" + projectFiles[0]; if (!tsystem->LoadProject(projectFile)) { //ErrorExit(ToString("Failed to load project: %s", projectFile.CString())); //return; } // Set the build path String buildFolder = projectDirectory + "/" + "Build"; buildSystem->SetBuildPath(buildFolder); if (!fileSystem->DirExists(buildFolder)) { fileSystem->CreateDir(buildFolder); if (!fileSystem->DirExists(buildFolder)) { ErrorExit(ToString("Failed to create build folder: %s", buildFolder.CString())); return; } } } command_ = cmd; // BEGIN LICENSE MANAGEMENT if (cmd->RequiresLicenseValidation()) { GetSubsystem<LicenseSystem>()->Initialize(); } else { if (command_.Null()) { GetSubsystem<Engine>()->Exit(); return; } command_->Run(); } // END LICENSE MANAGEMENT }
void BuildMac::Build(const String& buildPath) { buildPath_ = buildPath + "/Mac-Build"; Initialize(); BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); // BEGIN LICENSE MANAGEMENT LicenseSystem *licenseSystem = GetSubsystem<LicenseSystem>(); if (licenseSystem->IsStandardLicense()) { if (containsMDL_) { buildSystem->BuildComplete(CE_PLATFORM_MAC, buildPath_, false, true); return; } } // END LICENSE MANAGEMENT FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem->DirExists(buildPath_)) fileSystem->RemoveDir(buildPath_, true); #ifdef CLOCKWORK_PLATFORM_WINDOWS String buildSourceDir = fileSystem->GetProgramDir(); #else String buildSourceDir = fileSystem->GetAppBundleResourceFolder(); #endif buildSourceDir += "Deployment/MacOS/ClockworkPlayer.app"; fileSystem->CreateDir(buildPath_); buildPath_ += "/ClockworkPlayer.app"; fileSystem->CreateDir(buildPath_); fileSystem->CreateDir(buildPath_ + "/Contents"); fileSystem->CreateDir(buildPath_ + "/Contents/MacOS"); fileSystem->CreateDir(buildPath_ + "/Contents/Resources"); String resourcePackagePath = buildPath_ + "/Contents/Resources/ClockworkResources.pak"; GenerateResourcePackage(resourcePackagePath); fileSystem->Copy(buildSourceDir + "/Contents/Resources/Clockwork.icns", buildPath_ + "/Contents/Resources/Clockwork.icns"); fileSystem->Copy(buildSourceDir + "/Contents/Info.plist", buildPath_ + "/Contents/Info.plist"); fileSystem->Copy(buildSourceDir + "/Contents/MacOS/ClockworkPlayer", buildPath_ + "/Contents/MacOS/ClockworkPlayer"); #ifdef CLOCKWORK_PLATFORM_OSX Vector<String> args; args.Push("+x"); args.Push(buildPath_ + "/Contents/MacOS/ClockworkPlayer"); fileSystem->SystemRun("chmod", args); #endif buildPath_ = buildPath + "/Mac-Build"; buildSystem->BuildComplete(CE_PLATFORM_MAC, buildPath_); }
void BuildWindows::Build(const String& buildPath) { BuildSystem* buildSystem = GetSubsystem<BuildSystem>(); FileSystem* fileSystem = GetSubsystem<FileSystem>(); ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>(); ToolSystem* tsystem = GetSubsystem<ToolSystem>(); Project* project = tsystem->GetProject(); buildPath_ = AddTrailingSlash(buildPath); if (!resourcesOnly_) buildPath_ += GetBuildSubfolder(); BuildLog("Starting Windows Deployment"); Initialize(); if (!resourcesOnly_ && !BuildClean(buildPath_)) return; String rootSourceDir = tenv->GetRootSourceDir(); if (!BuildCreateDirectory(buildPath_)) return; if (!resourcesOnly_ && !BuildCreateDirectory(buildPath_ + "/AtomicPlayer_Resources")) return; String resourcePackagePath = buildPath_ + "/AtomicPlayer_Resources/AtomicResources" + PAK_EXTENSION; if (resourcesOnly_) { resourcePackagePath = buildPath_ + "/AtomicResources" + PAK_EXTENSION; } GenerateResourcePackage(resourcePackagePath); if (buildFailed_) return; if (resourcesOnly_) return; if (!BuildCreateDirectory(buildPath_ + "/Settings")) return; String engineJSON(GetSettingsDirectory() + "/Engine.json"); if (fileSystem->FileExists(engineJSON)) { if (!BuildCopyFile(engineJSON, buildPath_ + "/Settings/Engine.json")) return; } // TODO: Set project as managed and don't key off project assembly if (fileSystem->FileExists(project->GetResourcePath() + project->GetProjectSettings()->GetName() + ".dll")) { if (!BuildManaged(buildPath)) return; } else { BuildNative(buildPath); } BuildLog("Windows Deployment Complete"); buildSystem->BuildComplete(PLATFORMID_WINDOWS, buildPath_); }