summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2004-02-28 23:59:19 (GMT)
committerAndy Cedilnik <andy.cedilnik@kitware.com>2004-02-28 23:59:19 (GMT)
commitb1a74218401a6d990b570cae8141cad97fb8dc19 (patch)
tree3775e35ac3f08525ad6808e53f0faf027fe9f357
parent6ab87555ea483601cb1829f3b6e9d3d77d6746ff (diff)
downloadCMake-b1a74218401a6d990b570cae8141cad97fb8dc19.zip
CMake-b1a74218401a6d990b570cae8141cad97fb8dc19.tar.gz
CMake-b1a74218401a6d990b570cae8141cad97fb8dc19.tar.bz2
ENH: Styart working on bundles support and abstract WIN32_EXECUTABLE
-rw-r--r--Modules/MacOSXBundleInfo.plist.in36
-rw-r--r--Source/cmAddExecutableCommand.cxx60
-rw-r--r--Source/cmCPluginAPI.cxx6
-rw-r--r--Source/cmFindPackageCommand.cxx56
-rw-r--r--Source/cmLocalGenerator.cxx5
-rw-r--r--Source/cmLocalUnixMakefileGenerator.cxx37
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx27
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx5
-rw-r--r--Source/cmMakefile.cxx54
-rw-r--r--Source/cmMakefile.h9
-rw-r--r--Source/cmTarget.h2
11 files changed, 193 insertions, 104 deletions
diff --git a/Modules/MacOSXBundleInfo.plist.in b/Modules/MacOSXBundleInfo.plist.in
new file mode 100644
index 0000000..1f68ccf
--- /dev/null
+++ b/Modules/MacOSXBundleInfo.plist.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${APPLE_GUI_EXECUTABLE}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${APPLE_GUI_INFO_STRING}</string>
+ <key>CFBundleIconFile</key>
+ <string>${APPLE_GUI_ICON}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${APPLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${APPLE_GUI_LONG_VERSION_STRING}</string>
+ <key>CFBundleName</key>
+ <string>${APPLE_GUI_BUNDLE_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${APPLE_GUI_SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${APPLE_GUI_BUNDLE_VERSION}</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>LSRequiresCarbon</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>${APPLE_GUI_COPYRIGHT}</string>
+</dict>
+</plist>
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 09aae18..71f3b57 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -30,16 +30,62 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args)
++s;
bool use_win32 = false;
-
- if (*s == "WIN32")
+ bool use_macbundle = false;
+ while ( s != args.end() )
{
- ++s;
- use_win32 = true;
+ if (*s == "WIN32")
+ {
+ ++s;
+ use_win32 = true;
+ }
+ else if ( *s == "MACBUNDLE" )
+ {
+ ++s;
+ use_macbundle = true;
+ }
+ else
+ {
+ break;
+ }
}
std::vector<std::string> srclists(s, args.end());
- m_Makefile->AddExecutable(exename.c_str(), srclists, use_win32);
-
+ cmTarget* tgt = m_Makefile->AddExecutable(exename.c_str(), srclists);
+ if ( use_win32 )
+ {
+ tgt->SetProperty("WIN32_EXECUTABLE", "ON");
+ }
+ if ( use_macbundle)
+ {
+ tgt->SetProperty("MACOSX_BUNDLE", "ON");
+#ifdef __APPLE__
+ cmListFileFunction func;
+ func.m_Name = "CONFIGURE_FILE";
+ std::string f1 = m_Makefile->GetModulesFile("MacOSXBundleInfo.plist.in");
+ if ( f1.size() == 0 )
+ {
+ this->SetError("could not find Mac OSX bundle template file.");
+ return false;
+ }
+ std::string macdir = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
+ if ( macdir.size() == 0 )
+ {
+ macdir = m_Makefile->GetCurrentOutputDirectory();
+ if(macdir.size() && macdir[macdir.size()-1] != '/')
+ {
+ macdir += "/";
+ }
+ }
+ macdir += exename + ".app/Contents/";
+ std::string f2 = macdir + "Info.plist";
+ macdir += "MacOS";
+ cmSystemTools::MakeDirectory(macdir.c_str());
+
+ func.m_Arguments.push_back(cmListFileArgument(f1, true));
+ func.m_Arguments.push_back(cmListFileArgument(f2, true));
+ m_Makefile->ExecuteCommand(func);
+#endif
+ }
+
return true;
}
-
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 7061f5d..3ca886a 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -187,7 +187,11 @@ void cmAddExecutable(void *arg, const char *exename,
{
srcs2.push_back(srcs[i]);
}
- mf->AddExecutable(exename, srcs2, (win32 ? true : false));
+ cmTarget* tg = mf->AddExecutable(exename, srcs2);
+ if ( win32 )
+ {
+ tg->SetProperty("WIN32_EXECUTABLE", "ON");
+ }
}
void cmAddUtilityCommand(void *arg, const char* utilityName,
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 3b7a526..ca26671 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -219,50 +219,24 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
//----------------------------------------------------------------------------
bool cmFindPackageCommand::FindModule(bool& found, bool quiet)
{
- // Search the CMAKE_MODULE_PATH for a Find<name>.cmake module.
- found = false;
- std::string module;
- std::vector<std::string> modulePath;
- const char* def = m_Makefile->GetDefinition("CMAKE_MODULE_PATH");
- if(def)
+ std::string module = "/Find";
+ module += this->Name;
+ module += ".cmake";
+ std::string mfile = m_Makefile->GetModulesFile(module.c_str());
+ if ( mfile.size() )
{
- cmSystemTools::ExpandListArgument(def, modulePath);
- }
-
- // Also search in the standard modules location.
- def = m_Makefile->GetDefinition("CMAKE_ROOT");
- if(def)
- {
- std::string rootModules = def;
- rootModules += "/Modules";
- modulePath.push_back(rootModules);
- }
-
- // Look through the possible module directories.
- for(std::vector<std::string>::iterator i = modulePath.begin();
- i != modulePath.end(); ++i)
- {
- module = *i;
- cmSystemTools::ConvertToUnixSlashes(module);
- module += "/Find";
- module += this->Name;
- module += ".cmake";
- if(cmSystemTools::FileExists(module.c_str()))
+ if(quiet)
{
- found = true;
-
- if(quiet)
- {
- // Tell the module that is about to be read that it should find
- // quietly.
- std::string quietly = this->Name;
- quietly += "_FIND_QUIETLY";
- m_Makefile->AddDefinition(quietly.c_str(), "1");
- }
-
- // Load the module we found.
- return this->ReadListFile(module.c_str());
+ // Tell the module that is about to be read that it should find
+ // quietly.
+ std::string quietly = this->Name;
+ quietly += "_FIND_QUIETLY";
+ m_Makefile->AddDefinition(quietly.c_str(), "1");
}
+
+ // Load the module we found.
+ found = true;
+ return this->ReadListFile(mfile.c_str());
}
return true;
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 1f95d70..a108b13 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -165,7 +165,6 @@ void cmLocalGenerator::GenerateInstallRules()
}
}
break;
- case cmTarget::WIN32_EXECUTABLE:
case cmTarget::EXECUTABLE:
fname = exeOutPath;
fname += this->GetFullTargetName(l->first.c_str(), l->second);
@@ -253,8 +252,7 @@ void cmLocalGenerator::AddInstallRule(std::ostream& fout, const char* dest,
switch ( type )
{
case cmTarget::INSTALL_PROGRAMS: stype = "PROGRAM"; break;
- case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE: stype = "EXECUTABLE"; break;
+ case cmTarget::EXECUTABLE: stype = "EXECUTABLE"; break;
case cmTarget::STATIC_LIBRARY: stype = "STATIC_LIBRARY"; break;
case cmTarget::SHARED_LIBRARY: stype = "SHARED_LIBRARY"; break;
case cmTarget::MODULE_LIBRARY: stype = "MODULE"; break;
@@ -302,7 +300,6 @@ std::string cmLocalGenerator::GetFullTargetName(const char* n,
suffixVar = "CMAKE_SHARED_MODULE_SUFFIX";
break;
case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE:
targetSuffix = cmSystemTools::GetExecutableExtension();
case cmTarget::UTILITY:
case cmTarget::INSTALL_FILES:
diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx
index 65b0ca9..7a7d659 100644
--- a/Source/cmLocalUnixMakefileGenerator.cxx
+++ b/Source/cmLocalUnixMakefileGenerator.cxx
@@ -350,7 +350,6 @@ std::string cmLocalUnixMakefileGenerator::GetBaseTargetName(const char* n,
prefixVar = "CMAKE_SHARED_MODULE_PREFIX";
break;
case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE:
case cmTarget::UTILITY:
case cmTarget::INSTALL_FILES:
case cmTarget::INSTALL_PROGRAMS:
@@ -383,7 +382,6 @@ std::string cmLocalUnixMakefileGenerator::GetFullTargetName(const char* n,
suffixVar = "CMAKE_SHARED_MODULE_SUFFIX";
break;
case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE:
targetSuffix = cmSystemTools::GetExecutableExtension();
case cmTarget::UTILITY:
case cmTarget::INSTALL_FILES:
@@ -454,8 +452,7 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
for(cmTargets::const_iterator l = tgts.begin();
l != tgts.end(); l++)
{
- if ((l->second.GetType() == cmTarget::EXECUTABLE ||
- l->second.GetType() == cmTarget::WIN32_EXECUTABLE))
+ if ( l->second.GetType() == cmTarget::EXECUTABLE )
{
path = "... ";
path += l->first + cmSystemTools::GetExecutableExtension();
@@ -499,8 +496,7 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
for(cmTargets::const_iterator l = tgts.begin();
l != tgts.end(); l++)
{
- if ((l->second.GetType() == cmTarget::EXECUTABLE ||
- l->second.GetType() == cmTarget::WIN32_EXECUTABLE) &&
+ if (l->second.GetType() == cmTarget::EXECUTABLE &&
l->second.IsInAll())
{
path = m_ExecutableOutputPath;
@@ -676,8 +672,7 @@ void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
std::string linkLibs;
// Flags to link an executable to shared libraries.
- if( tgt.GetType() == cmTarget::EXECUTABLE ||
- tgt.GetType() == cmTarget::WIN32_EXECUTABLE )
+ if( tgt.GetType() == cmTarget::EXECUTABLE )
{
if(cxx)
{
@@ -1320,6 +1315,16 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
const cmTarget &t)
{
std::string linkFlags;
+ bool win32_executable = false;
+ bool macosx_bundle = false;
+ if ( t.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ win32_executable = true;
+ }
+ if ( t.GetPropertyAsBool("MACOSX_BUNDLE") )
+ {
+ macosx_bundle = true;
+ }
std::string buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
buildType = cmSystemTools::UpperCase(buildType);
@@ -1335,6 +1340,14 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
target += "/";
}
}
+#ifdef __APPLE__
+ if ( macosx_bundle )
+ {
+ // Make bundle directories
+ target += name;
+ target += ".app/Contents/MacOS/";
+ }
+#endif
target += name;
target += cmSystemTools::GetExecutableExtension();
target = this->ConvertToRelativeOutputPath(target.c_str());
@@ -1384,6 +1397,7 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
std::string comment = "executable";
std::vector<std::string> commands;
+
std::string customCommands = this->CreatePreBuildRules(t, name);
if(customCommands.size() > 0)
{
@@ -1406,7 +1420,7 @@ void cmLocalUnixMakefileGenerator::OutputExecutableRule(std::ostream& fout,
linkFlags += " ";
}
- if(t.GetType() == cmTarget::WIN32_EXECUTABLE)
+ if(win32_executable)
{
linkFlags += this->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
linkFlags += " ";
@@ -1526,7 +1540,6 @@ void cmLocalUnixMakefileGenerator::OutputTargets(std::ostream& fout)
this->OutputModuleLibraryRule(fout, l->first.c_str(), l->second);
break;
case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE:
this->OutputExecutableRule(fout, l->first.c_str(), l->second);
break;
case cmTarget::UTILITY:
@@ -1564,8 +1577,7 @@ void cmLocalUnixMakefileGenerator::OutputDependLibs(std::ostream& fout)
|| (l->second.GetType() == cmTarget::MODULE_LIBRARY)
|| (l->second.GetType() == cmTarget::STATIC_LIBRARY)
|| (l->second.GetType() == cmTarget::EXECUTABLE)
- || (l->second.GetType() == cmTarget::UTILITY)
- || (l->second.GetType() == cmTarget::WIN32_EXECUTABLE))
+ || (l->second.GetType() == cmTarget::UTILITY))
{
fout << this->CreateMakeVariable(l->first.c_str(), "_DEPEND_LIBS") << " = ";
@@ -2434,7 +2446,6 @@ void cmLocalUnixMakefileGenerator::OutputInstallRules(std::ostream& fout)
<< installNameReal << "\" \"" << installNameSO << "\" \"" << installName
<< "\"\n";
}; break;
- case cmTarget::WIN32_EXECUTABLE:
case cmTarget::EXECUTABLE:
fname = m_ExecutableOutputPath;
fname += this->GetFullTargetName(l->first.c_str(), l->second);
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 0d3f8ca..28b08df 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -97,9 +97,6 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
case cmTarget::EXECUTABLE:
this->SetBuildType(EXECUTABLE,l->first.c_str(), l->second);
break;
- case cmTarget::WIN32_EXECUTABLE:
- this->SetBuildType(WIN32_EXECUTABLE,l->first.c_str(), l->second);
- break;
case cmTarget::UTILITY:
this->SetBuildType(UTILITY, l->first.c_str(), l->second);
break;
@@ -581,16 +578,20 @@ void cmLocalVisualStudio6Generator::SetBuildType(BuildType b,
m_DSPFooterTemplate += "/DLLFooter.dsptemplate";
break;
case EXECUTABLE:
- m_DSPHeaderTemplate = root;
- m_DSPHeaderTemplate += "/EXEHeader.dsptemplate";
- m_DSPFooterTemplate = root;
- m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
- break;
- case WIN32_EXECUTABLE:
- m_DSPHeaderTemplate = root;
- m_DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
- m_DSPFooterTemplate = root;
- m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
+ if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ m_DSPHeaderTemplate = root;
+ m_DSPHeaderTemplate += "/EXEWinHeader.dsptemplate";
+ m_DSPFooterTemplate = root;
+ m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
+ }
+ else
+ {
+ m_DSPHeaderTemplate = root;
+ m_DSPHeaderTemplate += "/EXEHeader.dsptemplate";
+ m_DSPFooterTemplate = root;
+ m_DSPFooterTemplate += "/EXEFooter.dsptemplate";
+ }
break;
case UTILITY:
m_DSPHeaderTemplate = root;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index bfd1851..f79d689 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -235,7 +235,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
configType = "2";
break;
case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE:
configType = "1";
break;
case cmTarget::UTILITY:
@@ -491,8 +490,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
}
std::string extraLinkOptions;
- if((target.GetType() == cmTarget::EXECUTABLE) ||
- (target.GetType() == cmTarget::WIN32_EXECUTABLE))
+ if(target.GetType() == cmTarget::EXECUTABLE)
{
extraLinkOptions = m_Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS");
}
@@ -575,7 +573,6 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
break;
case cmTarget::EXECUTABLE:
- case cmTarget::WIN32_EXECUTABLE:
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"VCLinkerTool\"\n"
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 348c489..ecdd3b0 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1053,29 +1053,16 @@ void cmMakefile::AddLibrary(const char* lname, int shared,
}
}
-void cmMakefile::AddExecutable(const char *exeName,
+cmTarget* cmMakefile::AddExecutable(const char *exeName,
const std::vector<std::string> &srcs)
{
- this->AddExecutable(exeName,srcs,false);
-}
-
-void cmMakefile::AddExecutable(const char *exeName,
- const std::vector<std::string> &srcs,
- bool win32)
-{
cmTarget target;
- if (win32)
- {
- target.SetType(cmTarget::WIN32_EXECUTABLE);
- }
- else
- {
- target.SetType(cmTarget::EXECUTABLE);
- }
+ target.SetType(cmTarget::EXECUTABLE);
target.SetInAll(true);
target.GetSourceLists() = srcs;
this->AddGlobalLinkInformation(exeName, target);
- m_Targets.insert(cmTargets::value_type(exeName,target));
+ cmTargets::iterator it =
+ m_Targets.insert(cmTargets::value_type(exeName,target)).first;
// Add an entry into the cache
std::string exePath = exeName;
@@ -1084,6 +1071,7 @@ void cmMakefile::AddExecutable(const char *exeName,
AddCacheEntry(exePath.c_str(),
this->GetCurrentOutputDirectory(),
"Path to an executable", cmCacheManager::INTERNAL);
+ return &it->second;
}
@@ -2186,3 +2174,35 @@ std::string cmMakefile::FindLibrary(const char* name,
return cmSystemTools::FindLibrary(name, path);
}
+
+std::string cmMakefile::GetModulesFile(const char* filename)
+{
+ std::vector<std::string> modulePath;
+ const char* def = this->GetDefinition("CMAKE_MODULE_PATH");
+ if(def)
+ {
+ cmSystemTools::ExpandListArgument(def, modulePath);
+ }
+
+ // Also search in the standard modules location.
+ def = this->GetDefinition("CMAKE_ROOT");
+ if(def)
+ {
+ std::string rootModules = def;
+ rootModules += "/Modules";
+ modulePath.push_back(rootModules);
+ }
+ //std::string Look through the possible module directories.
+ for(std::vector<std::string>::iterator i = modulePath.begin();
+ i != modulePath.end(); ++i)
+ {
+ std::string itempl = *i;
+ cmSystemTools::ConvertToUnixSlashes(itempl);
+ itempl += filename;
+ if(cmSystemTools::FileExists(itempl.c_str()))
+ {
+ return itempl;
+ }
+ }
+ return "";
+}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 28a5c3e..620691b 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -165,10 +165,8 @@ public:
/**
* Add an executable to the build.
*/
- void AddExecutable(const char *exename,
+ cmTarget* AddExecutable(const char *exename,
const std::vector<std::string> &srcs);
- void AddExecutable(const char *exename,
- const std::vector<std::string> &srcs, bool win32);
/**
* Add a utility to the build. A utiltity target is
@@ -617,6 +615,11 @@ public:
* Get a list of macros as a ; separated string
*/
void GetListOfMacros(std::string& macros);
+
+ /**
+ * Return a location of a file in cmake or custom modules directory
+ */
+ std::string GetModulesFile(const char* name);
protected:
// add link libraries and directories to the target
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index d31ca3a..804e126 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -29,7 +29,7 @@ class cmSourceFile;
class cmTarget
{
public:
- enum TargetType { EXECUTABLE, WIN32_EXECUTABLE, STATIC_LIBRARY,
+ enum TargetType { EXECUTABLE, STATIC_LIBRARY,
SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, INSTALL_FILES,
INSTALL_PROGRAMS };