2011-09-27 35 views
16

'da dylib dosyalarıyla çalışma çerçevesini nasıl oluşturabilirim? Xcode'da yeni bir kakao çerçeve oluşturdum, destekleyici dosyalar dışında baştaki tüm kitaplıkları ve dosyaları kaldırdım. inşa aşamalarındaXcode 4

add.h 

#ifndef add_add_h 
#define add_add_h 

void add(void); 

#endif 

ve

add.c 
#include <stdio.h> 
#include "add.h" 

void add(void) 
{ 
    printf("adfding"); 

} 

ben kamu başlıklarını derlemeye kaynakları ve add.h derlemeye add.c ekleyin:

Ben 2 dosya var. Proje bir sorun yaratmadan, ancak çerçeve içinde herhangi bir dylib dosyası bulunmuyor ve çerçeveyi başka bir projeye sürükleyip bıraktığımda dylib dosyasının bulunamadığını söylüyor.

dyld: Library not loaded: @rpath/add.framework/Versions/A/add 
    Referenced from: /Users/vjoukov/Desktop/Projects/test/build/Debug/test.app/Contents/MacOS/test 
    Reason: image not found 

Basit bir çerçeve nasıl yapabilirim ve içindeki dylib dosyalarını nasıl saklayabilirim?

cevap

61

Hata mesajını yanlış anladığınızı düşünüyorum.

A .framework, bir dinamik kitaplık olarak çalışır, ancak .framework klasörünün içinde gerçek bir .dylib dosya adı uzantısına sahip herhangi bir Mach-O yüklenebilir nesne dosyası olmayacaktır. Çalışma zamanında dinamik bağlantı kitaplığı yükleyicisi olan dyld'dan bu hata iletisini almanızın birkaç nedeni vardır. Birincisi, .frameworks'i, oluşturma işlemi sırasında yerleşik uygulama paketine kopyalamayı unutmanızdır. Uygulama paketindeki herhangi bir konuma kopyalanabilirken, geleneksel yer AppName.app/Contents/Frameworks/ içinde. Henüz yapmadıysanız, Proje> Yeni Yapı Aşaması> Yeni Kopya Dosyaları Oluşturma Aşaması'nı seçin. Aşağıdaki pencerede bulunan Hedef açılır pencerelerini Çerçeveler olarak değiştirin. o oluşturma işlemi sırasında kopyalanan böylece

enter image description here

Daha sonra klasöre çerçevenin simgesini sürükleyerek edeceğiz. Çerçeve zamanında bulunamayan

enter image description here

ikinci ve daha büyük olasılıkla nedeni, ana yürütülebilir için herhangi runpath arama yolları belirtilmemiş olmasıdır. (Bu, hata iletinizden gördüğümüz gibi, çerçeveniz, daha eski @executable_path/ veya @loader_path/ stillerinden daha yeni olan @rpath/ stil yükleme adı kullanılarak oluşturulmuştur, çünkü).

aşağıdaki resimde gösterildiği gibi, sen @loader_path/../Frameworks bir runpath arama yolu giriş eklemek istiyorum, yukarıda belirtilen konuma özel çerçeveler kopyalamak Sağlanan:

enter image description here

Aşağıdaki alıntıda olduğu açıklanmaktadır

dİNAMİK kÜTÜPHANE YÜKLENİYOR

: dinamik kütüphaneler zamanında bulunurlar dyld adlı kılavuz sayfasına dan

Diğer birçok işletim sisteminden farklı olarak Darwin, yaprak dosya adıyla bağımlı dinamik kütüphaneleri bulamaz. Bunun yerine, her bir dylib için tam yolu kullanılır (ör. /usr/lib/libSystem.B.dylib). Ancak tam bir yolunun uygun olmadığı zamanlar vardır; Örneğin, ikili dosyalarınızın diskte herhangi bir yere kurulabilmesi için olmasını isteyebilirsiniz. Bunu desteklemek için, yol öneki olarak kullanılabilen üç adet @xxx/ değişken vardır. Çalışma zamanında dyld , @xxx/ öneki için dinamik olarak oluşturulan bir yolun yerine geçer.

@executable_path/

Bu değişken işlemi için ana çalıştırılabilir içeren dizin yolu ile değiştirilir. Bu, bir .app dizinine gömülü yükleme dylibs/frameworks için kullanışlıdır. ana yürütülebilir dosya /some/path/My.app/Contents/MacOS/My olan ve bir çerçeve dylib dosya daha sonra çerçeve yük yolu @executable_path/../Frameworks/Foo.framework/Versions/A/Foo olarak kodlanmış olabilir
/some/path/My.app/Contents/Frameworks/Foo.framework/Versions/A/Foo, olan ve .App dizini dosya sistemi ve dyld etrafında hareket edilebilseydi gömülü çerçeveyi yüklemek için hala 'a sahip olacak.

@loader_path/

Bu değişken mach-o ikili @loader_path kullanarak yük komutu içeren içeren dizin yolu ile değiştirilir. Böylece, her ikilide, @loader_path, farklı yola gider, oysa @executable_path her zaman aynı yola gider. , bir eklentide gömülü çerçeve/dylib için yük yolu olarak yararlıdır, eklenti bilinmeyenin son dosya sistemi ise (bu nedenle mutlak yollar kullanılamaz) veya eklenti kullanılıyorsa Birden çok uygulama tarafından (bu nedenle @executable_path kullanılamaz). Plug-in makinesi-o dosyaya /some/path/Myfilter.plugin/Contents/MacOS/Myfilter olan ve bir çerçeve dylib dosyası /some/path/Myfilter.plugin/Contents/Frameworks/Foo.framework/Versions/A/Foo az ise, sonra çerçeve yük yolu @loader_path/../Frameworks/Foo.framework/Versions/A/Foo olarak kodlanabilir ve Myfilter.plugin dizin dosyasında etrafında hareket olabilir Sistem ve dyld hala gömülü çerçeveyi yükleyecektir.

@rpath/

Dyld yolların bir geçerli yığın çalıştırma yolu listesi adı tutar. @rpath ile karşılaşıldığında, varsa, yüklenebilir bir dylib bulunana kadar, çalışma yolu listesinde her bir yolunun yerine kullanılır. çalışma yolu yığını, geçerli dylib yüküne yol açan bağımlılık zincirindeki LC_RPATH yük komutlarından oluşturulur. -rpath seçeneğini ld (1) ile bir görüntüye bir LC_RPATH yükleme komutu ekleyebilirsiniz. @loader_path/ ile başlayan bir LC_RPATH yükleme komutu yolunu ekleyebilir ve LC_RPATH içeren görüntüye göre yol yığınında bir yol itecektir. @rpath kullanımı, dizin yapısına sahip olduğunuz ve herhangi bir yere yüklenebilen, ancak göreceli konumlarını koruyabilen dylibs'lerin karmaşık bir yapısına sahip olduğunuzda en kullanışlıdır. Bu senaryosu, @loader_path kullanılarak uygulanabilir, ancak dylib'in her istemcisi, dosya sistemindeki ilgili konumu farklı olduğundan farklı bir yükleme yoluna ihtiyaç duyabilir. @rpath 'un kullanımı, işleri basitleştiren bir düzeyde indirgenme seviyesi sunar. , dizin yapınızda bir bağlantı noktası olarak bir konum seçin. Her bir dylib, @rpath ile başlayan bir yükleme yolunu alır ve , bağlantı noktasını, bağlantı noktasına göre dylib yoludur. Her ana yürütülebilir dosya -rpath @loader_path/zzz ile bağlantılıdır; burada zzz, yürütülebilir dosyadan bağlantı noktasına olan yoldur. Çalışma zamanında dyld, bağlantı noktası olmak için çalışma yolunu ayarlar, sonra her bir dylib bağlantı noktasına göre bulunur.

+5

WOW! Tam bir cevabı olan bu, aynı zamanda sahip olduğum bir problemi çözdü! Teşekkürler!! –

+0

Çok kapsamlı ve eksiksiz bir cevap ... Güzel iş! –

+0

Mükemmel cevap! Dylan'ın nasıl çalıştığını asla bilemedim. Güzel! – JackPearse