Implement find-package mode of cmake
In find-package mode, cmake executes Modules/CMakeFindPackage.cmake, which calls find_package(), and this is then evaluated in cmake.cxx, which prints an appropriate message to stdout, so it can be used e.g. in a normal Makefile: $ /opt/cmake-HEAD/bin/cmake --find-package -DNAME=JPEG -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=EXIST JPEG found. $ /opt/cmake-HEAD/bin/cmake --find-package -DNAME=JPEG -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=COMPILE $ /opt/cmake-HEAD/bin/cmake --find-package -DNAME=JPEG -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=LINK -rdynamic -ljpeg Alex
This commit is contained in:
parent
a91d662f46
commit
e4f603b698
|
@ -0,0 +1,125 @@
|
|||
# COMPILER_ID = GNU/Intel/etc.
|
||||
# LANGUAGE = C/CXX/Fortan/ASM
|
||||
# MODE = EXIST/COMPILE/LINK
|
||||
# NAME = name of the package
|
||||
# QUIET = if TRUE, don't print anything
|
||||
|
||||
if(NOT NAME)
|
||||
message(FATAL_ERROR "NAME argument not specified.")
|
||||
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()
|
||||
|
||||
|
||||
include(CMakeDetermineSystem)
|
||||
|
||||
# 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)
|
||||
|
||||
# this is ugly, and not enough for the multilib-stuff I guess
|
||||
if(UNIX AND EXISTS /usr/lib64)
|
||||
set(CMAKE_SIZEOF_VOID_P 8)
|
||||
endif()
|
||||
|
||||
set(CMAKE_${LANGUAGE}_COMPILER "dummy")
|
||||
set(CMAKE_${LANGUAGE}_COMPILER_ID "${COMPILER_ID}")
|
||||
include(CMake${LANGUAGE}Information)
|
||||
|
||||
|
||||
function(print_compile_flags _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(print_link_flags _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")
|
||||
print_compile_flags(${NAME})
|
||||
elseif("${MODE}" STREQUAL "LINK")
|
||||
print_link_flags(${NAME})
|
||||
else("${MODE}" STREQUAL "LINK")
|
||||
message(FATAL_ERROR "Invalid mode argument ${MODE} given.")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
set(PACKAGE_QUIET ${SILENT} )
|
100
Source/cmake.cxx
100
Source/cmake.cxx
|
@ -547,8 +547,104 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
|
|||
|
||||
bool cmake::FindPackage(const std::vector<std::string>& args)
|
||||
{
|
||||
// create empty function for now, will be filled later
|
||||
return true;
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue