Merge topic 'refactor-try_compile-argument-processing'

d06db7e try_compile: Refactor argument processing
b680824 try_compile: Add test for bad call error cases
This commit is contained in:
Brad King 2013-06-03 09:57:39 -04:00 committed by CMake Topic Stage
commit bcc29c56a5
36 changed files with 197 additions and 139 deletions

View File

@ -23,150 +23,130 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
this->BinaryDirectory = argv[1].c_str(); this->BinaryDirectory = argv[1].c_str();
this->OutputFile = ""; this->OutputFile = "";
// which signature were we called with ? // which signature were we called with ?
this->SrcFileSignature = false; this->SrcFileSignature = true;
unsigned int i;
const char* sourceDirectory = argv[2].c_str(); const char* sourceDirectory = argv[2].c_str();
const char* projectName = 0; const char* projectName = 0;
const char* targetName = 0; const char* targetName = 0;
char targetNameBuf[64];
int extraArgs = 0;
// look for CMAKE_FLAGS and store them
std::vector<std::string> cmakeFlags; std::vector<std::string> cmakeFlags;
for (i = 3; i < argv.size(); ++i) std::vector<std::string> compileDefs;
{
if (argv[i] == "CMAKE_FLAGS")
{
// CMAKE_FLAGS is the first argument because we need an argv[0] that
// is not used, so it matches regular command line parsing which has
// the program name as arg 0
for (; i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
argv[i] != "OUTPUT_VARIABLE" &&
argv[i] != "LINK_LIBRARIES";
++i)
{
extraArgs++;
cmakeFlags.push_back(argv[i]);
}
break;
}
}
// look for OUTPUT_VARIABLE and store them
std::string outputVariable; std::string outputVariable;
for (i = 3; i < argv.size(); ++i) std::string copyFile;
{
if (argv[i] == "OUTPUT_VARIABLE")
{
if ( argv.size() <= (i+1) )
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"OUTPUT_VARIABLE specified but there is no variable");
return -1;
}
extraArgs += 2;
outputVariable = argv[i+1];
break;
}
}
// look for COMPILE_DEFINITIONS and store them
std::vector<std::string> compileFlags;
for (i = 3; i < argv.size(); ++i)
{
if (argv[i] == "COMPILE_DEFINITIONS")
{
extraArgs++;
for (i = i + 1; i < argv.size() && argv[i] != "CMAKE_FLAGS" &&
argv[i] != "OUTPUT_VARIABLE" &&
argv[i] != "LINK_LIBRARIES";
++i)
{
extraArgs++;
compileFlags.push_back(argv[i]);
}
break;
}
}
std::vector<cmTarget*> targets; std::vector<cmTarget*> targets;
std::string libsToLink = " "; std::string libsToLink = " ";
bool useOldLinkLibs = true; bool useOldLinkLibs = true;
for (i = 3; i < argv.size(); ++i) char targetNameBuf[64];
bool didOutputVariable = false;
bool didCopyFile = false;
enum Doing { DoingNone, DoingCMakeFlags, DoingCompileDefinitions,
DoingLinkLibraries, DoingOutputVariable, DoingCopyFile };
Doing doing = DoingNone;
for(size_t i=3; i < argv.size(); ++i)
{ {
if (argv[i] == "LINK_LIBRARIES") if(argv[i] == "CMAKE_FLAGS")
{ {
if ( argv.size() <= (i+1) ) doing = DoingCMakeFlags;
{ // CMAKE_FLAGS is the first argument because we need an argv[0] that
this->Makefile->IssueMessage(cmake::FATAL_ERROR, // is not used, so it matches regular command line parsing which has
"LINK_LIBRARIES specified but there is no content"); // the program name as arg 0
return -1; cmakeFlags.push_back(argv[i]);
} }
extraArgs++; else if(argv[i] == "COMPILE_DEFINITIONS")
++i; {
doing = DoingCompileDefinitions;
}
else if(argv[i] == "LINK_LIBRARIES")
{
doing = DoingLinkLibraries;
useOldLinkLibs = false; useOldLinkLibs = false;
for ( ; i < argv.size() && argv[i] != "CMAKE_FLAGS"
&& argv[i] != "COMPILE_DEFINITIONS" && argv[i] != "OUTPUT_VARIABLE";
++i)
{
extraArgs++;
libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" ";
cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str());
if (!tgt)
{
continue;
}
switch(tgt->GetType())
{
case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::UNKNOWN_LIBRARY:
break;
case cmTarget::EXECUTABLE:
if (tgt->IsExecutableWithExports())
{
break;
}
default:
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"Only libraries may be used as try_compile IMPORTED "
"LINK_LIBRARIES. Got " + std::string(tgt->GetName()) + " of "
"type " + tgt->GetTargetTypeName(tgt->GetType()) + ".");
return -1;
}
if (!tgt->IsImported())
{
continue;
}
targets.push_back(tgt);
}
break;
} }
} else if(argv[i] == "OUTPUT_VARIABLE")
// look for COPY_FILE
std::string copyFile;
for (i = 3; i < argv.size(); ++i)
{
if (argv[i] == "COPY_FILE")
{ {
if ( argv.size() <= (i+1) ) doing = DoingOutputVariable;
didOutputVariable = true;
}
else if(argv[i] == "COPY_FILE")
{
doing = DoingCopyFile;
didCopyFile = true;
}
else if(doing == DoingCMakeFlags)
{
cmakeFlags.push_back(argv[i]);
}
else if(doing == DoingCompileDefinitions)
{
compileDefs.push_back(argv[i]);
}
else if(doing == DoingLinkLibraries)
{
libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" ";
if(cmTarget *tgt = this->Makefile->FindTargetToUse(argv[i].c_str()))
{ {
this->Makefile->IssueMessage(cmake::FATAL_ERROR, switch(tgt->GetType())
"COPY_FILE specified but there is no variable"); {
return -1; case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::UNKNOWN_LIBRARY:
break;
case cmTarget::EXECUTABLE:
if (tgt->IsExecutableWithExports())
{
break;
}
default:
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"Only libraries may be used as try_compile IMPORTED "
"LINK_LIBRARIES. Got " + std::string(tgt->GetName()) + " of "
"type " + tgt->GetTargetTypeName(tgt->GetType()) + ".");
return -1;
}
if (tgt->IsImported())
{
targets.push_back(tgt);
}
} }
extraArgs += 2; }
copyFile = argv[i+1]; else if(doing == DoingOutputVariable)
break; {
outputVariable = argv[i].c_str();
doing = DoingNone;
}
else if(doing == DoingCopyFile)
{
copyFile = argv[i].c_str();
doing = DoingNone;
}
else if(i == 3)
{
this->SrcFileSignature = false;
projectName = argv[i].c_str();
}
else if(i == 4 && !this->SrcFileSignature)
{
targetName = argv[i].c_str();
}
else
{
cmOStringStream m;
m << "try_compile given unknown argument \"" << argv[i] << "\".";
this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, m.str());
} }
} }
// do we have a srcfile signature if(didCopyFile && copyFile.empty())
if (argv.size() - extraArgs == 3)
{ {
this->SrcFileSignature = true; this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"COPY_FILE must be followed by a file path");
return -1;
}
if(didOutputVariable && outputVariable.empty())
{
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"OUTPUT_VARIABLE must be followed by a variable name");
return -1;
} }
// compute the binary dir when TRY_COMPILE is called with a src file // compute the binary dir when TRY_COMPILE is called with a src file
@ -179,10 +159,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
else else
{ {
// only valid for srcfile signatures // only valid for srcfile signatures
if (compileFlags.size()) if (compileDefs.size())
{ {
this->Makefile->IssueMessage(cmake::FATAL_ERROR, this->Makefile->IssueMessage(cmake::FATAL_ERROR,
"COMPILE_FLAGS specified on a srcdir type TRY_COMPILE"); "COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE");
return -1; return -1;
} }
if (copyFile.size()) if (copyFile.size())
@ -297,12 +277,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n"); fprintf(fout, "SET(CMAKE_SUPPRESS_REGENERATION 1)\n");
fprintf(fout, "LINK_DIRECTORIES(${LINK_DIRECTORIES})\n"); fprintf(fout, "LINK_DIRECTORIES(${LINK_DIRECTORIES})\n");
// handle any compile flags we need to pass on // handle any compile flags we need to pass on
if (compileFlags.size()) if (compileDefs.size())
{ {
fprintf(fout, "ADD_DEFINITIONS( "); fprintf(fout, "ADD_DEFINITIONS( ");
for (i = 0; i < compileFlags.size(); ++i) for (size_t i = 0; i < compileDefs.size(); ++i)
{ {
fprintf(fout,"%s ",compileFlags[i].c_str()); fprintf(fout,"%s ",compileDefs[i].c_str());
} }
fprintf(fout, ")\n"); fprintf(fout, ")\n");
} }
@ -398,16 +378,6 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
} }
} }
// else the srcdir bindir project target signature
else
{
projectName = argv[3].c_str();
if (argv.size() - extraArgs == 5)
{
targetName = argv[4].c_str();
}
}
bool erroroc = cmSystemTools::GetErrorOccuredFlag(); bool erroroc = cmSystemTools::GetErrorOccuredFlag();
cmSystemTools::ResetErrorOccuredFlag(); cmSystemTools::ResetErrorOccuredFlag();

View File

@ -76,6 +76,7 @@ add_RunCMake_test(if)
add_RunCMake_test(include) add_RunCMake_test(include)
add_RunCMake_test(include_directories) add_RunCMake_test(include_directories)
add_RunCMake_test(list) add_RunCMake_test(list)
add_RunCMake_test(try_compile)
add_RunCMake_test(CMP0004) add_RunCMake_test(CMP0004)
find_package(Qt4 QUIET) find_package(Qt4 QUIET)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,5 @@
CMake Error at BadLinkLibraries.cmake:2 \(try_compile\):
Only libraries may be used as try_compile IMPORTED LINK_LIBRARIES. Got
not_a_library of type UTILITY.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,3 @@
add_custom_target(not_a_library)
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
LINK_LIBRARIES not_a_library)

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 2.8)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at NoArgs.cmake:1 \(try_compile\):
try_compile unknown error.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
try_compile()

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at NoCopyFile.cmake:1 \(try_compile\):
COPY_FILE must be followed by a file path
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,2 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
COPY_FILE)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at NoCopyFile2.cmake:1 \(try_compile\):
COPY_FILE must be followed by a file path
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,2 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
COPY_FILE CMAKE_FLAGS -DA=B)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at NoOutputVariable.cmake:1 \(try_compile\):
OUTPUT_VARIABLE must be followed by a variable name
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,2 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
OUTPUT_VARIABLE)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at NoOutputVariable2.cmake:1 \(try_compile\):
OUTPUT_VARIABLE must be followed by a variable name
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,2 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
OUTPUT_VARIABLE CMAKE_FLAGS -DA=B)

View File

@ -0,0 +1,4 @@
CMake Error at NonSourceCompileDefinitions.cmake:1 \(try_compile\):
COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,2 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/proj
TestProject COMPILE_DEFINITIONS DEF)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at NonSourceCopyFile.cmake:1 \(try_compile\):
COPY_FILE specified on a srcdir type TRY_COMPILE
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,2 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/proj
TestProject COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/result)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at OneArg.cmake:1 \(try_compile\):
try_compile unknown error.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
try_compile(RESULT)

View File

@ -0,0 +1,12 @@
include(RunCMake)
run_cmake(NoArgs)
run_cmake(OneArg)
run_cmake(TwoArgs)
run_cmake(NoCopyFile)
run_cmake(NoCopyFile2)
run_cmake(NoOutputVariable)
run_cmake(NoOutputVariable2)
run_cmake(BadLinkLibraries)
run_cmake(NonSourceCopyFile)
run_cmake(NonSourceCompileDefinitions)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,4 @@
CMake Error at TwoArgs.cmake:1 \(try_compile\):
try_compile unknown error.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1 @@
try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -0,0 +1,2 @@
cmake_minimum_required(VERSION 2.8.10)
project(TestProject NONE)

View File

@ -0,0 +1 @@
int main(void) { return 0; }