Merge topic 'UsingCMakeLikePkgConfig2'

59238dc Fix --find-package mode on Cygwin, where enable_language(RC) is called
98472e4 Require the current cmake version in --find-package mode
a6ccf3c Use $(CXXFLAGS) and $(LDFLAGS) in the --find-package test Makefile
4386918 Fix line length
7d69310 Only enable the test when using GNU make
3011149 Make the test harder by always having a space in the include dirs
ab57ff6 Make the --find-package test harder
626fc71 Much improved test, should now be executed on all UNIXes
ec6982d Disable any STATUS output in --find-package mode
e552ae7 Dont check for -isysroot and -mmacosx-version on OSX in --find-package mode
e589589 Rename helper macros print_compile_flags() to set_compile_flags_var()
aecfc1f Fix test on OpenBSD with BSD make
6bb4ca3 The makefile for the test was kindof wrong
fd15b5e Only run the test if we are using a makefile generator under UNIX
9fc87c6 Add a test for the new --find-package mode
d3ae0ff Improve documentation for --find-package mode
bf07375 Add a cmake.m4 for using cmake in autoconf projects instead of pkgconfig
b0e3578 Use the file-utility to test for 64bit if there is no /usr/lib64
53edfb2 Better support for lib64 and Debian multiarch
b8fdaa1 Fix copyright notice in new CMakeFindPackageMode.cmake
7690edf Replace cmake::GetScriptMode() with GetWorkingMode()
e4f603b Implement find-package mode of cmake
a91d662 Add find-package mode, which does nothing yet
b976e70 Make clLocalGenerator::GetTargetFlags() public
This commit is contained in:
David Cole 2011-08-25 15:40:49 -04:00 committed by CMake Topic Stage
commit 28cba226b3
16 changed files with 491 additions and 25 deletions

View File

@ -0,0 +1,187 @@
# This file is executed by cmake when invoked with --find-package.
# It expects that the following variables are set using -D:
# NAME = name of the package
# COMPILER_ID = the CMake compiler ID for which the result is, i.e. GNU/Intel/Clang/MSVC, etc.
# LANGUAGE = language for which the result will be used, i.e. C/CXX/Fortan/ASM
# MODE = EXIST : only check for existance of the given package
# COMPILE : print the flags needed for compiling an object file which uses the given package
# LINK : print the flags needed for linking when using the given package
# QUIET = if TRUE, don't print anything
#=============================================================================
# Copyright 2006-2011 Alexander Neundorf, <neundorf@kde.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if(NOT NAME)
message(FATAL_ERROR "Name of the package to be searched not specified. Set the CMake variable NAME, e.g. -DNAME=JPEG .")
endif()
if(NOT COMPILER_ID)
message(FATAL_ERROR "COMPILER_ID argument not specified. In doubt, use GNU.")
endif()
if(NOT LANGUAGE)
message(FATAL_ERROR "LANGUAGE argument not specified. Use C, CXX or Fortran.")
endif()
if(NOT MODE)
message(FATAL_ERROR "MODE argument not specified. Use either EXIST, COMPILE or LINK.")
endif()
# require the current version. If we don't do this, Platforms/CYGWIN.cmake complains because
# it doesn't know whether it should set WIN32 or not:
cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )
macro(ENABLE_LANGUAGE)
# disable the enable_language() command, otherwise --find-package breaks on Windows.
# On Windows, enable_language(RC) is called in the platform files unconditionally.
# But in --find-package mode, we don't want (and can't) enable any language.
endmacro()
include(CMakeDetermineSystem)
# short-cut some tests on Darwin, see Darwin-GNU.cmake:
if("${CMAKE_SYSTEM_NAME}" MATCHES Darwin AND "${COMPILER_ID}" MATCHES GNU)
set(${CMAKE_${LANGUAGE}_HAS_ISYSROOT} 0 )
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "")
endif()
# Also load the system specific file, which sets up e.g. the search paths.
# This makes the FIND_XXX() calls work much better
include(CMakeSystemSpecificInformation)
if(UNIX)
# try to guess whether we have a 64bit system, if it has not been set
# from the outside
if(NOT CMAKE_SIZEOF_VOID_P)
set(CMAKE_SIZEOF_VOID_P 4)
if(EXISTS /usr/lib64)
set(CMAKE_SIZEOF_VOID_P 8)
else()
# use the file utility to check whether itself is 64 bit:
find_program(FILE_EXECUTABLE file)
if(FILE_EXECUTABLE)
execute_process(COMMAND "${FILE_EXECUTABLE}" "${FILE_EXECUTABLE}" OUTPUT_VARIABLE fileOutput ERROR_QUIET)
if("${fileOutput}" MATCHES "64-bit")
set(CMAKE_SIZEOF_VOID_P 8)
endif()
endif()
endif()
endif()
# guess Debian multiarch if it has not been set:
if(EXISTS /etc/debian_version)
if(NOT CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE )
file(GLOB filesInLib RELATIVE /lib /lib/*-linux-gnu* )
foreach(file ${filesInLib})
if("${file}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
set(CMAKE_${LANGUAGE}_LANGUAGE_ARCHITECTURE ${file})
break()
endif()
endforeach()
endif()
endif()
endif()
set(CMAKE_${LANGUAGE}_COMPILER "dummy")
set(CMAKE_${LANGUAGE}_COMPILER_ID "${COMPILER_ID}")
include(CMake${LANGUAGE}Information)
function(set_compile_flags_var _packageName)
string(TOUPPER "${_packageName}" PACKAGE_NAME)
# Check the following variables:
# FOO_INCLUDE_DIRS
# Foo_INCLUDE_DIRS
# FOO_INCLUDES
# Foo_INCLUDES
# FOO_INCLUDE_DIR
# Foo_INCLUDE_DIR
set(includes)
if(DEFINED ${_packageName}_INCLUDE_DIRS)
set(includes ${_packageName}_INCLUDE_DIRS)
elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIRS)
set(includes ${PACKAGE_NAME}_INCLUDE_DIRS)
elseif(DEFINED ${_packageName}_INCLUDES)
set(includes ${_packageName}_INCLUDES)
elseif(DEFINED ${PACKAGE_NAME}_INCLUDES)
set(includes ${PACKAGE_NAME}_INCLUDES)
elseif(DEFINED ${_packageName}_INCLUDE_DIR)
set(includes ${_packageName}_INCLUDE_DIR)
elseif(DEFINED ${PACKAGE_NAME}_INCLUDE_DIR)
set(includes ${PACKAGE_NAME}_INCLUDE_DIR)
endif()
set(PACKAGE_INCLUDE_DIRS "${${includes}}" PARENT_SCOPE)
# Check the following variables:
# FOO_DEFINITIONS
# Foo_DEFINITIONS
set(definitions)
if(DEFINED ${_packageName}_DEFINITIONS)
set(definitions ${_packageName}_DEFINITIONS)
elseif(DEFINED ${PACKAGE_NAME}_DEFINITIONS)
set(definitions ${PACKAGE_NAME}_DEFINITIONS)
endif()
set(PACKAGE_DEFINITIONS "${${definitions}}" )
endfunction()
function(set_link_flags_var _packageName)
string(TOUPPER "${_packageName}" PACKAGE_NAME)
# Check the following variables:
# FOO_LIBRARIES
# Foo_LIBRARIES
# FOO_LIBS
# Foo_LIBS
set(libs)
if(DEFINED ${_packageName}_LIBRARIES)
set(libs ${_packageName}_LIBRARIES)
elseif(DEFINED ${PACKAGE_NAME}_LIBRARIES)
set(libs ${PACKAGE_NAME}_LIBRARIES)
elseif(DEFINED ${_packageName}_LIBS)
set(libs ${_packageName}_LIBS)
elseif(DEFINED ${PACKAGE_NAME}_LIBS)
set(libs ${PACKAGE_NAME}_LIBS)
endif()
set(PACKAGE_LIBRARIES "${${libs}}" PARENT_SCOPE )
endfunction()
find_package("${NAME}" QUIET)
set(PACKAGE_FOUND FALSE)
string(TOUPPER "${NAME}" UPPERCASE_NAME)
if(${NAME}_FOUND OR ${UPPERCASE_NAME}_FOUND)
set(PACKAGE_FOUND TRUE)
if("${MODE}" STREQUAL "EXIST")
# do nothing
elseif("${MODE}" STREQUAL "COMPILE")
set_compile_flags_var(${NAME})
elseif("${MODE}" STREQUAL "LINK")
set_link_flags_var(${NAME})
else("${MODE}" STREQUAL "LINK")
message(FATAL_ERROR "Invalid mode argument ${MODE} given.")
endif()
endif()
set(PACKAGE_QUIET ${SILENT} )

View File

@ -783,7 +783,7 @@ void cmGlobalGenerator::Configure()
// so create the map from project name to vector of local generators // so create the map from project name to vector of local generators
this->FillProjectMap(); this->FillProjectMap();
if ( !this->CMakeInstance->GetScriptMode() ) if ( this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE)
{ {
const char* msg = "Configuring done"; const char* msg = "Configuring done";
if(cmSystemTools::GetErrorOccuredFlag()) if(cmSystemTools::GetErrorOccuredFlag())

View File

@ -307,7 +307,6 @@ public:
std::string const& dir_max, std::string const& dir_max,
bool* hasSourceExtension = 0); bool* hasSourceExtension = 0);
protected:
/** Fill out these strings for the given target. Libraries to link, /** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */ * flags, and linkflags. */
void GetTargetFlags(std::string& linkLibs, void GetTargetFlags(std::string& linkLibs,
@ -315,6 +314,7 @@ protected:
std::string& linkFlags, std::string& linkFlags,
cmTarget&target); cmTarget&target);
protected:
///! put all the libraries for a target on into the given stream ///! put all the libraries for a target on into the given stream
virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink); virtual void OutputLinkLibraries(std::ostream&, cmTarget&, bool relink);

View File

@ -384,7 +384,9 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
// Decide whether to invoke the command. // Decide whether to invoke the command.
if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() && if(pcmd->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() &&
(!this->GetCMakeInstance()->GetScriptMode() || pcmd->IsScriptable())) (this->GetCMakeInstance()->GetWorkingMode() != cmake::SCRIPT_MODE
|| pcmd->IsScriptable()))
{ {
// if trace is one, print out invoke information // if trace is one, print out invoke information
if(this->GetCMakeInstance()->GetTrace()) if(this->GetCMakeInstance()->GetTrace())
@ -411,7 +413,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError()); this->IssueMessage(cmake::FATAL_ERROR, pcmd->GetError());
} }
result = false; result = false;
if ( this->GetCMakeInstance()->GetScriptMode() ) if ( this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE)
{ {
cmSystemTools::SetFatalErrorOccured(); cmSystemTools::SetFatalErrorOccured();
} }
@ -422,7 +424,7 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
this->UsedCommands.push_back(pcmd.release()); this->UsedCommands.push_back(pcmd.release());
} }
} }
else if ( this->GetCMakeInstance()->GetScriptMode() else if ( this->GetCMakeInstance()->GetWorkingMode() == cmake::SCRIPT_MODE
&& !pcmd->IsScriptable() ) && !pcmd->IsScriptable() )
{ {
std::string error = "Command "; std::string error = "Command ";
@ -3025,8 +3027,15 @@ cmCacheManager *cmMakefile::GetCacheManager() const
void cmMakefile::DisplayStatus(const char* message, float s) void cmMakefile::DisplayStatus(const char* message, float s)
{ {
this->GetLocalGenerator()->GetGlobalGenerator() cmake* cm = this->GetLocalGenerator()->GetGlobalGenerator()
->GetCMakeInstance()->UpdateProgress(message, s); ->GetCMakeInstance();
if (cm->GetWorkingMode() == cmake::FIND_PACKAGE_MODE)
{
// don't output any STATUS message in FIND_PACKAGE_MODE, since they will
// directly be fed to the compiler, which will be confused.
return;
}
cm->UpdateProgress(message, s);
} }
std::string cmMakefile::GetModulesFile(const char* filename) std::string cmMakefile::GetModulesFile(const char* filename)

View File

@ -183,7 +183,7 @@ cmake::cmake()
this->GlobalGenerator = 0; this->GlobalGenerator = 0;
this->ProgressCallback = 0; this->ProgressCallback = 0;
this->ProgressCallbackClientData = 0; this->ProgressCallbackClientData = 0;
this->ScriptMode = false; this->CurrentWorkingMode = NORMAL_MODE;
#ifdef CMAKE_BUILD_WITH_CMAKE #ifdef CMAKE_BUILD_WITH_CMAKE
this->VariableWatch = new cmVariableWatch; this->VariableWatch = new cmVariableWatch;
@ -356,6 +356,7 @@ void cmake::RemoveUnscriptableCommands()
// Parse the args // Parse the args
bool cmake::SetCacheArgs(const std::vector<std::string>& args) bool cmake::SetCacheArgs(const std::vector<std::string>& args)
{ {
bool findPackageMode = false;
for(unsigned int i=1; i < args.size(); ++i) for(unsigned int i=1; i < args.size(); ++i)
{ {
std::string arg = args[i]; std::string arg = args[i];
@ -483,7 +484,17 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
} }
this->ReadListFile(args, path.c_str()); this->ReadListFile(args, path.c_str());
} }
else if (arg.find("--find-package",0) == 0)
{
findPackageMode = true;
}
} }
if (findPackageMode)
{
return this->FindPackage(args);
}
return true; return true;
} }
@ -514,7 +525,7 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); (cmSystemTools::GetCurrentWorkingDirectory().c_str());
lg->GetMakefile()->SetStartDirectory lg->GetMakefile()->SetStartDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str()); (cmSystemTools::GetCurrentWorkingDirectory().c_str());
if (this->GetScriptMode()) if (this->GetWorkingMode() != NORMAL_MODE)
{ {
std::string file(cmSystemTools::CollapseFullPath(path)); std::string file(cmSystemTools::CollapseFullPath(path));
cmSystemTools::ConvertToUnixSlashes(file); cmSystemTools::ConvertToUnixSlashes(file);
@ -535,6 +546,111 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
} }
} }
bool cmake::FindPackage(const std::vector<std::string>& args)
{
// if a generator was not yet created, temporarily create one
cmGlobalGenerator *gg = new cmGlobalGenerator;
gg->SetCMakeInstance(this);
this->SetGlobalGenerator(gg);
// read in the list file to fill the cache
std::auto_ptr<cmLocalGenerator> lg(gg->CreateLocalGenerator());
cmMakefile* mf = lg->GetMakefile();
mf->SetHomeOutputDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
mf->SetStartOutputDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
mf->SetHomeDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
mf->SetStartDirectory
(cmSystemTools::GetCurrentWorkingDirectory().c_str());
mf->SetArgcArgv(args);
std::string systemFile = mf->GetModulesFile("CMakeFindPackageMode.cmake");
mf->ReadListFile(0, systemFile.c_str());
std::string language = mf->GetSafeDefinition("LANGUAGE");
std::string mode = mf->GetSafeDefinition("MODE");
std::string packageName = mf->GetSafeDefinition("NAME");
bool packageFound = mf->IsOn("PACKAGE_FOUND");
bool quiet = mf->IsOn("PACKAGE_QUIET");
if (!packageFound)
{
if (!quiet)
{
printf("%s not found.\n", packageName.c_str());
}
}
else if (mode == "EXIST")
{
if (!quiet)
{
printf("%s found.\n", packageName.c_str());
}
}
else if (mode == "COMPILE")
{
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
std::vector<std::string> includeDirs;
cmSystemTools::ExpandListArgument(includes, includeDirs);
for(std::vector<std::string>::const_iterator dirIt=includeDirs.begin();
dirIt != includeDirs.end();
++dirIt)
{
mf->AddIncludeDirectory(dirIt->c_str(), false);
}
std::string includeFlags = lg->GetIncludeFlags(language.c_str(), false);
std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS");
printf("%s %s\n", includeFlags.c_str(), definitions.c_str());
}
else if (mode == "LINK")
{
const char* targetName = "dummy";
std::vector<std::string> srcs;
cmTarget* tgt = mf->AddExecutable(targetName, srcs, true);
tgt->SetProperty("LINKER_LANGUAGE", language.c_str());
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
std::vector<std::string> libList;
cmSystemTools::ExpandListArgument(libs, libList);
for(std::vector<std::string>::const_iterator libIt=libList.begin();
libIt != libList.end();
++libIt)
{
mf->AddLinkLibraryForTarget(targetName, libIt->c_str(),
cmTarget::GENERAL);
}
std::string linkLibs;
std::string flags;
std::string linkFlags;
lg->GetTargetFlags(linkLibs, flags, linkFlags, *tgt);
printf("%s\n", linkLibs.c_str() );
/* if ( use_win32 )
{
tgt->SetProperty("WIN32_EXECUTABLE", "ON");
}
if ( use_macbundle)
{
tgt->SetProperty("MACOSX_BUNDLE", "ON");
}*/
}
// free generic one if generated
// this->SetGlobalGenerator(0); // setting 0-pointer is not possible
// delete gg; // this crashes inside the cmake instance
return packageFound;
}
// Parse the args // Parse the args
void cmake::SetArgs(const std::vector<std::string>& args, void cmake::SetArgs(const std::vector<std::string>& args,
bool directoriesSetBefore) bool directoriesSetBefore)
@ -607,6 +723,11 @@ void cmake::SetArgs(const std::vector<std::string>& args,
// skip for now // skip for now
i++; i++;
} }
else if(arg.find("--find-package",0) == 0)
{
// skip for now
i++;
}
else if(arg.find("-Wno-dev",0) == 0) else if(arg.find("-Wno-dev",0) == 0)
{ {
// skip for now // skip for now
@ -2035,7 +2156,7 @@ int cmake::ActualConfigure()
this->CleanupCommandsAndMacros(); this->CleanupCommandsAndMacros();
int res = 0; int res = 0;
if ( !this->ScriptMode ) if ( this->GetWorkingMode() == NORMAL_MODE )
{ {
res = this->DoPreConfigureChecks(); res = this->DoPreConfigureChecks();
} }
@ -2223,7 +2344,7 @@ int cmake::ActualConfigure()
this->CacheManager->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR"); this->CacheManager->RemoveCacheEntry("CMAKE_EXTRA_GENERATOR");
} }
// only save the cache if there were no fatal errors // only save the cache if there were no fatal errors
if ( !this->ScriptMode ) if ( this->GetWorkingMode() == NORMAL_MODE )
{ {
this->CacheManager->SaveCache(this->GetHomeOutputDirectory()); this->CacheManager->SaveCache(this->GetHomeOutputDirectory());
} }
@ -2289,7 +2410,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
// set the cmake command // set the cmake command
this->CMakeCommand = args[0]; this->CMakeCommand = args[0];
if ( !this->ScriptMode ) if ( this->GetWorkingMode() == NORMAL_MODE )
{ {
// load the cache // load the cache
if(this->LoadCache() < 0) if(this->LoadCache() < 0)
@ -2310,7 +2431,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
} }
// In script mode we terminate after running the script. // In script mode we terminate after running the script.
if(this->ScriptMode) if(this->GetWorkingMode() != NORMAL_MODE)
{ {
if(cmSystemTools::GetErrorOccuredFlag()) if(cmSystemTools::GetErrorOccuredFlag())
{ {
@ -2356,7 +2477,7 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
this->SetStartDirectory(this->GetHomeDirectory()); this->SetStartDirectory(this->GetHomeDirectory());
this->SetStartOutputDirectory(this->GetHomeOutputDirectory()); this->SetStartOutputDirectory(this->GetHomeOutputDirectory());
int ret = this->Configure(); int ret = this->Configure();
if (ret || this->ScriptMode) if (ret || this->GetWorkingMode() != NORMAL_MODE)
{ {
#if defined(CMAKE_HAVE_VS_GENERATORS) #if defined(CMAKE_HAVE_VS_GENERATORS)
if(!this->VSSolutionFile.empty() && this->GlobalGenerator) if(!this->VSSolutionFile.empty() && this->GlobalGenerator)

View File

@ -64,6 +64,25 @@ class cmake
WARNING, WARNING,
LOG LOG
}; };
/** Describes the working modes of cmake.
* NORMAL_MODE: cmake runs to create project files
* SCRIPT_MODE: in script mode there is no generator and no cache. Also,
* language are not enabled, so add_executable and things do
* not do anything. Started by using -P
* FIND_PACKAGE_MODE: cmake runs in pkg-config like mode, i.e. it just
* searches for a package and prints the results to stdout.
* This is similar to SCRIPT_MODE, but commands like
* add_library() work too, since they may be used e.g. in
* exported target files. Started via --find-package
*/
enum WorkingMode
{
NORMAL_MODE,
SCRIPT_MODE,
FIND_PACKAGE_MODE
};
typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap; typedef std::map<cmStdString, cmCommand*> RegisteredCommandsMap;
///! construct an instance of cmake ///! construct an instance of cmake
@ -274,13 +293,8 @@ class cmake
///! Do all the checks before running configure ///! Do all the checks before running configure
int DoPreConfigureChecks(); int DoPreConfigureChecks();
/** void SetWorkingMode(WorkingMode mode) { this->CurrentWorkingMode = mode; }
* Set and get the script mode option. In script mode there is no WorkingMode GetWorkingMode() { return this->CurrentWorkingMode; }
* generator and no cache. Also, language are not enabled, so
* add_executable and things do not do anything.
*/
void SetScriptMode(bool mode) { this->ScriptMode = mode; }
bool GetScriptMode() { return this->ScriptMode; }
///! Debug the try compile stuff by not delelting the files ///! Debug the try compile stuff by not delelting the files
bool GetDebugTryCompile(){return this->DebugTryCompile;} bool GetDebugTryCompile(){return this->DebugTryCompile;}
@ -409,6 +423,7 @@ protected:
///! read in a cmake list file to initialize the cache ///! read in a cmake list file to initialize the cache
void ReadListFile(const std::vector<std::string>& args, const char *path); void ReadListFile(const std::vector<std::string>& args, const char *path);
bool FindPackage(const std::vector<std::string>& args);
///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file. ///! Check if CMAKE_CACHEFILE_DIR is set. If it is not, delete the log file.
/// If it is set, truncate it to 50kb /// If it is set, truncate it to 50kb
@ -462,7 +477,7 @@ private:
void* ProgressCallbackClientData; void* ProgressCallbackClientData;
bool Verbose; bool Verbose;
bool InTryCompile; bool InTryCompile;
bool ScriptMode; WorkingMode CurrentWorkingMode;
bool DebugOutput; bool DebugOutput;
bool Trace; bool Trace;
bool WarnUninitialized; bool WarnUninitialized;

View File

@ -103,6 +103,11 @@ static const char * cmDocumentationOptions[][3] =
"No configure or generate step is performed and the cache is not" "No configure or generate step is performed and the cache is not"
" modified. If variables are defined using -D, this must be done " " modified. If variables are defined using -D, this must be done "
"before the -P argument."}, "before the -P argument."},
{"--find-package", "Run in pkg-config like mode.",
"Search a package using find_package() and print the resulting flags "
"to stdout. This can be used to use cmake instead of pkg-config to find "
"installed libraries in plain Makefile-based projects or in "
"autoconf-based projects (via share/aclocal/cmake.m4)."},
{"--graphviz=[file]", "Generate graphviz of dependencies.", {"--graphviz=[file]", "Generate graphviz of dependencies.",
"Generate a graphviz input file that will contain all the library and " "Generate a graphviz input file that will contain all the library and "
"executable dependencies in the project."}, "executable dependencies in the project."},
@ -434,7 +439,7 @@ int do_cmake(int ac, char** av)
bool list_all_cached = false; bool list_all_cached = false;
bool list_help = false; bool list_help = false;
bool view_only = false; bool view_only = false;
bool script_mode = false; cmake::WorkingMode workingMode = cmake::NORMAL_MODE;
std::vector<std::string> args; std::vector<std::string> args;
for(int i =0; i < ac; ++i) for(int i =0; i < ac; ++i)
{ {
@ -482,12 +487,18 @@ int do_cmake(int ac, char** av)
} }
else else
{ {
script_mode = true; workingMode = cmake::SCRIPT_MODE;
args.push_back(av[i]); args.push_back(av[i]);
i++; i++;
args.push_back(av[i]); args.push_back(av[i]);
} }
} }
else if (!command && strncmp(av[i], "--find-package",
strlen("--find-package")) == 0)
{
workingMode = cmake::FIND_PACKAGE_MODE;
args.push_back(av[i]);
}
else else
{ {
args.push_back(av[i]); args.push_back(av[i]);
@ -512,7 +523,7 @@ int do_cmake(int ac, char** av)
cmake cm; cmake cm;
cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm); cmSystemTools::SetErrorCallback(cmakemainErrorCallback, (void *)&cm);
cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm); cm.SetProgressCallback(cmakemainProgressCallback, (void *)&cm);
cm.SetScriptMode(script_mode); cm.SetWorkingMode(workingMode);
int res = cm.Run(args, view_only); int res = cm.Run(args, view_only);
if ( list_cached || list_all_cached ) if ( list_cached || list_all_cached )

View File

@ -48,6 +48,8 @@ IF(BUILD_TESTING)
ADD_SUBDIRECTORY(CMakeLib) ADD_SUBDIRECTORY(CMakeLib)
ADD_SUBDIRECTORY(FindPackageModeMakefileTest)
# Collect a list of all test build directories. # Collect a list of all test build directories.
SET(TEST_BUILD_DIRS) SET(TEST_BUILD_DIRS)

View File

@ -0,0 +1,30 @@
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile")
# Test whether the make is GNU make, and only add the test in this case,
# since the configured makefile in this test uses $(shell ...), which
# is AFAIK a GNU make extension. Alex
execute_process(COMMAND ${CMAKE_MAKE_PROGRAM} -v
OUTPUT_VARIABLE makeVersionOutput
TIMEOUT 10)
string(TOUPPER "${makeVersionOutput}" MAKE_VERSION_OUTPUT)
if("${MAKE_VERSION_OUTPUT}" MATCHES ".*GNU MAKE.*")
# build a library which we can search during the test
add_library(foo STATIC foo.cpp)
# configure a FindFoo.cmake so it knows where the library can be found
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
# now set up the test:
get_target_property(cmakeExecutable cmake LOCATION)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Makefile.in ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/main.cpp ${CMAKE_CURRENT_BINARY_DIR}/main.cpp COPYONLY)
add_test(FindPackageModeMakefileTest ${CMAKE_MAKE_PROGRAM} -f ${CMAKE_CURRENT_BINARY_DIR}/ConfMakefile )
endif()
endif()

View File

@ -0,0 +1,9 @@
find_library(FOO_LIBRARY NAMES foo HINTS "@CMAKE_CURRENT_BINARY_DIR@" )
find_path(FOO_INCLUDE_DIR NAMES foo.h HINTS "@CMAKE_CURRENT_SOURCE_DIR@" )
set(FOO_LIBRARIES ${FOO_LIBRARY})
set(FOO_INCLUDE_DIRS "${FOO_INCLUDE_DIR}" "/some/path/with a space/include" )
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo DEFAULT_MSG FOO_LIBRARY FOO_INCLUDE_DIR )

View File

@ -0,0 +1,10 @@
all: clean pngtest
main.o: main.cpp
"@CMAKE_CXX_COMPILER@" $(CXXFLAGS) -c $(shell "@cmakeExecutable@" --find-package -DCMAKE_MODULE_PATH="@CMAKE_CURRENT_BINARY_DIR@" -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=@CMAKE_CXX_COMPILER_ID@ -DMODE=COMPILE) main.cpp
pngtest: main.o
"@CMAKE_CXX_COMPILER@" $(LDFLAGS) -o pngtest main.o $(shell "@cmakeExecutable@" --find-package -DCMAKE_MODULE_PATH="@CMAKE_CURRENT_BINARY_DIR@" -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=@CMAKE_CXX_COMPILER_ID@ -DMODE=LINK)
clean:
rm -f *.o pngtest

View File

@ -0,0 +1,4 @@
int foo()
{
return 1477;
}

View File

@ -0,0 +1,6 @@
#ifndef FOO_H
#define FOO_H
int foo();
#endif

View File

@ -0,0 +1,8 @@
#include <stdio.h>
#include <foo.h>
int main()
{
printf("foo is: %d\n", foo());
return 0;
}

View File

@ -126,6 +126,7 @@ ADD_CUSTOM_COMMAND(
INSTALL_FILES(${CMAKE_MAN_DIR}/man1 FILES ${MAN_FILES}) INSTALL_FILES(${CMAKE_MAN_DIR}/man1 FILES ${MAN_FILES})
INSTALL_FILES(${CMAKE_DOC_DIR} FILES ${HTML_FILES} ${TEXT_FILES}) INSTALL_FILES(${CMAKE_DOC_DIR} FILES ${HTML_FILES} ${TEXT_FILES})
INSTALL_FILES(share/aclocal FILES cmake.m4)
# Drive documentation generation. # Drive documentation generation.
ADD_CUSTOM_TARGET(documentation ALL DEPENDS ${DOC_FILES} ${CMake_BINARY_DIR}/Docs/cmake.txt ) ADD_CUSTOM_TARGET(documentation ALL DEPENDS ${DOC_FILES} ${CMake_BINARY_DIR}/Docs/cmake.txt )

53
Utilities/cmake.m4 Normal file
View File

@ -0,0 +1,53 @@
dnl ============================================================================
dnl CMake - Cross Platform Makefile Generator
dnl Copyright 2011 Matthias Kretz, kretz@kde.org
dnl
dnl Distributed under the OSI-approved BSD License (the "License");
dnl see accompanying file Copyright.txt for details.
dnl
dnl This software is distributed WITHOUT ANY WARRANTY; without even the
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dnl See the License for more information.
dnl ============================================================================
AC_DEFUN([CMAKE_FIND_BINARY],
[AC_ARG_VAR([CMAKE_BINARY], [path to the cmake binary])dnl
if test "x$ac_cv_env_CMAKE_BINARY_set" != "xset"; then
AC_PATH_TOOL([CMAKE_BINARY], [cmake])dnl
fi
])dnl
# $1: package name
# $2: language (e.g. C/CXX/Fortran)
# $3: The compiler ID, defaults to GNU.
# Possible values are: GNU, Intel, Clang, SunPro, HP, XL, VisualAge, PGI,
# PathScale, Cray, SCO, MIPSpro, MSVC
# $4: optional extra arguments to cmake, e.g. "-DCMAKE_SIZEOF_VOID_P=8"
# $5: optional path to cmake binary
AC_DEFUN([CMAKE_FIND_PACKAGE], [
AC_REQUIRE([CMAKE_FIND_BINARY])dnl
AC_ARG_VAR([$1][_][$2][FLAGS], [$2 compiler flags for $1. This overrides the cmake output])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1. This overrides the cmake output])dnl
failed=false
AC_MSG_CHECKING([for $1])
if test -n "$1[]_$2[]FLAGS"; then
$1[]_$2[]FLAGS=`$CMAKE_BINARY --find-package "-DNAME=$1" "-DCOMPILER_ID=m4_default([$3], [GNU])" "-DLANGUAGE=$2" -DMODE=COMPILE $4` || failed=true
fi
if test -n "$1[]_LIBS"; then
$1[]_LIBS=`$CMAKE_BINARY --find-package "-DNAME=$1" "-DCOMPILER_ID=m4_default([$3], [GNU])" "-DLANGUAGE=$2" -DMODE=LINK $4` || failed=true
fi
if $failed; then
unset $1[]_$2[]FLAGS
unset $1[]_LIBS
AC_MSG_RESULT([no])
$6
else
AC_MSG_RESULT([yes])
$5
fi[]dnl
])