BUG: 4244, add a --build option to cmake that can build projects configured by CMake
This commit is contained in:
parent
e099dccf4b
commit
1777bb502a
|
@ -1117,7 +1117,9 @@ int cmGlobalGenerator::Build(
|
|||
const char *makeCommandCSTR,
|
||||
const char *config,
|
||||
bool clean, bool fast,
|
||||
double timeout)
|
||||
double timeout,
|
||||
bool verbose,
|
||||
const char* extraOptions)
|
||||
{
|
||||
/**
|
||||
* Run an executable command and put the stdout in output.
|
||||
|
@ -1155,7 +1157,7 @@ int cmGlobalGenerator::Build(
|
|||
}
|
||||
|
||||
if (!cmSystemTools::RunSingleCommand(cleanCommand.c_str(), outputPtr,
|
||||
&retVal, 0, false, timeout))
|
||||
&retVal, 0, verbose, timeout))
|
||||
{
|
||||
cmSystemTools::SetRunCommandHideConsole(hideconsole);
|
||||
cmSystemTools::Error("Generator: execution of make clean failed.");
|
||||
|
@ -1178,7 +1180,8 @@ int cmGlobalGenerator::Build(
|
|||
// now build
|
||||
std::string makeCommand =
|
||||
this->GenerateBuildCommand(makeCommandCSTR, projectName,
|
||||
0, target, config, false, fast);
|
||||
extraOptions, target,
|
||||
config, false, fast);
|
||||
if(output)
|
||||
{
|
||||
*output += "\nRun Build Command:";
|
||||
|
@ -1187,7 +1190,7 @@ int cmGlobalGenerator::Build(
|
|||
}
|
||||
|
||||
if (!cmSystemTools::RunSingleCommand(makeCommand.c_str(), outputPtr,
|
||||
&retVal, 0, false, timeout))
|
||||
&retVal, 0, verbose, timeout))
|
||||
{
|
||||
cmSystemTools::SetRunCommandHideConsole(hideconsole);
|
||||
cmSystemTools::Error
|
||||
|
|
|
@ -105,13 +105,15 @@ public:
|
|||
std::string *output,
|
||||
const char *makeProgram, const char *config,
|
||||
bool clean, bool fast,
|
||||
double timeout);
|
||||
virtual std::string GenerateBuildCommand
|
||||
(const char* makeProgram,
|
||||
const char *projectName, const char* additionalOptions,
|
||||
const char *targetName,
|
||||
const char* config, bool ignoreErrors, bool fast);
|
||||
|
||||
double timeout, bool verbose=false,
|
||||
const char* extraOptions = 0);
|
||||
|
||||
virtual std::string GenerateBuildCommand(
|
||||
const char* makeProgram,
|
||||
const char *projectName, const char* additionalOptions,
|
||||
const char *targetName,
|
||||
const char* config, bool ignoreErrors, bool fast);
|
||||
|
||||
|
||||
///! Set the CMake instance
|
||||
void SetCMakeInstance(cmake *cm);
|
||||
|
|
|
@ -57,6 +57,10 @@ bool cmProjectCommand
|
|||
if(!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME"))
|
||||
{
|
||||
this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str());
|
||||
this->Makefile->AddCacheDefinition
|
||||
("CMAKE_PROJECT_NAME",
|
||||
args[0].c_str(),
|
||||
"Value Computed by CMake", cmCacheManager::STATIC);
|
||||
}
|
||||
|
||||
std::vector<std::string> languages;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
# include <cmsys/Terminal.h>
|
||||
#endif
|
||||
|
||||
#include <cmsys/CommandLineArguments.hxx>
|
||||
#include <cmsys/Directory.hxx>
|
||||
#include <cmsys/Process.h>
|
||||
#include <cmsys/Glob.hxx>
|
||||
|
@ -947,7 +948,8 @@ void CMakeCommandUsage(const char* program)
|
|||
errorStream
|
||||
<< "cmake bootstrap\n";
|
||||
#endif
|
||||
|
||||
// If you add new commands, change here,
|
||||
// and in cmakemain.cxx in the options table
|
||||
errorStream
|
||||
<< "Usage: " << program << " -E [command] [arguments ...]\n"
|
||||
<< "Available commands: \n"
|
||||
|
@ -973,6 +975,7 @@ void CMakeCommandUsage(const char* program)
|
|||
<< " time command [args] ... - run command and return elapsed time\n"
|
||||
<< " touch file - touch a file.\n"
|
||||
<< " touch_nocreate file - touch a file but do not create it.\n"
|
||||
<< " build build_dir - build the project in build_dir.\n"
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
<< " write_regv key value - write registry value\n"
|
||||
<< " delete_regv key - delete registry value\n"
|
||||
|
@ -987,6 +990,7 @@ void CMakeCommandUsage(const char* program)
|
|||
|
||||
int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
|
||||
{
|
||||
// IF YOU ADD A NEW COMMAND, DOCUMENT IT ABOVE and in cmakemain.cxx
|
||||
if (args.size() > 1)
|
||||
{
|
||||
// Copy file
|
||||
|
@ -1188,7 +1192,6 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
|
|||
<< "\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Command to calculate the md5sum of a file
|
||||
else if (args[1] == "md5sum" && args.size() >= 3)
|
||||
{
|
||||
|
@ -4329,3 +4332,86 @@ std::vector<std::string> const& cmake::GetDebugConfigs()
|
|||
}
|
||||
return this->DebugConfigs;
|
||||
}
|
||||
|
||||
|
||||
int cmake::Build(const std::string& dir,
|
||||
const std::string& target,
|
||||
const std::string& config,
|
||||
const std::string& extraBuildOptions,
|
||||
bool clean)
|
||||
{
|
||||
if(!cmSystemTools::FileIsDirectory(dir.c_str()))
|
||||
{
|
||||
std::cerr << "Error: " << dir << " is not a directory\n";
|
||||
return 1;
|
||||
}
|
||||
std::string cachePath = dir;
|
||||
cmSystemTools::ConvertToUnixSlashes(cachePath);
|
||||
cmCacheManager* cachem = this->GetCacheManager();
|
||||
cmCacheManager::CacheIterator it = cachem->NewIterator();
|
||||
if(!cachem->LoadCache(cachePath.c_str()))
|
||||
{
|
||||
std::cerr << "Error: could not load cache\n";
|
||||
return 1;
|
||||
}
|
||||
if(!it.Find("CMAKE_GENERATOR"))
|
||||
{
|
||||
std::cerr << "Error: could find generator in Cache\n";
|
||||
return 1;
|
||||
}
|
||||
cmGlobalGenerator* gen =
|
||||
this->CreateGlobalGenerator(it.GetValue());
|
||||
std::string output;
|
||||
std::string projName;
|
||||
std::string makeProgram;
|
||||
if(!it.Find("CMAKE_PROJECT_NAME"))
|
||||
{
|
||||
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
|
||||
return 1;
|
||||
}
|
||||
projName = it.GetValue();
|
||||
if(!it.Find("CMAKE_MAKE_PROGRAM"))
|
||||
{
|
||||
std::cerr << "Error: could not find CMAKE_MAKE_PROGRAM in Cache\n";
|
||||
return 1;
|
||||
}
|
||||
makeProgram = it.GetValue();
|
||||
return gen->Build(0, dir.c_str(),
|
||||
projName.c_str(), target.c_str(),
|
||||
&output,
|
||||
makeProgram.c_str(),
|
||||
config.c_str(), clean, false, 0, true);
|
||||
}
|
||||
|
||||
int cmake::DoBuild(int ac, char* av[])
|
||||
{
|
||||
std::string target;
|
||||
std::string config = "Debug";
|
||||
std::string extraBuildOptions;
|
||||
std::string dir;
|
||||
bool clean = false;
|
||||
cmsys::CommandLineArguments arg;
|
||||
arg.Initialize(ac, av);
|
||||
typedef cmsys::CommandLineArguments argT;
|
||||
arg.AddArgument("--build", argT::SPACE_ARGUMENT, &dir,
|
||||
"Build a configured cmake project --build dir.");
|
||||
arg.AddArgument("--target", argT::SPACE_ARGUMENT, &target,
|
||||
"Specifiy the target to build,"
|
||||
" if missing, all targets are built.");
|
||||
arg.AddArgument("--config", argT::SPACE_ARGUMENT, &config,
|
||||
"Specify configuration to build"
|
||||
" if missing Debug is built.");
|
||||
arg.AddArgument("--extra-options", argT::SPACE_ARGUMENT, &extraBuildOptions,
|
||||
"Specify extra options to pass to build program,"
|
||||
" for example with gmake -jN.");
|
||||
arg.AddArgument("--clean", argT::NO_ARGUMENT, &clean,
|
||||
"Clean before building.");
|
||||
if ( !arg.Parse() )
|
||||
{
|
||||
std::cerr << "Problem parsing --build arguments:\n";
|
||||
std::cerr << arg.GetHelp() << "\n";
|
||||
return 1;
|
||||
}
|
||||
cmake cm;
|
||||
return cm.Build(dir, target, config, extraBuildOptions, clean);
|
||||
}
|
||||
|
|
|
@ -356,7 +356,14 @@ class cmake
|
|||
/** Display a message to the user. */
|
||||
void IssueMessage(cmake::MessageType t, std::string const& text,
|
||||
cmListFileBacktrace const& backtrace);
|
||||
// * run the --build option
|
||||
static int DoBuild(int ac, char* av[]);
|
||||
protected:
|
||||
int Build(const std::string& dir,
|
||||
const std::string& target,
|
||||
const std::string& config,
|
||||
const std::string& extraBuildOptions,
|
||||
bool clean);
|
||||
void InitializeProperties();
|
||||
int HandleDeleteCacheVariables(const char* var);
|
||||
cmPropertyMap Properties;
|
||||
|
|
|
@ -85,6 +85,11 @@ static const char * cmDocumentationOptions[][3] =
|
|||
"variables being created. If A is specified, then it will display also "
|
||||
"advanced variables. If H is specified, it will also display help for "
|
||||
"each variable."},
|
||||
{"--build dir", "Build a configured cmake tree found in dir.",
|
||||
"This option will use the native build tool from the command line to"
|
||||
" build the project. Other options that can be specified with this one"
|
||||
" are --target, --config, --extra-options, and --clean. For complete "
|
||||
"help run --build with no options."},
|
||||
{"-N", "View mode only.",
|
||||
"Only load the cache. Do not actually run configure and generate steps."},
|
||||
{"-P <file>", "Process script mode.",
|
||||
|
@ -407,6 +412,7 @@ int do_cmake(int ac, char** av)
|
|||
bool list_help = false;
|
||||
bool view_only = false;
|
||||
bool script_mode = false;
|
||||
bool build = false;
|
||||
std::vector<std::string> args;
|
||||
for(int i =0; i < ac; ++i)
|
||||
{
|
||||
|
@ -414,6 +420,10 @@ int do_cmake(int ac, char** av)
|
|||
{
|
||||
wiz = true;
|
||||
}
|
||||
else if(!command && strcmp(av[i], "--build") == 0)
|
||||
{
|
||||
return cmake::DoBuild(ac, av);
|
||||
}
|
||||
else if(!command && strcmp(av[i], "--system-information") == 0)
|
||||
{
|
||||
sysinfo = true;
|
||||
|
@ -465,6 +475,11 @@ int do_cmake(int ac, char** av)
|
|||
args.push_back(av[i]);
|
||||
}
|
||||
}
|
||||
if(build)
|
||||
{
|
||||
int ret = cmake::DoBuild(ac, av);
|
||||
return ret;
|
||||
}
|
||||
if(command)
|
||||
{
|
||||
int ret = cmake::ExecuteCMakeCommand(args);
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
# create the binary directory
|
||||
make_directory("@CMAKE_BUILD_TEST_BINARY_DIR@")
|
||||
|
||||
# run cmake in the binary directory
|
||||
execute_process(COMMAND "@CMAKE_CMAKE_COMMAND@"
|
||||
"@CMAKE_BUILD_TEST_SOURCE_DIR@"
|
||||
"-G@CMAKE_TEST_GENERATOR@"
|
||||
WORKING_DIRECTORY "@CMAKE_BUILD_TEST_BINARY_DIR@"
|
||||
RESULT_VARIABLE RESULT)
|
||||
if(RESULT)
|
||||
message(FATAL_ERROR "Error running cmake command")
|
||||
endif(RESULT)
|
||||
|
||||
# Now use the --build option to build the project
|
||||
execute_process(COMMAND "@CMAKE_CMAKE_COMMAND@"
|
||||
--build "@CMAKE_BUILD_TEST_BINARY_DIR@" --config Debug
|
||||
RESULT_VARIABLE RESULT)
|
||||
if(RESULT)
|
||||
message(FATAL_ERROR "Error running cmake --build")
|
||||
endif(RESULT)
|
||||
|
||||
# check for configuration types
|
||||
set(CMAKE_CONFIGURATION_TYPES @CMAKE_CONFIGURATION_TYPES@)
|
||||
# run the executable out of the Debug directory if there
|
||||
# are configuration types
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
set(RUN_TEST "@CMAKE_BUILD_TEST_BINARY_DIR@/Debug/COnly")
|
||||
else(CMAKE_CONFIGURATION_TYPES)
|
||||
set(RUN_TEST "@CMAKE_BUILD_TEST_BINARY_DIR@/COnly")
|
||||
endif(CMAKE_CONFIGURATION_TYPES)
|
||||
# run the test results
|
||||
message("running [${RUN_TEST}]")
|
||||
execute_process(COMMAND "${RUN_TEST}" RESULT_VARIABLE RESULT)
|
||||
if(RESULT)
|
||||
message(FATAL_ERROR "Error running test COnly")
|
||||
endif(RESULT)
|
||||
|
||||
# build it again with clean and only COnly target
|
||||
execute_process(COMMAND "@CMAKE_CMAKE_COMMAND@"
|
||||
--build "@CMAKE_BUILD_TEST_BINARY_DIR@" --config Debug
|
||||
--clean --target COnly
|
||||
RESULT_VARIABLE RESULT)
|
||||
if(RESULT)
|
||||
message(FATAL_ERROR "Error running cmake --build")
|
||||
endif(RESULT)
|
||||
|
||||
# run it again after clean
|
||||
execute_process(COMMAND "${RUN_TEST}" RESULT_VARIABLE RESULT)
|
||||
if(RESULT)
|
||||
message(FATAL_ERROR "Error running test COnly after clean ")
|
||||
endif(RESULT)
|
|
@ -96,6 +96,12 @@ IF(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(ExportImport ExportImport)
|
||||
ADD_TEST_MACRO(Unset Unset)
|
||||
|
||||
SET(CMAKE_BUILD_TEST_SOURCE_DIR "${CMake_SOURCE_DIR}/Tests/COnly")
|
||||
SET(CMAKE_BUILD_TEST_BINARY_DIR "${CMake_BINARY_DIR}/Tests/CMakeBuildCOnly")
|
||||
CONFIGURE_FILE("${CMake_SOURCE_DIR}/Tests/CMakeBuildTest.cmake.in"
|
||||
"${CMake_BINARY_DIR}/Tests/CMakeBuildTest.cmake" @ONLY)
|
||||
ADD_TEST(CMakeBuildTest ${CMAKE_CMAKE_COMMAND} -P
|
||||
"${CMake_BINARY_DIR}/Tests/CMakeBuildTest.cmake")
|
||||
|
||||
# If we are running right now with a UnixMakefiles based generator,
|
||||
# build the "Simple" test with the ExtraGenerators, if available
|
||||
|
|
Loading…
Reference in New Issue