try_compile: Add COPY_FILE_ERROR option to capture failure
When the COPY_FILE operation fails optionally capture the error message with a COPY_FILE_ERROR option instead of reporting the error immediately. This gives callers a chance to do something else or report the error. Teach the RunCMake.try_compile test to cover bad argument combinations involving COPY_FILE_ERROR. Teach the TryCompile test to cover the case of a COPY_FILE error message captured by COPY_FILE_ERROR.
This commit is contained in:
parent
448a677148
commit
c28715b16c
|
@ -32,18 +32,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
|||
std::vector<std::string> compileDefs;
|
||||
std::string outputVariable;
|
||||
std::string copyFile;
|
||||
std::string copyFileError;
|
||||
std::vector<cmTarget*> targets;
|
||||
std::string libsToLink = " ";
|
||||
bool useOldLinkLibs = true;
|
||||
char targetNameBuf[64];
|
||||
bool didOutputVariable = false;
|
||||
bool didCopyFile = false;
|
||||
bool didCopyFileError = false;
|
||||
bool useSources = argv[2] == "SOURCES";
|
||||
std::vector<std::string> sources;
|
||||
|
||||
enum Doing { DoingNone, DoingCMakeFlags, DoingCompileDefinitions,
|
||||
DoingLinkLibraries, DoingOutputVariable, DoingCopyFile,
|
||||
DoingSources };
|
||||
DoingCopyFileError, DoingSources };
|
||||
Doing doing = useSources? DoingSources : DoingNone;
|
||||
for(size_t i=3; i < argv.size(); ++i)
|
||||
{
|
||||
|
@ -74,6 +76,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
|||
doing = DoingCopyFile;
|
||||
didCopyFile = true;
|
||||
}
|
||||
else if(argv[i] == "COPY_FILE_ERROR")
|
||||
{
|
||||
doing = DoingCopyFileError;
|
||||
didCopyFileError = true;
|
||||
}
|
||||
else if(doing == DoingCMakeFlags)
|
||||
{
|
||||
cmakeFlags.push_back(argv[i]);
|
||||
|
@ -121,6 +128,11 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
|||
copyFile = argv[i].c_str();
|
||||
doing = DoingNone;
|
||||
}
|
||||
else if(doing == DoingCopyFileError)
|
||||
{
|
||||
copyFileError = argv[i].c_str();
|
||||
doing = DoingNone;
|
||||
}
|
||||
else if(doing == DoingSources)
|
||||
{
|
||||
sources.push_back(argv[i]);
|
||||
|
@ -149,6 +161,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if(didCopyFileError && copyFileError.empty())
|
||||
{
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
|
||||
"COPY_FILE_ERROR must be followed by a variable name");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(didCopyFileError && !didCopyFile)
|
||||
{
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
|
||||
"COPY_FILE_ERROR may be used only with COPY_FILE");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(didOutputVariable && outputVariable.empty())
|
||||
{
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
|
||||
|
@ -444,6 +470,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
|||
|
||||
if (this->SrcFileSignature)
|
||||
{
|
||||
std::string copyFileErrorMessage;
|
||||
this->FindOutputFile(targetName);
|
||||
|
||||
if ((res==0) && (copyFile.size()))
|
||||
|
@ -461,9 +488,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
|
|||
{
|
||||
emsg << this->FindErrorMessage.c_str();
|
||||
}
|
||||
if(copyFileError.empty())
|
||||
{
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, emsg.str());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
copyFileErrorMessage = emsg.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!copyFileError.empty())
|
||||
{
|
||||
this->Makefile->AddDefinition(copyFileError.c_str(),
|
||||
copyFileErrorMessage.c_str());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
|
|
@ -69,14 +69,14 @@ public:
|
|||
" [COMPILE_DEFINITIONS flags...]\n"
|
||||
" [LINK_LIBRARIES libs...]\n"
|
||||
" [OUTPUT_VARIABLE <var>]\n"
|
||||
" [COPY_FILE <fileName>])\n"
|
||||
" [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]])\n"
|
||||
"Try building an executable from one or more source files. "
|
||||
"In this form the user need only supply one or more source files "
|
||||
"that include a definition for 'main'. "
|
||||
"CMake will create a CMakeLists.txt file to build the source(s) "
|
||||
"as an executable. "
|
||||
"Specify COPY_FILE to get a copy of the linked executable at the "
|
||||
"given fileName."
|
||||
"given fileName and optionally COPY_FILE_ERROR to capture any error."
|
||||
"\n"
|
||||
"In this version all files in bindir/CMakeFiles/CMakeTmp "
|
||||
"will be cleaned automatically. For debugging, --debug-trycompile can "
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at CopyFileErrorNoCopyFile.cmake:1 \(try_compile\):
|
||||
COPY_FILE_ERROR may be used only with COPY_FILE
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
|||
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||
COPY_FILE_ERROR _copied)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error at NoCopyFileError.cmake:1 \(try_compile\):
|
||||
COPY_FILE_ERROR must be followed by a variable name
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,2 @@
|
|||
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
|
||||
COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/copied.bin COPY_FILE_ERROR)
|
|
@ -1,10 +1,12 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(CopyFileErrorNoCopyFile)
|
||||
run_cmake(NoArgs)
|
||||
run_cmake(OneArg)
|
||||
run_cmake(TwoArgs)
|
||||
run_cmake(NoCopyFile)
|
||||
run_cmake(NoCopyFile2)
|
||||
run_cmake(NoCopyFileError)
|
||||
run_cmake(NoOutputVariable)
|
||||
run_cmake(NoOutputVariable2)
|
||||
run_cmake(NoSources)
|
||||
|
|
|
@ -44,6 +44,23 @@ else()
|
|||
file(REMOVE "${TryCompile_BINARY_DIR}/CopyOfPass")
|
||||
endif()
|
||||
|
||||
# try to compile a file that should compile
|
||||
# also check that COPY_FILE_ERROR works
|
||||
file(WRITE ${TryCompile_BINARY_DIR}/invalid "")
|
||||
try_compile(SHOULD_PASS
|
||||
${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
|
||||
${TryCompile_SOURCE_DIR}/pass.c
|
||||
OUTPUT_VARIABLE TRY_OUT
|
||||
COPY_FILE ${TryCompile_BINARY_DIR}/invalid/path
|
||||
COPY_FILE_ERROR _captured
|
||||
)
|
||||
if(NOT SHOULD_PASS)
|
||||
message(SEND_ERROR "should pass failed ${TRY_OUT}")
|
||||
endif()
|
||||
if(NOT _captured MATCHES "Cannot copy output executable.*/invalid/path")
|
||||
message(SEND_ERROR "COPY_FILE_ERROR did not capture expected message")
|
||||
endif()
|
||||
|
||||
# try to compile a file that should not compile
|
||||
try_compile(SHOULD_FAIL
|
||||
${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
|
||||
|
|
Loading…
Reference in New Issue