diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 575dd04f2..2bc65ceba 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -68,6 +68,12 @@ bool cmAddLibraryCommand type = cmTarget::MODULE_LIBRARY; haveSpecifiedType = true; } + else if(libType == "UNKNOWN") + { + ++s; + type = cmTarget::UNKNOWN_LIBRARY; + haveSpecifiedType = true; + } else if(*s == "EXCLUDE_FROM_ALL") { ++s; @@ -127,6 +133,16 @@ bool cmAddLibraryCommand return true; } + // A non-imported target may not have UNKNOWN type. + if(type == cmTarget::UNKNOWN_LIBRARY) + { + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + "The UNKNOWN library type may be used only for IMPORTED libraries." + ); + return true; + } + // Enforce name uniqueness. { std::string msg; diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h index ad23ffc5b..6cad681a9 100644 --- a/Source/cmAddLibraryCommand.h +++ b/Source/cmAddLibraryCommand.h @@ -100,7 +100,7 @@ public: "\n" "The add_library command can also create IMPORTED library " "targets using this signature:\n" - " add_library( IMPORTED)\n" + " add_library( IMPORTED)\n" "An IMPORTED library target references a library file located " "outside the project. " "No rules are generated to build it. " diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 177ec5877..df329a67f 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -890,6 +890,14 @@ void cmComputeLinkDepends::CheckWrongConfigItem(std::string const& item) } } +//---------------------------------------------------------------------------- +static bool cmComputeLinkDependsNotStatic(cmTarget* tgt) +{ + return (tgt && + tgt->GetType() != cmTarget::STATIC_LIBRARY && + tgt->GetType() != cmTarget::UNKNOWN_LIBRARY); +} + //---------------------------------------------------------------------------- void cmComputeLinkDepends::PreserveOriginalEntries() { @@ -901,7 +909,7 @@ void cmComputeLinkDepends::PreserveOriginalEntries() out != this->FinalLinkOrder.end()) { cmTarget* tgt = this->EntryList[*in].Target; - if(tgt && tgt->GetType() != cmTarget::STATIC_LIBRARY) + if(cmComputeLinkDependsNotStatic(tgt)) { // Skip input items known to not be static libraries. ++in; @@ -924,7 +932,7 @@ void cmComputeLinkDepends::PreserveOriginalEntries() while(in != this->OriginalEntries.end()) { cmTarget* tgt = this->EntryList[*in].Target; - if(tgt && tgt->GetType() != cmTarget::STATIC_LIBRARY) + if(cmComputeLinkDependsNotStatic(tgt)) { // Skip input items known to not be static libraries. ++in; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 6e0f10bf7..0b02ae12f 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -581,10 +581,7 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt) return; } - if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY || - tgt->GetType() == cmTarget::SHARED_LIBRARY || - tgt->GetType() == cmTarget::MODULE_LIBRARY || - impexe)) + if(tgt && tgt->IsLinkable()) { // This is a CMake target. Ask the target for its real name. if(impexe && this->LoaderFlag) @@ -1555,6 +1552,14 @@ void cmComputeLinkInformation::AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target) { + // Libraries with unknown type must be handled using just the file + // on disk. + if(target->GetType() == cmTarget::UNKNOWN_LIBRARY) + { + this->AddLibraryRuntimeInfo(fullPath); + return; + } + // Skip targets that are not shared libraries (modules cannot be linked). if(target->GetType() != cmTarget::SHARED_LIBRARY) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 064cfb5ac..4bf183943 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1706,6 +1706,7 @@ std::string cmLocalGenerator::GetRealDependency(const char* inName, case cmTarget::STATIC_LIBRARY: case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + case cmTarget::UNKNOWN_LIBRARY: { // Get the location of the target's output file and depend on it. if(const char* location = target->GetLocation(config)) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index caa534f38..296e93df3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -30,7 +30,8 @@ const char* cmTarget::TargetTypeNames[] = { "EXECUTABLE", "STATIC_LIBRARY", "SHARED_LIBRARY", "MODULE_LIBRARY", "UTILITY", "GLOBAL_TARGET", - "INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY" + "INSTALL_FILES", "INSTALL_PROGRAMS", "INSTALL_DIRECTORY", + "UNKNOWN_LIBRARY" }; //---------------------------------------------------------------------------- @@ -277,6 +278,7 @@ void cmTarget::DefineProperties(cmake *cm) "For frameworks on OS X this is the location of the library file " "symlink just inside the framework folder. " "For DLLs this is the location of the \".dll\" part of the library. " + "For UNKNOWN libraries this is the location of the file to be linked. " "Ignored for non-imported targets."); cm->DefineProperty @@ -786,6 +788,16 @@ bool cmTarget::IsExecutableWithExports() this->GetPropertyAsBool("ENABLE_EXPORTS")); } +//---------------------------------------------------------------------------- +bool cmTarget::IsLinkable() +{ + return (this->GetType() == cmTarget::STATIC_LIBRARY || + this->GetType() == cmTarget::SHARED_LIBRARY || + this->GetType() == cmTarget::MODULE_LIBRARY || + this->GetType() == cmTarget::UNKNOWN_LIBRARY || + this->IsExecutableWithExports()); +} + //---------------------------------------------------------------------------- bool cmTarget::IsFrameworkOnApple() { @@ -1860,7 +1872,8 @@ const char *cmTarget::GetProperty(const char* prop, if(this->GetType() == cmTarget::EXECUTABLE || this->GetType() == cmTarget::STATIC_LIBRARY || this->GetType() == cmTarget::SHARED_LIBRARY || - this->GetType() == cmTarget::MODULE_LIBRARY) + this->GetType() == cmTarget::MODULE_LIBRARY || + this->GetType() == cmTarget::UNKNOWN_LIBRARY) { if(!this->IsImported() && strcmp(prop,"LOCATION") == 0) { @@ -1957,6 +1970,9 @@ const char *cmTarget::GetProperty(const char* prop, case cmTarget::INSTALL_DIRECTORY: return "INSTALL_DIRECTORY"; // break; /* unreachable */ + case cmTarget::UNKNOWN_LIBRARY: + return "UNKNOWN_LIBRARY"; + // break; /* unreachable */ } return 0; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7141e4184..07004bed7 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -80,7 +80,8 @@ public: cmTarget(); enum TargetType { EXECUTABLE, STATIC_LIBRARY, SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET, - INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY}; + INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY, + UNKNOWN_LIBRARY}; static const char* TargetTypeNames[]; enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD }; @@ -393,6 +394,9 @@ public: enabled. */ bool IsExecutableWithExports(); + /** Return whether this target may be used to link another target. */ + bool IsLinkable(); + /** Return whether this target is a shared library Framework on Apple. */ bool IsFrameworkOnApple(); diff --git a/Tests/SimpleInstall/CMakeLists.txt b/Tests/SimpleInstall/CMakeLists.txt index 34914b6a3..c204e6410 100644 --- a/Tests/SimpleInstall/CMakeLists.txt +++ b/Tests/SimpleInstall/CMakeLists.txt @@ -66,9 +66,13 @@ IF(STAGE2) PATHS ${LIBPATHS} DOC "Fourth library") + # Test importing a library found on disk. + ADD_LIBRARY(lib_test4 UNKNOWN IMPORTED) + SET_PROPERTY(TARGET lib_test4 PROPERTY IMPORTED_LOCATION ${TEST4_LIBRARY}) + INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/MyTest/include) ADD_EXECUTABLE (SimpleInstExeS2 inst2.cxx foo.c foo.h) - TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY}) + TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} lib_test4) SET(install_target SimpleInstExeS2) IF("${TEST1_LIBRARY}" MATCHES "static") diff --git a/Tests/SimpleInstallS2/CMakeLists.txt b/Tests/SimpleInstallS2/CMakeLists.txt index 34914b6a3..c204e6410 100644 --- a/Tests/SimpleInstallS2/CMakeLists.txt +++ b/Tests/SimpleInstallS2/CMakeLists.txt @@ -66,9 +66,13 @@ IF(STAGE2) PATHS ${LIBPATHS} DOC "Fourth library") + # Test importing a library found on disk. + ADD_LIBRARY(lib_test4 UNKNOWN IMPORTED) + SET_PROPERTY(TARGET lib_test4 PROPERTY IMPORTED_LOCATION ${TEST4_LIBRARY}) + INCLUDE_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/MyTest/include) ADD_EXECUTABLE (SimpleInstExeS2 inst2.cxx foo.c foo.h) - TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} ${TEST4_LIBRARY}) + TARGET_LINK_LIBRARIES(SimpleInstExeS2 ${TEST1_LIBRARY} ${TEST2_LIBRARY} lib_test4) SET(install_target SimpleInstExeS2) IF("${TEST1_LIBRARY}" MATCHES "static")