Realm-cocoa: Project with iOS and OS X targets fails to compile with "Undefined symbols"

Created on 17 Jun 2016  路  10Comments  路  Source: realm/realm-cocoa

I have project with two targets - iOS and OS X. After adding Realm to it with CocoaPods it fails to compile for iOS target with Undefined symbols for architecture x86_64. For OS X everything works fine.

You can find sample project here.

Realm version: 1.0.1
Xcode version: 7.3
CocoaPods: 1.0.1

T-Bug

Most helpful comment

Hey @jpsim - running pod deintegrate && pod install --verbose did it. Thanks!

All 10 comments

Thanks for reporting this!

I can confirm this issue. Everything works with CocoaPods 0.39 though. There is a similar issues here: https://github.com/CocoaPods/CocoaPods/issues/5518

/cc @mrackwitz

I can confirm that this is a problem and could locate the root cause.

The problem here is that there is a name overlapping of the build product of the static library target generated by CocoaPods (libRealm-iOS.a) and the vendored static library used by the podspec (librealm-ios.a). Even though the name is not exactly identical, clang's linker is case-insensitive and uses the first matching according to the order of the LIBRARY_SEARCH_PATHS. As both are required changing the order doesn't help.

Usually the linter ensures that a pod can be built and included in a project. But it uses frameworks by default and doesn't additionally check whether a pod can be used in the integration mode with static libraries.

This must be fixed in CocoaPods.

As an alternative workaround to what @stel proposed before, you could also declare use_frameworks! in your Podfile and use frameworks, while this will break backwards-compatibility to iOS 7.0 for distribution via the AppStore.

Is it worth working around in Realm for now by using our core static libraries via different names with CocoaPods? We could easily rename them to librealm-core-foo.a within build.sh cocoapods-setup.

Is this issue still open? I cloned @dvor repo and updated it to current versions and my desired project structure with the shared code between iOS and OS X in a "Kit". Here is the repo. https://github.com/jcmendez/ReproducingCocoaRealmIssue

If I use use_frameworks! it builds, but I guess that's the same as @mrackwitz mentions above. However on the actual project I'm trying to use this, even with use_frameworks!, I keep getting a bunch of undefined symbols (below) - any ideas?

Undefined symbols for architecture x86_64: "realm::BpTreeBase::replace_root(std::__1::unique_ptr<realm::Array, std::__1::default_delete<realm::Array> >)", referenced from: realm::Column<long long>::replace_root_array(std::__1::unique_ptr<realm::Array, std::__1::default_delete<realm::Array> >) in collection_notifier.o realm::BpTree<long long>::EraseHandler::replace_root_by_leaf(realm::MemRef) in collection_notifier.o realm::BpTree<long long>::EraseHandler::replace_root_by_empty_leaf() in collection_notifier.o realm::BpTree<long long>::clear() in collection_notifier.o realm::Column<long long>::replace_root_array(std::__1::unique_ptr<realm::Array, std::__1::default_delete<realm::Array> >) in external_commit_helper.o realm::BpTree<long long>::EraseHandler::replace_root_by_leaf(realm::MemRef) in external_commit_helper.o realm::BpTree<long long>::EraseHandler::replace_root_by_empty_leaf() in external_commit_helper.o ... "realm::BpTreeBase::write_subtree(realm::BpTreeNode const&, unsigned long, unsigned long, unsigned long, realm::BpTreeBase::SliceHandler&, realm::_impl::OutputStream&)", referenced from: realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in collection_notifier.o realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in external_commit_helper.o realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in list.o realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in list_notifier.o realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in object.o realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in object_notifier.o realm::BpTree<long long>::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in object_store.o

I cloned your project @jcmendez and couldn't reproduce the compilation failures with CocoaPods 1.2.0 and Xcode 8.2. Perhaps update your version of CocoaPods to confirm that the issue is still occurring there?

Deleting the CocoaPods cache, clearing derived data, cleaning your project, running pod deintegrate && pod install --verbose are also good things to try.

Looks like your repro case and real project are different enough to not produce the same results. Could you update your repro project to trigger the same undefined symbols errors?

Also keep in mind that Swift frameworks (such as the RealmSwift pod) _require_ use_frameworks!, so removing that line from your Podfile isn't _supposed_ to work.

@jpsim - thanks so much for looking into this. I think the easiest is for me to give you access to the actual repo where the issue happens. I'll follow up with a private invite

The branch admin on that repo starts to build a Mac app for managing some of the data there. The DockKit kit contains the shared classes between client and admin.

Here is the partial log of the failure to build Realm-OSX

````
Ld /Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Products/Debug/Realm-OSX/Realm.framework/Versions/A/Realm normal x86_64
cd /Users/jcmendez/Development/DockGenius/dockgenius-ios/Pods
export MACOSX_DEPLOYMENT_TARGET=10.9
/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -dynamiclib -isysroot /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -L/Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Products/Debug/Realm-OSX -F/Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Products/Debug/Realm-OSX -filelist /Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Intermediates/Pods.build/Debug/Realm-OSX.build/Objects-normal/x86_64/Realm.LinkFileList -install_name @rpath/Realm.framework/Versions/A/Realm -Xlinker -rpath -Xlinker @executable_path/../Frameworks -Xlinker -rpath -Xlinker @loader_path/Frameworks -mmacosx-version-min=10.9 -Xlinker -object_path_lto -Xlinker /Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Intermediates/Pods.build/Debug/Realm-OSX.build/Objects-normal/x86_64/Realm_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -stdlib=libc++ -fapplication-extension -fobjc-arc -fobjc-link-runtime -lc++ -lz -framework Cocoa -single_module -compatibility_version 1 -current_version 1 -Xlinker -dependency_info -Xlinker /Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Intermediates/Pods.build/Debug/Realm-OSX.build/Objects-normal/x86_64/Realm_dependency_info.dat -o /Users/jcmendez/Library/Developer/Xcode/DerivedData/DockGenius-hgfrwvonfxytbjbfiwmyocaywscc/Build/Products/Debug/Realm-OSX/Realm.framework/Versions/A/Realm

Undefined symbols for architecture x86_64:
"realm::BpTreeBase::replace_root(std::__1::unique_ptr >)", referenced from:
realm::Column::replace_root_array(std::__1::unique_ptr >) in collection_notifier.o
realm::BpTree::EraseHandler::replace_root_by_leaf(realm::MemRef) in collection_notifier.o
realm::BpTree::EraseHandler::replace_root_by_empty_leaf() in collection_notifier.o
realm::BpTree::clear() in collection_notifier.o
realm::Column::replace_root_array(std::__1::unique_ptr >) in external_commit_helper.o
realm::BpTree::EraseHandler::replace_root_by_leaf(realm::MemRef) in external_commit_helper.o
realm::BpTree::EraseHandler::replace_root_by_empty_leaf() in external_commit_helper.o
...
"realm::BpTreeBase::write_subtree(realm::BpTreeNode const&, unsigned long, unsigned long, unsigned long, realm::BpTreeBase::SliceHandler&, realm::_impl::OutputStream&)", referenced from:
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in collection_notifier.o
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in external_commit_helper.o
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in list.o
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in list_notifier.o
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in object.o
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in object_notifier.o
realm::BpTree::write(unsigned long, unsigned long, unsigned long, realm::_impl::OutputStream&) const in object_store.o
...
"realm::BpTreeBase::introduce_new_root(unsigned long, realm::TreeInsertBase&, bool)", referenced from:
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in collection_notifier.o
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in external_commit_helper.o
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in list.o
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in list_notifier.o
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in object.o
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in object_notifier.o
void realm::BpTree::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&, unsigned long) in object_store.o
...
"realm::BpTreeNode::erase_bptree_elem(realm::BpTreeNode, unsigned long, realm::BpTreeNode::EraseHandler&)", referenced from:
realm::BpTree::erase(unsigned long, bool) in collection_notifier.o
realm::BpTree::erase(unsigned long, bool) in external_commit_helper.o
realm::BpTree::erase(unsigned long, bool) in list.o
realm::BpTree::erase(unsigned long, bool) in list_notifier.o
realm::BpTree::erase(unsigned long, bool) in object.o
realm::BpTree::erase(unsigned long, bool) in object_notifier.o
realm::BpTree::erase(unsigned long, bool) in object_store.o
...
"realm::BpTreeNode::update_bptree_elem(unsigned long, realm::BpTreeNode::UpdateHandler&)", referenced from:
realm::BpTree::set_null(unsigned long) in collection_notifier.o
realm::BpTree::set(unsigned long, long long) in collection_notifier.o
realm::BpTree::set_null(unsigned long) in external_commit_helper.o
realm::BpTree::set(unsigned long, long long) in external_commit_helper.o
realm::BpTree::set_null(unsigned long) in list.o
realm::BpTree::set(unsigned long, long long) in list.o
realm::BpTree::set_null(unsigned long) in list_notifier.o
...
"realm::BpTreeNode::insert_bptree_child(realm::Array&, unsigned long, unsigned long, realm::TreeInsertBase&)", referenced from:
unsigned long realm::BpTreeNode::bptree_append::LeafValueInserter>(realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in collection_notifier.o
unsigned long realm::BpTreeNode::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in collection_notifier.o
unsigned long realm::BpTreeNode::bptree_append::LeafValueInserter>(realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in external_commit_helper.o
unsigned long realm::BpTreeNode::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in external_commit_helper.o
unsigned long realm::BpTreeNode::bptree_append::LeafValueInserter>(realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in list.o
unsigned long realm::BpTreeNode::bptree_insert::LeafValueInserter>(unsigned long, realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in list.o
unsigned long realm::BpTreeNode::bptree_append::LeafValueInserter>(realm::BpTreeNode::TreeInsert::LeafValueInserter>&) in list_notifier.o
...
"realm::BpTreeNode::create_bptree_offsets(realm::Array&, long long)", referenced from:
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in collection_notifier.o
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in external_commit_helper.o
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in list.o
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in list_notifier.o
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in object.o
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in object_notifier.o
realm::BpTreeNode::ensure_bptree_offsets(realm::Array&) in object_store.o
...
"realm::ColumnBase::set_string(unsigned long, realm::StringData)", referenced from:
vtable for realm::LinkColumnBase in collection_notifier.o
vtable for realm::LinkListColumn in collection_notifier.o
vtable for realm::Column in collection_notifier.o
vtable for realm::LinkColumnBase in external_commit_helper.o
vtable for realm::LinkListColumn in external_commit_helper.o
vtable for realm::Column in external_commit_helper.o
vtable for realm::LinkColumnBase in list.o
...
"realm::ColumnBase::cascade_break_backlinks_to(unsigned long, realm::CascadeState&)", referenced from:
vtable for realm::LinkColumnBase in collection_notifier.o
vtable for realm::BinaryColumn in collection_notifier.o
vtable for realm::Column in collection_notifier.o
vtable for realm::LinkColumnBase in external_commit_helper.o
vtable for realm::BinaryColumn in external_commit_helper.o
vtable for realm::Column in external_commit_helper.o
vtable for realm::LinkColumnBase in list.o
...
"realm::ColumnBase::cascade_break_backlinks_to_all_rows(unsigned long, realm::CascadeState&)", referenced from:
vtable for realm::LinkColumnBase in collection_notifier.o
vtable for realm::BinaryColumn in collection_notifier.o
vtable for realm::Column in collection_notifier.o
vtable for realm::LinkColumnBase in external_commit_helper.o
vtable for realm::BinaryColumn in external_commit_helper.o
vtable for realm::Column in external_commit_helper.o
vtable for realm::LinkColumnBase in list.o
...
"realm::ColumnBase::build(unsigned long
, unsigned long, realm::Allocator&, realm::ColumnBase::CreateHandler&)", referenced from:
realm::ColumnBase::create(realm::Allocator&, unsigned long, realm::ColumnBase::CreateHandler&) in results.o
realm::ColumnBase::create(realm::Allocator&, unsigned long, realm::ColumnBase::CreateHandler&) in results_notifier.o
realm::ColumnBase::create(realm::Allocator&, unsigned long, realm::ColumnBase::CreateHandler&) in RLMCollection.o
"realm::LinkColumn::erase_rows(unsigned long, unsigned long, unsigned long, bool)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::insert_rows(unsigned long, unsigned long, unsigned long, bool)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::do_nullify_link(unsigned long, unsigned long)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::move_last_row_over(unsigned long, unsigned long, bool)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::cascade_break_backlinks_to(unsigned long, realm::CascadeState&)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::cascade_break_backlinks_to_all_rows(unsigned long, realm::CascadeState&)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::clear(unsigned long, bool)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::LinkColumn::swap_rows(unsigned long, unsigned long)", referenced from:
vtable for realm::LinkColumn in RLMQueryUtil.o
"realm::RowIndexes::RowIndexes(realm::Column::unattached_root_tag, realm::Allocator&)", referenced from:
realm::TableViewBase::TableViewBase() in results.o
realm::TableViewBase::TableViewBase(realm::TableViewBase const&) in results.o
realm::TableViewBase::TableViewBase() in results_notifier.o
realm::TableViewBase::TableViewBase(realm::TableViewBase const&) in results_notifier.o
realm::TableViewBase::TableViewBase(realm::TableViewBase const&) in RLMAccessor.o
realm::TableViewBase::TableViewBase() in RLMCollection.o
realm::TableViewBase::TableViewBase(realm::TableViewBase const&) in RLMCollection.o
...
"realm::RowIndexes::RowIndexes(realm::Column&&)", referenced from:
realm::TableViewBase::TableViewBase(realm::TableViewBase&&) in results.o
realm::TableViewBase::TableViewBase(realm::TableViewBase&&) in RLMAccessor.o
"realm::StringData::matchlike(realm::StringData const&, realm::StringData const&)", referenced from:
realm::StringData::like(realm::StringData) const in RLMQueryUtil.o
"realm::ArrayBinary::get(char const*, unsigned long, realm::Allocator&)", referenced from:
realm::BinaryColumn::get(unsigned long) const in collection_notifier.o
realm::BinaryColumn::get(unsigned long) const in external_commit_helper.o
realm::BinaryColumn::get(unsigned long) const in list.o
realm::BinaryColumn::get(unsigned long) const in list_notifier.o
realm::BinaryColumn::get(unsigned long) const in object.o
realm::BinaryColumn::get(unsigned long) const in object_notifier.o
realm::BinaryColumn::get(unsigned long) const in object_schema.o
...
"realm::SharedGroup::begin_read(realm::VersionID)", referenced from:
realm::_impl::RealmCoordinator::pin_version(realm::VersionID) in realm_coordinator.o
realm::_impl::RealmCoordinator::run_async_notifiers() in realm_coordinator.o
realm::_impl::RealmCoordinator::open_helper_shared_group() in realm_coordinator.o
realm::Realm::read_group() in shared_realm.o
realm::Realm::Internal::begin_read(realm::Realm&, realm::VersionID) in shared_realm.o
realm::Object realm::Realm::resolve_thread_safe_reference(realm::ThreadSafeReference) in shared_realm.o
realm::List
````

I had tried clearing derived data, cleaning your project. I'll try deintegrating and reintegrating as you suggest

Hey @jpsim - running pod deintegrate && pod install --verbose did it. Thanks!

I'm glad to hear it! Going to close this now.

Hey @jpsim - running pod deintegrate && pod install --verbose did it. Thanks!

Thank you so much!

Was this page helpful?
0 / 5 - 0 ratings