MantisBT - CMake
View Issue Details
0014105CMakeCMakepublic2013-04-22 11:042013-10-07 10:09
Stephen Kelly 
Stephen Kelly 
normalminoralways
closedno change required 
Apple MacOSX
CMake 2.8.10.2 
 
0014105: IMPORTED target for a framework not handled correctly.

Given this:

 
 cmake_minimum_required(VERSION 2.8)
 
 project(cmake_framework_target)
 
 find_library(COCOA_LIBRARY Cocoa)
 
 add_library(Custom::Cocoa IMPORTED SHARED)
 
 set_property(TARGET Custom::Cocoa APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
 set_property(TARGET Custom::Cocoa PROPERTY IMPORTED_LOCATION_RELEASE "${COCOA_LIBRARY}")
 
 set_property(TARGET Custom::Cocoa PROPERTY FRAMEWORK 1)
 
 add_executable(Framework_test main.cpp)
 #target_link_libraries(Framework_test ${COCOA_LIBRARY})
 target_link_libraries(Framework_test Custom::Cocoa)

Using the COCOA_LIBRARY in the tll() line works fine, linking is done with -framework Cocoa.

However, using the IMPORTED target, cmake links with this result:

 Linking CXX executable Framework_test
 /Users/kdab/dev/cmake/build/bin/cmake -E cmake_link_script CMakeFiles/Framework_test.dir/link.txt --verbose=1
 /usr/bin/c++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/Framework_test.dir/main.cpp.o -o Framework_test /System/Library/Frameworks/Cocoa.framework
 ld: in /System/Library/Frameworks/Cocoa.framework, can't map file, errno=22 for architecture x86_64
 collect2: ld returned 1 exit status


This patch fixes the issue, but I have no idea if it is appropriate (because I don't have any familiarity with Mac, or how frameworks are supposed to work, or if it is appropriate to create an imported target for a framework at all in cmake):

 
 diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
 index 896b50a..4fd32ea 100644
 --- a/Source/cmComputeLinkInformation.cxx
 +++ b/Source/cmComputeLinkInformation.cxx
 @@ -657,14 +657,21 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
 
       // Pass the full path to the target file.
       std::string lib = tgt->GetFullPath(config, implib, true);
 - if(!this->LinkDependsNoShared ||
 - tgt->GetType() != cmTarget::SHARED_LIBRARY)
 + if(cmSystemTools::FileIsDirectory(lib.c_str()))
         {
 - this->Depends.push_back(lib);
 + this->AddDirectoryItem(lib);
         }
 + else
 + {
 + if(!this->LinkDependsNoShared ||
 + tgt->GetType() != cmTarget::SHARED_LIBRARY)
 + {
 + this->Depends.push_back(lib);
 + }
 
 - this->AddTargetItem(lib, tgt);
 - this->AddLibraryRuntimeInfo(lib, tgt);
 + this->AddTargetItem(lib, tgt);
 + this->AddLibraryRuntimeInfo(lib, tgt);
 + }
       }
     }
   else

 
No tags attached.
Issue History
2013-04-22 11:04Stephen KellyNew Issue
2013-04-22 11:17Brad KingNote Added: 0032918
2013-04-22 11:28Stephen KellyNote Added: 0032919
2013-04-22 11:34Brad KingNote Added: 0032920
2013-04-22 11:38Stephen KellyNote Added: 0032921
2013-04-22 11:38Stephen KellyStatusnew => resolved
2013-04-22 11:38Stephen KellyResolutionopen => no change required
2013-04-22 11:38Stephen KellyAssigned To => Stephen Kelly
2013-10-07 10:09Robert MaynardNote Added: 0034036
2013-10-07 10:09Robert MaynardStatusresolved => closed

Notes
(0032918)
Brad King   
2013-04-22 11:17   
What is the content of link.txt in the failing case?

The ExportImport test covers a framework (testLib4) so there must be something different here. The imported location of the framework should not be just the directory but the "Cocoa" symlink inside it.
(0032919)
Stephen Kelly   
2013-04-22 11:28   
# cat CMakeFiles/Framework_test.dir/link.txt
 /usr/bin/c++ -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/Framework_test.dir/main.cpp.o -o Framework_test /System/Library/Frameworks/Cocoa.framework

Indeed, if I update the location to

 set_property(TARGET Custom::Cocoa PROPERTY IMPORTED_LOCATION_RELEASE "${COCOA_LIBRARY}/Cocoa")

It builds, but with the full path to the directory, not '-framework Cocoa'. Does that have any disadvantages?
(0032920)
Brad King   
2013-04-22 11:34   
From OS X "man ld":

 -framework name[,suffix]
  This option tells the linker to search for `name.framework/name' the framework search path.

For linking, specifying the name directly instead of "-framework name" is equivalent except there is no chance the wrong one will be found.
(0032921)
Stephen Kelly   
2013-04-22 11:38   
Ok, thanks for the info. I'll close the bug.
(0034036)
Robert Maynard   
2013-10-07 10:09   
Closing resolved issues that have not been updated in more than 4 months.