ENH: add a wrapper for xcodebuild to get around bug and verbose output
This commit is contained in:
parent
bc649db7cc
commit
ae10b3578d
@ -282,6 +282,11 @@ SET(CPACK_SRCS
|
|||||||
ADD_LIBRARY(CPackLib ${CPACK_SRCS})
|
ADD_LIBRARY(CPackLib ${CPACK_SRCS})
|
||||||
TARGET_LINK_LIBRARIES(CPackLib CMakeLib)
|
TARGET_LINK_LIBRARIES(CPackLib CMakeLib)
|
||||||
|
|
||||||
|
IF(APPLE)
|
||||||
|
ADD_EXECUTABLE(cmakexbuild cmakexbuild.cxx)
|
||||||
|
TARGET_LINK_LIBRARIES(cmakexbuild CMakeLib)
|
||||||
|
ENDIF(APPLE)
|
||||||
|
|
||||||
# Build CMake executable
|
# Build CMake executable
|
||||||
ADD_EXECUTABLE(cmake cmakemain.cxx)
|
ADD_EXECUTABLE(cmake cmakemain.cxx)
|
||||||
TARGET_LINK_LIBRARIES(cmake CMakeLib)
|
TARGET_LINK_LIBRARIES(cmake CMakeLib)
|
||||||
@ -1088,4 +1093,8 @@ INCLUDE (${CMAKE_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
|
|||||||
INSTALL_TARGETS(/bin cmake)
|
INSTALL_TARGETS(/bin cmake)
|
||||||
INSTALL_TARGETS(/bin ctest)
|
INSTALL_TARGETS(/bin ctest)
|
||||||
INSTALL_TARGETS(/bin cpack)
|
INSTALL_TARGETS(/bin cpack)
|
||||||
|
IF(APPLE)
|
||||||
|
INSTALL_TARGETS(/bin cmakexbuild)
|
||||||
|
ENDIF(APPLE)
|
||||||
|
|
||||||
INSTALL_FILES(${CMAKE_DATA_DIR}/include cmCPluginAPI.h)
|
INSTALL_FILES(${CMAKE_DATA_DIR}/include cmCPluginAPI.h)
|
||||||
|
@ -99,7 +99,25 @@ void cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
|
|||||||
"make program",
|
"make program",
|
||||||
cmCacheManager::FILEPATH);
|
cmCacheManager::FILEPATH);
|
||||||
}
|
}
|
||||||
|
if(makeProgram.find("xcodebuild") != makeProgram.npos)
|
||||||
|
{
|
||||||
|
// due to the text file busy /bin/sh problem with xcodebuild
|
||||||
|
// use the cmakexbuild wrapper instead. This program
|
||||||
|
// will run xcodebuild and if it sees the error text file busy
|
||||||
|
// it will stop forwarding output, and let the build finish.
|
||||||
|
// Then it will retry the build. It will continue this
|
||||||
|
// untill no text file busy errors occur.
|
||||||
|
std::string cmakexbuild =
|
||||||
|
this->CMakeInstance->GetCacheManager()->GetCacheValue("CMAKE_COMMAND");
|
||||||
|
cmakexbuild = cmakexbuild.substr(0, cmakexbuild.length()-5);
|
||||||
|
cmakexbuild += "cmakexbuild";
|
||||||
|
|
||||||
|
this->GetCMakeInstance()->AddCacheEntry("CMAKE_MAKE_PROGRAM",
|
||||||
|
cmakexbuild.c_str(),
|
||||||
|
"make program",
|
||||||
|
cmCacheManager::FILEPATH);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable the given language
|
// enable the given language
|
||||||
@ -1313,9 +1331,8 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(cmTargets* targets)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
singleLine.push_back(cmakeCommand);
|
singleLine.push_back(cmakeCommand);
|
||||||
singleLine.push_back("-H$(CMAKE_SOURCE_DIR)");
|
|
||||||
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
|
|
||||||
singleLine.push_back("-i");
|
singleLine.push_back("-i");
|
||||||
|
singleLine.push_back(".");
|
||||||
cpackCommandLines.push_back(singleLine);
|
cpackCommandLines.push_back(singleLine);
|
||||||
(*targets)[editCacheTargetName] =
|
(*targets)[editCacheTargetName] =
|
||||||
this->CreateGlobalTarget(
|
this->CreateGlobalTarget(
|
||||||
|
@ -1148,8 +1148,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||||||
this->CreateString("mh_bundle"));
|
this->CreateString("mh_bundle"));
|
||||||
buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC",
|
buildSettings->AddAttribute("GCC_DYNAMIC_NO_PIC",
|
||||||
this->CreateString("NO"));
|
this->CreateString("NO"));
|
||||||
buildSettings->AddAttribute("PREBINDING",
|
|
||||||
this->CreateString("NO"));
|
|
||||||
buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN",
|
buildSettings->AddAttribute("GCC_SYMBOLS_PRIVATE_EXTERN",
|
||||||
this->CreateString("NO"));
|
this->CreateString("NO"));
|
||||||
buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN",
|
buildSettings->AddAttribute("GCC_INLINES_ARE_PRIVATE_EXTERN",
|
||||||
@ -1245,7 +1243,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(this->XcodeVersion >= 22)
|
||||||
|
{
|
||||||
|
buildSettings->AddAttribute("PREBINDING",
|
||||||
|
this->CreateString("NO"));
|
||||||
|
}
|
||||||
std::string dirs;
|
std::string dirs;
|
||||||
std::vector<std::string> includes;
|
std::vector<std::string> includes;
|
||||||
this->CurrentLocalGenerator->GetIncludeDirectories(includes);
|
this->CurrentLocalGenerator->GetIncludeDirectories(includes);
|
||||||
|
@ -231,20 +231,6 @@ int cmTryCompileCommand::CoreTryCompileCode(
|
|||||||
// actually do the try compile now that everything is setup
|
// actually do the try compile now that everything is setup
|
||||||
int res = mf->TryCompile(sourceDirectory, binaryDirectory,
|
int res = mf->TryCompile(sourceDirectory, binaryDirectory,
|
||||||
projectName, targetName, &cmakeFlags, &output);
|
projectName, targetName, &cmakeFlags, &output);
|
||||||
// for the xcode generator
|
|
||||||
if(strcmp(mf->GetCMakeInstance()->GetGlobalGenerator()->GetName() ,
|
|
||||||
"Xcode") == 0)
|
|
||||||
{
|
|
||||||
int numTrys = 0;
|
|
||||||
while(output.find("/bin/sh: bad interpreter: Text file busy")
|
|
||||||
!= output.npos && numTrys < 4)
|
|
||||||
{
|
|
||||||
output = "";
|
|
||||||
res = mf->TryCompile(sourceDirectory, binaryDirectory,
|
|
||||||
projectName, targetName, &cmakeFlags, &output);
|
|
||||||
numTrys++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( erroroc )
|
if ( erroroc )
|
||||||
{
|
{
|
||||||
cmSystemTools::SetErrorOccured();
|
cmSystemTools::SetErrorOccured();
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
#include "cmCacheManager.h"
|
#include "cmCacheManager.h"
|
||||||
#include "cmListFileCache.h"
|
#include "cmListFileCache.h"
|
||||||
|
#include "cmakewizard.h"
|
||||||
|
|
||||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||||
#include "cmakewizard.h"
|
|
||||||
#include "cmDynamicLoader.h"
|
#include "cmDynamicLoader.h"
|
||||||
#include "cmDocumentation.h"
|
#include "cmDocumentation.h"
|
||||||
|
|
||||||
@ -182,9 +182,7 @@ int do_cmake(int ac, char** av)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
|
||||||
bool wiz = false;
|
bool wiz = false;
|
||||||
#endif
|
|
||||||
bool command = false;
|
bool command = false;
|
||||||
bool list_cached = false;
|
bool list_cached = false;
|
||||||
bool list_all_cached = false;
|
bool list_all_cached = false;
|
||||||
@ -194,16 +192,13 @@ int do_cmake(int ac, char** av)
|
|||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
for(int i =0; i < ac; ++i)
|
for(int i =0; i < ac; ++i)
|
||||||
{
|
{
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
|
||||||
if(strcmp(av[i], "-i") == 0)
|
if(strcmp(av[i], "-i") == 0)
|
||||||
{
|
{
|
||||||
wiz = true;
|
wiz = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
|
||||||
// if command has already been set, then
|
// if command has already been set, then
|
||||||
// do not eat the -E
|
// do not eat the -E
|
||||||
if (!command && strcmp(av[i], "-E") == 0)
|
else if (!command && strcmp(av[i], "-E") == 0)
|
||||||
{
|
{
|
||||||
command = true;
|
command = true;
|
||||||
}
|
}
|
||||||
@ -251,13 +246,11 @@ int do_cmake(int ac, char** av)
|
|||||||
int ret = cmake::ExecuteCMakeCommand(args);
|
int ret = cmake::ExecuteCMakeCommand(args);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
|
||||||
if (wiz)
|
if (wiz)
|
||||||
{
|
{
|
||||||
cmakewizard wizard;
|
cmakewizard wizard;
|
||||||
return wizard.RunWizard(args);
|
return wizard.RunWizard(args);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
cmake cm;
|
cmake cm;
|
||||||
cm.SetProgressCallback(updateProgress, 0);
|
cm.SetProgressCallback(updateProgress, 0);
|
||||||
cm.SetScriptMode(script_mode);
|
cm.SetScriptMode(script_mode);
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
#include <cmsys/Process.h>
|
#include <cmsys/Process.h>
|
||||||
#include "cmStandardIncludes.h"
|
#include "cmStandardIncludes.h"
|
||||||
|
|
||||||
|
// This is a wrapper program for xcodebuild
|
||||||
|
// it calls xcodebuild, and does two things
|
||||||
|
// it removes much of the output, all the setevn
|
||||||
|
// stuff. Also, it checks for the text file busy
|
||||||
|
// error, and re-runs xcodebuild until that error does
|
||||||
|
// not show up.
|
||||||
|
|
||||||
int WaitForLine(cmsysProcess* process, std::string& line,
|
int WaitForLine(cmsysProcess* process, std::string& line,
|
||||||
double timeout,
|
double timeout,
|
||||||
std::vector<char>& out,
|
std::vector<char>& out,
|
||||||
@ -113,29 +120,31 @@ int RunXCode(std::vector<const char*>& argv, bool& hitbug)
|
|||||||
std::vector<char> out;
|
std::vector<char> out;
|
||||||
std::vector<char> err;
|
std::vector<char> err;
|
||||||
std::string line;
|
std::string line;
|
||||||
int pipe =WaitForLine(cp, line, 0, out, err);
|
int pipe =WaitForLine(cp, line, 100.0, out, err);
|
||||||
while(pipe != cmsysProcess_Pipe_None)
|
while(pipe != cmsysProcess_Pipe_None)
|
||||||
{
|
{
|
||||||
if(line.find("/bin/sh: bad interpreter: Text file busy")
|
if(line.find("/bin/sh: bad interpreter: Text file busy")
|
||||||
!= line.npos)
|
!= line.npos)
|
||||||
{
|
{
|
||||||
hitbug = true;
|
hitbug = true;
|
||||||
std::cerr << "Found xcodebuild bug: " << line << "\n";
|
std::cerr << "Hit xcodebuild bug : " << line << "\n";
|
||||||
}
|
}
|
||||||
// if the bug is hit, no more output should be generated
|
// if the bug is hit, no more output should be generated
|
||||||
// because it may contain bogus errors
|
// because it may contain bogus errors
|
||||||
if(!hitbug)
|
// also remove all output with setenv in it to tone down
|
||||||
|
// the verbosity of xcodebuild
|
||||||
|
if(!hitbug && (line.find("setenv") == line.npos))
|
||||||
{
|
{
|
||||||
if(pipe == cmsysProcess_Pipe_STDERR)
|
if(pipe == cmsysProcess_Pipe_STDERR)
|
||||||
{
|
{
|
||||||
std::cerr << line;
|
std::cerr << line << "\n";
|
||||||
}
|
}
|
||||||
else if(pipe == cmsysProcess_Pipe_STDOUT)
|
else if(pipe == cmsysProcess_Pipe_STDOUT)
|
||||||
{
|
{
|
||||||
std::cout << line;
|
std::cout << line << "\n";
|
||||||
}
|
}
|
||||||
pipe =WaitForLine(cp, line, 0, out, err);
|
|
||||||
}
|
}
|
||||||
|
pipe =WaitForLine(cp, line, 100, out, err);
|
||||||
}
|
}
|
||||||
cmsysProcess_WaitForExit(cp, 0);
|
cmsysProcess_WaitForExit(cp, 0);
|
||||||
if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
|
if(cmsysProcess_GetState(cp) == cmsysProcess_State_Exited)
|
||||||
@ -144,7 +153,6 @@ int RunXCode(std::vector<const char*>& argv, bool& hitbug)
|
|||||||
}
|
}
|
||||||
if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
|
if(cmsysProcess_GetState(cp) == cmsysProcess_State_Error)
|
||||||
{
|
{
|
||||||
std::cerr << "error\n";
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -160,12 +168,11 @@ int main(int ac, char*av[])
|
|||||||
}
|
}
|
||||||
argv.push_back(0);
|
argv.push_back(0);
|
||||||
bool hitbug = true;
|
bool hitbug = true;
|
||||||
int ret;
|
int ret = 0;
|
||||||
while(hitbug)
|
while(hitbug)
|
||||||
{
|
{
|
||||||
ret = RunXCode(argv, hitbug);
|
ret = RunXCode(argv, hitbug);
|
||||||
}
|
}
|
||||||
std::cerr << "ret " << ret << "\n";
|
|
||||||
if(ret < 0)
|
if(ret < 0)
|
||||||
{
|
{
|
||||||
return 255;
|
return 255;
|
||||||
|
@ -83,7 +83,6 @@ CMAKE_PROBLEMATIC_FILES="\
|
|||||||
"
|
"
|
||||||
|
|
||||||
CMAKE_UNUSED_SOURCES="\
|
CMAKE_UNUSED_SOURCES="\
|
||||||
cmakewizard \
|
|
||||||
cmGlobalXCodeGenerator \
|
cmGlobalXCodeGenerator \
|
||||||
cmLocalXCodeGenerator \
|
cmLocalXCodeGenerator \
|
||||||
cmXCodeObject \
|
cmXCodeObject \
|
||||||
@ -94,6 +93,7 @@ CMAKE_UNUSED_SOURCES="\
|
|||||||
CMAKE_CXX_SOURCES="\
|
CMAKE_CXX_SOURCES="\
|
||||||
cmake \
|
cmake \
|
||||||
cmakemain \
|
cmakemain \
|
||||||
|
cmakewizard \
|
||||||
cmCommandArgumentLexer \
|
cmCommandArgumentLexer \
|
||||||
cmCommandArgumentParser \
|
cmCommandArgumentParser \
|
||||||
cmCommandArgumentParserHelper \
|
cmCommandArgumentParserHelper \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user