Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
CMake
CMake
Commits
1a165dc6
Commit
1a165dc6
authored
Jun 03, 2005
by
Andy Cedilnik
Browse files
ENH: Move the build-and-test code to a handler
parent
6fe633e1
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Source/CMakeLists.txt
View file @
1a165dc6
...
...
@@ -156,6 +156,7 @@ INCLUDE_DIRECTORIES(
SET
(
CMTEST_SRCS cmCTest.cxx
CTest/cmCTestBuildCommand.cxx
CTest/cmCTestBuildHandler.cxx
CTest/cmCTestBuildAndTestHandler.cxx
CTest/cmCTestConfigureCommand.cxx
CTest/cmCTestConfigureHandler.cxx
CTest/cmCTestCoverageHandler.cxx
...
...
Source/CTest/cmCTestBuildAndTestHandler.cxx
0 → 100644
View file @
1a165dc6
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include
"cmCTestBuildAndTestHandler.h"
#include
"cmSystemTools.h"
#include
"cmCTest.h"
#include
"cmake.h"
#include
"cmGlobalGenerator.h"
#include
<cmsys/Process.h>
//----------------------------------------------------------------------
cmCTestBuildAndTestHandler
::
cmCTestBuildAndTestHandler
()
{
m_BuildTwoConfig
=
false
;
m_BuildNoClean
=
false
;
m_BuildNoCMake
=
false
;
}
//----------------------------------------------------------------------
const
char
*
cmCTestBuildAndTestHandler
::
GetOutput
()
{
return
m_Output
.
c_str
();
}
//----------------------------------------------------------------------
int
cmCTestBuildAndTestHandler
::
ProcessHandler
()
{
m_Output
=
""
;
std
::
string
output
;
cmSystemTools
::
ResetErrorOccuredFlag
();
cmListFileCache
::
ClearCache
();
int
retv
=
this
->
RunCMakeAndTest
(
&
m_Output
);
cmSystemTools
::
ResetErrorOccuredFlag
();
cmListFileCache
::
ClearCache
();
return
retv
;
}
//----------------------------------------------------------------------
int
cmCTestBuildAndTestHandler
::
RunCMake
(
std
::
string
*
outstring
,
cmOStringStream
&
out
,
std
::
string
&
cmakeOutString
,
std
::
string
&
cwd
,
cmake
*
cm
)
{
unsigned
int
k
;
std
::
vector
<
std
::
string
>
args
;
args
.
push_back
(
m_CTest
->
GetCMakeExecutable
());
args
.
push_back
(
m_SourceDir
);
if
(
m_BuildGenerator
.
size
())
{
std
::
string
generator
=
"-G"
;
generator
+=
m_BuildGenerator
;
args
.
push_back
(
generator
);
}
if
(
m_CTest
->
GetConfigType
().
size
()
>
0
)
{
std
::
string
btype
=
"-DBUILD_TYPE:STRING="
+
m_CTest
->
GetConfigType
();
args
.
push_back
(
btype
);
}
for
(
k
=
0
;
k
<
m_BuildOptions
.
size
();
++
k
)
{
args
.
push_back
(
m_BuildOptions
[
k
]);
}
if
(
cm
->
Run
(
args
)
!=
0
)
{
out
<<
"Error: cmake execution failed
\n
"
;
out
<<
cmakeOutString
<<
"
\n
"
;
// return to the original directory
cmSystemTools
::
ChangeDirectory
(
cwd
.
c_str
());
if
(
outstring
)
{
*
outstring
=
out
.
str
();
}
else
{
cmCTestLog
(
m_CTest
,
ERROR_MESSAGE
,
out
.
str
()
<<
std
::
endl
);
}
return
1
;
}
// do another config?
if
(
m_BuildTwoConfig
)
{
if
(
cm
->
Run
(
args
)
!=
0
)
{
out
<<
"Error: cmake execution failed
\n
"
;
out
<<
cmakeOutString
<<
"
\n
"
;
// return to the original directory
cmSystemTools
::
ChangeDirectory
(
cwd
.
c_str
());
if
(
outstring
)
{
*
outstring
=
out
.
str
();
}
else
{
cmCTestLog
(
m_CTest
,
ERROR_MESSAGE
,
out
.
str
()
<<
std
::
endl
);
}
return
1
;
}
}
return
0
;
}
//----------------------------------------------------------------------
void
CMakeMessageCallback
(
const
char
*
m
,
const
char
*
,
bool
&
,
void
*
s
)
{
std
::
string
*
out
=
(
std
::
string
*
)
s
;
*
out
+=
m
;
*
out
+=
"
\n
"
;
}
//----------------------------------------------------------------------
void
CMakeStdoutCallback
(
const
char
*
m
,
int
len
,
void
*
s
)
{
std
::
string
*
out
=
(
std
::
string
*
)
s
;
out
->
append
(
m
,
len
);
}
//----------------------------------------------------------------------
int
cmCTestBuildAndTestHandler
::
RunCMakeAndTest
(
std
::
string
*
outstring
)
{
unsigned
int
k
;
std
::
string
cmakeOutString
;
cmSystemTools
::
SetErrorCallback
(
CMakeMessageCallback
,
&
cmakeOutString
);
cmSystemTools
::
SetStdoutCallback
(
CMakeStdoutCallback
,
&
cmakeOutString
);
cmOStringStream
out
;
// What is this? double timeout = m_CTest->GetTimeOut();
int
retVal
=
0
;
// if the generator and make program are not specified then it is an error
if
(
!
m_BuildGenerator
.
size
()
||
!
m_BuildMakeProgram
.
size
())
{
if
(
outstring
)
{
*
outstring
=
"--build-and-test requires that both the generator and makeprogram "
"be provided using the --build-generator and --build-makeprogram "
"command line options. "
;
}
return
1
;
}
// make sure the binary dir is there
std
::
string
cwd
=
cmSystemTools
::
GetCurrentWorkingDirectory
();
out
<<
"Internal cmake changing into directory: "
<<
m_BinaryDir
<<
"
\n
"
;
if
(
!
cmSystemTools
::
FileIsDirectory
(
m_BinaryDir
.
c_str
()))
{
cmSystemTools
::
MakeDirectory
(
m_BinaryDir
.
c_str
());
}
cmSystemTools
::
ChangeDirectory
(
m_BinaryDir
.
c_str
());
// should we cmake?
cmake
cm
;
cm
.
SetGlobalGenerator
(
cm
.
CreateGlobalGenerator
(
m_BuildGenerator
.
c_str
()));
if
(
!
m_BuildNoCMake
)
{
// do the cmake step
if
(
this
->
RunCMake
(
outstring
,
out
,
cmakeOutString
,
cwd
,
&
cm
))
{
return
1
;
}
}
// do the build
std
::
string
output
;
retVal
=
cm
.
GetGlobalGenerator
()
->
Build
(
m_SourceDir
.
c_str
(),
m_BinaryDir
.
c_str
(),
m_BuildProject
.
c_str
(),
m_BuildTarget
.
c_str
(),
&
output
,
m_BuildMakeProgram
.
c_str
(),
m_CTest
->
GetConfigType
().
c_str
(),
!
m_BuildNoClean
);
out
<<
output
;
if
(
outstring
)
{
*
outstring
=
out
.
str
();
}
// if the build failed then return
if
(
retVal
)
{
return
1
;
}
// if not test was specified then we are done
if
(
!
m_TestCommand
.
size
())
{
return
0
;
}
// now run the compiled test if we can find it
std
::
vector
<
std
::
string
>
attempted
;
std
::
vector
<
std
::
string
>
failed
;
std
::
string
tempPath
;
std
::
string
filepath
=
cmSystemTools
::
GetFilenamePath
(
m_TestCommand
);
std
::
string
filename
=
cmSystemTools
::
GetFilenameName
(
m_TestCommand
);
// if full path specified then search that first
if
(
filepath
.
size
())
{
tempPath
=
filepath
;
tempPath
+=
"/"
;
tempPath
+=
filename
;
attempted
.
push_back
(
tempPath
);
if
(
m_CTest
->
GetConfigType
().
size
())
{
tempPath
=
filepath
;
tempPath
+=
"/"
;
tempPath
+=
m_CTest
->
GetConfigType
();
tempPath
+=
"/"
;
tempPath
+=
filename
;
attempted
.
push_back
(
tempPath
);
}
}
// otherwise search local dirs
else
{
attempted
.
push_back
(
filename
);
if
(
m_CTest
->
GetConfigType
().
size
())
{
tempPath
=
m_CTest
->
GetConfigType
();
tempPath
+=
"/"
;
tempPath
+=
filename
;
attempted
.
push_back
(
tempPath
);
}
}
// if m_ExecutableDirectory is set try that as well
if
(
m_ExecutableDirectory
.
size
())
{
tempPath
=
m_ExecutableDirectory
;
tempPath
+=
"/"
;
tempPath
+=
m_TestCommand
;
attempted
.
push_back
(
tempPath
);
if
(
m_CTest
->
GetConfigType
().
size
())
{
tempPath
=
m_ExecutableDirectory
;
tempPath
+=
"/"
;
tempPath
+=
m_CTest
->
GetConfigType
();
tempPath
+=
"/"
;
tempPath
+=
filename
;
attempted
.
push_back
(
tempPath
);
}
}
// store the final location in fullPath
std
::
string
fullPath
;
// now look in the paths we specified above
for
(
unsigned
int
ai
=
0
;
ai
<
attempted
.
size
()
&&
fullPath
.
size
()
==
0
;
++
ai
)
{
// first check without exe extension
if
(
cmSystemTools
::
FileExists
(
attempted
[
ai
].
c_str
())
&&
!
cmSystemTools
::
FileIsDirectory
(
attempted
[
ai
].
c_str
()))
{
fullPath
=
cmSystemTools
::
CollapseFullPath
(
attempted
[
ai
].
c_str
());
}
// then try with the exe extension
else
{
failed
.
push_back
(
attempted
[
ai
].
c_str
());
tempPath
=
attempted
[
ai
];
tempPath
+=
cmSystemTools
::
GetExecutableExtension
();
if
(
cmSystemTools
::
FileExists
(
tempPath
.
c_str
())
&&
!
cmSystemTools
::
FileIsDirectory
(
tempPath
.
c_str
()))
{
fullPath
=
cmSystemTools
::
CollapseFullPath
(
tempPath
.
c_str
());
}
else
{
failed
.
push_back
(
tempPath
.
c_str
());
}
}
}
if
(
!
cmSystemTools
::
FileExists
(
fullPath
.
c_str
()))
{
out
<<
"Could not find path to executable, perhaps it was not built: "
<<
m_TestCommand
<<
"
\n
"
;
out
<<
"tried to find it in these places:
\n
"
;
out
<<
fullPath
.
c_str
()
<<
"
\n
"
;
for
(
unsigned
int
i
=
0
;
i
<
failed
.
size
();
++
i
)
{
out
<<
failed
[
i
]
<<
"
\n
"
;
}
if
(
outstring
)
{
*
outstring
=
out
.
str
();
}
else
{
cmCTestLog
(
m_CTest
,
ERROR_MESSAGE
,
out
.
str
());
}
// return to the original directory
cmSystemTools
::
ChangeDirectory
(
cwd
.
c_str
());
return
1
;
}
std
::
vector
<
const
char
*>
testCommand
;
testCommand
.
push_back
(
fullPath
.
c_str
());
for
(
k
=
0
;
k
<
m_TestCommandArgs
.
size
();
++
k
)
{
testCommand
.
push_back
(
m_TestCommandArgs
[
k
].
c_str
());
}
testCommand
.
push_back
(
0
);
std
::
string
outs
;
int
retval
=
0
;
// run the test from the m_BuildRunDir if set
if
(
m_BuildRunDir
.
size
())
{
out
<<
"Run test in directory: "
<<
m_BuildRunDir
<<
"
\n
"
;
cmSystemTools
::
ChangeDirectory
(
m_BuildRunDir
.
c_str
());
}
out
<<
"Running test executable: "
<<
fullPath
<<
" "
;
for
(
k
=
0
;
k
<
m_TestCommandArgs
.
size
();
++
k
)
{
out
<<
m_TestCommandArgs
[
k
]
<<
" "
;
}
out
<<
"
\n
"
;
// What is this? m_TimeOut = timeout;
int
runTestRes
=
m_CTest
->
RunTest
(
testCommand
,
&
outs
,
&
retval
,
0
);
if
(
runTestRes
!=
cmsysProcess_State_Exited
||
retval
!=
0
)
{
out
<<
"Failed to run test command: "
<<
testCommand
[
0
]
<<
"
\n
"
;
retval
=
1
;
}
out
<<
outs
<<
"
\n
"
;
if
(
outstring
)
{
*
outstring
=
out
.
str
();
}
else
{
cmCTestLog
(
m_CTest
,
OUTPUT
,
out
.
str
()
<<
std
::
endl
);
}
return
retval
;
}
//----------------------------------------------------------------------
int
cmCTestBuildAndTestHandler
::
ProcessCommandLineArguments
(
const
std
::
string
&
currentArg
,
size_t
&
idx
,
const
std
::
vector
<
std
::
string
>&
allArgs
)
{
// --build-and-test options
if
(
currentArg
.
find
(
"--build-and-test"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
if
(
idx
+
2
<
allArgs
.
size
())
{
idx
++
;
m_SourceDir
=
allArgs
[
idx
];
idx
++
;
m_BinaryDir
=
allArgs
[
idx
];
// dir must exist before CollapseFullPath is called
cmSystemTools
::
MakeDirectory
(
m_BinaryDir
.
c_str
());
m_BinaryDir
=
cmSystemTools
::
CollapseFullPath
(
m_BinaryDir
.
c_str
());
m_SourceDir
=
cmSystemTools
::
CollapseFullPath
(
m_SourceDir
.
c_str
());
}
else
{
cmCTestLog
(
m_CTest
,
ERROR_MESSAGE
,
"--build-and-test must have source and binary dir"
<<
std
::
endl
);
return
0
;
}
}
if
(
currentArg
.
find
(
"--build-target"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
idx
++
;
m_BuildTarget
=
allArgs
[
idx
];
}
if
(
currentArg
.
find
(
"--build-nocmake"
,
0
)
==
0
)
{
m_BuildNoCMake
=
true
;
}
if
(
currentArg
.
find
(
"--build-run-dir"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
idx
++
;
m_BuildRunDir
=
allArgs
[
idx
];
}
if
(
currentArg
.
find
(
"--build-two-config"
,
0
)
==
0
)
{
m_BuildTwoConfig
=
true
;
}
if
(
currentArg
.
find
(
"--build-exe-dir"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
idx
++
;
m_ExecutableDirectory
=
allArgs
[
idx
];
}
if
(
currentArg
.
find
(
"--build-generator"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
idx
++
;
m_BuildGenerator
=
allArgs
[
idx
];
}
if
(
currentArg
.
find
(
"--build-project"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
idx
++
;
m_BuildProject
=
allArgs
[
idx
];
}
if
(
currentArg
.
find
(
"--build-makeprogram"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
idx
++
;
m_BuildMakeProgram
=
allArgs
[
idx
];
}
if
(
currentArg
.
find
(
"--build-noclean"
,
0
)
==
0
)
{
m_BuildNoClean
=
true
;
}
if
(
currentArg
.
find
(
"--build-options"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
++
idx
;
bool
done
=
false
;
while
(
idx
<
allArgs
.
size
()
&&
!
done
)
{
m_BuildOptions
.
push_back
(
allArgs
[
idx
]);
if
(
idx
+
1
<
allArgs
.
size
()
&&
(
allArgs
[
idx
+
1
]
==
"--build-target"
||
allArgs
[
idx
+
1
]
==
"--test-command"
))
{
done
=
true
;
}
else
{
++
idx
;
}
}
}
if
(
currentArg
.
find
(
"--test-command"
,
0
)
==
0
&&
idx
<
allArgs
.
size
()
-
1
)
{
++
idx
;
m_TestCommand
=
allArgs
[
idx
];
while
(
idx
+
1
<
allArgs
.
size
())
{
++
idx
;
m_TestCommandArgs
.
push_back
(
allArgs
[
idx
]);
}
}
return
1
;
}
Source/CTest/cmCTestBuildAndTestHandler.h
0 → 100644
View file @
1a165dc6
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmCTestBuildAndTestHandler_h
#define cmCTestBuildAndTestHandler_h
#include
"cmCTestGenericHandler.h"
#include
"cmListFileCache.h"
class
cmake
;
/** \class cmCTestBuildAndTestHandler
* \brief A class that handles ctest -S invocations
*
*/
class
cmCTestBuildAndTestHandler
:
public
cmCTestGenericHandler
{
public:
/*
* The main entry point for this class
*/
int
ProcessHandler
();
//! Set all the build and test arguments
virtual
int
ProcessCommandLineArguments
(
const
std
::
string
&
currentArg
,
size_t
&
idx
,
const
std
::
vector
<
std
::
string
>&
allArgs
);
/*
* Get the output variable
*/
const
char
*
GetOutput
();
cmCTestBuildAndTestHandler
();
protected:
///! Run CMake and build a test and then run it as a single test.
int
RunCMakeAndTest
(
std
::
string
*
output
);
int
RunCMake
(
std
::
string
*
outstring
,
cmOStringStream
&
out
,
std
::
string
&
cmakeOutString
,
std
::
string
&
cwd
,
cmake
*
cm
);
cmStdString
m_Output
;
std
::
string
m_BuildGenerator
;
std
::
vector
<
std
::
string
>
m_BuildOptions
;
bool
m_BuildTwoConfig
;
std
::
string
m_BuildMakeProgram
;
std
::
string
m_SourceDir
;
std
::
string
m_BinaryDir
;
std
::
string
m_BuildProject
;
std
::
string
m_TestCommand
;
bool
m_BuildNoClean
;
std
::
string
m_BuildRunDir
;
std
::
string
m_ExecutableDirectory
;
std
::
vector
<
std
::
string
>
m_TestCommandArgs
;
std
::
string
m_BuildTarget
;
bool
m_BuildNoCMake
;
};
#endif
Source/cmCTest.cxx
View file @
1a165dc6
This diff is collapsed.
Click to expand it.
Source/cmCTest.h
View file @
1a165dc6
...
...
@@ -88,6 +88,7 @@ public:
///! what is the configuraiton type, e.g. Debug, Release etc.
std
::
string
GetConfigType
();
double
GetTimeOut
()
{
return
m_TimeOut
;
}
/**
* Check if CTest file exists
...
...
@@ -289,22 +290,10 @@ private:
int
m_CompatibilityMode
;
// information for the --build-and-test options
std
::
string
m_ExecutableDirectory
;
std
::
string
m_CMakeSelf
;
std
::
string
m_CTestSelf
;
std
::
string
m_SourceDir
;
std
::
string
m_BinaryDir
;
std
::
string
m_BuildRunDir
;
std
::
string
m_BuildGenerator
;
std
::
string
m_BuildMakeProgram
;
std
::
string
m_BuildProject
;
std
::
string
m_BuildTarget
;
std
::
vector
<
std
::
string
>
m_BuildOptions
;
std
::
string
m_TestCommand
;
std
::
vector
<
std
::
string
>
m_TestCommandArgs
;
bool
m_BuildTwoConfig
;
bool
m_BuildNoClean
;
bool
m_BuildNoCMake
;
std
::
string
m_NotesFiles
;
...
...
@@ -325,12 +314,6 @@ private:
//! Create not from files.
int
GenerateCTestNotesOutput
(
std
::
ostream
&
os
,
const
tm_VectorOfStrings
&
files
);
///! Run CMake and build a test and then run it as a single test.
int
RunCMakeAndTest
(
std
::
string
*
output
);
int
RunCMake
(
std
::
string
*
outstring
,
cmOStringStream
&
out
,
std
::
string
&
cmakeOutString
,
std
::
string
&
cwd
,
cmake
*
cm
);
///! Find the running cmake
void
FindRunningCMake
(
const
char
*
arg0
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment