ios - mac - Evite los símbolos duplicados al crear una biblioteca estática con Cocoapods
pod init (6)
Si bien he visto muchas preguntas relacionadas con Cocoapods y las bibliotecas estáticas, la mayoría de ellas parece suponer que eventualmente tendrá un espacio de trabajo único con su biblioteca estática y la aplicación de destino final.
En mi escenario, estoy construyendo una biblioteca estática. Más específicamente, estoy pirateando un MyLib.framework para que los usuarios lo consuman. Realmente me gustaría administrar las dependencias de MyLib.framework con Cocoapods, pero crea muchos puntos problemáticos cuando los consumidores de mi biblioteca también usan Cocoapods.
Por ejemplo, mi biblioteca tiene una dependencia de AFNetworking que administro con Cocoapods. Cuando construyo mi biblioteca, enlaza con libPods.a que incluye AFNetworking, así como algunos archivos / objetos "ficticios". Si los usuarios de mi framework también usan Cocoapods para construir su aplicación, verán algo como esto:
duplicate symbol _OBJC_METACLASS_$_PodsDummy_Pods in:
/Users/erikkerber/Dropbox/Projects/MillMain/MyLib.framework/BuddySDK(Pods-dummy.o)
/Users/erikkerber/Library/Developer/Xcode/DerivedData/MillMain-fngfqhlslygksgcfuciznkpqfrbr/Build/Products/Debug-iphonesimulator/libPods.a(Pods-dummy.o)
duplicate symbol _OBJC_CLASS_$_PodsDummy_Pods in:
/Users/erikkerber/Dropbox/Projects/MillMain/MyLib.framework/BuddySDK(Pods-dummy.o)
/Users/erikkerber/Library/Developer/Xcode/DerivedData/MillMain-fngfqhlslygksgcfuciznkpqfrbr/Build/Products/Debug-iphonesimulator/libPods.a(Pods-dummy.o)
ld: 2 duplicate symbols for architecture i386
Me imagino que si agregaran una dependencia de AFNetworking, también obtendrían símbolos duplicados relacionados con AFNetworking.
También planeo distribuir MyLib con Cocoapods eventualmente, pero también quiero poder distribuir un MyLib.framework en sí mismo.
¿Hay alguna forma de utilizar Cocoapods con mi biblioteca y hacer que Cocoapods sea seguro para cualquier usuario potencial?
Con referencia de http://guides.cocoapods.org/syntax/podfile.html#post_install & http://pdx.esri.com/blog/2013/12/13/namespacing-dependencies/
Uso el enfoque ''Cambiar el nombre manualmente a todos los símbolos''. Estaba experimentando el símbolo duplicado _OBJC_METACLASS _ $ _ PodsDummy_Pods y por eso agregué y edité el post_install en el Podfile a algo así para evitar el símbolo duplicado
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings[''GCC_PREPROCESSOR_DEFINITIONS''] = ''$(inherited), PodsDummy_Pods=SomeOtherNamePodsDummy_Pods''
end
end
end
En resumen, la única forma buena de distribuir bibliotecas precompiladas es no incluir ninguna de las dependencias, pero dejar eso en manos del usuario. Es decir, en su ejemplo, le diría a sus usuarios cómo agregar también AFNetworking a su proyecto. Lo mismo se aplica básicamente con respecto a los archivos dummy
.
Habiendo dicho eso, por supuesto, podría optar por múltiples variantes precompiladas:
- Incluir todas las dependencias.
- Solo incluye la fuente de tu lib, deja las dependencias en manos del usuario.
Hemos estado hablando sobre la creación de un complemento para producir bibliotecas estáticas independientes, para el propósito que usted desea, pero aún no se ha iniciado y probablemente tomará un poco más de tiempo. (Hasta que alguien / alguien tenga tiempo.)
Como solución alternativa, puede utilizar el enlace post_install de su post_install
para eliminar todos los archivos ficticios. (de todos modos, solo se necesitan para las bibliotecas que no son de origen, como Testflight). Por ejemplo, algo como lo siguiente:
post_install do |installer|
installer.project.targets.each do |target|
source_files = target.source_build_phase.files
dummy = source_files.find do |file|
# TODO Fix this to the actual filename
# puts "File: #{file.file_ref.name}"
file.file_ref.name == ''TheDummyFile.m''
end
puts "Deleting source file #{dummy.inspect} from target #{target.inspect}."
source_files.delete(dummy)
end
end
Este es un código no probado.
El post_install
proporciona el objeto de instalación CocoaPods, desde el cual puede obtener los objetivos Pods.xcodeproj, para los cuales puede encontrar documentación here . Desde allí, puede profundizar y hacer lo que quiera en el proyecto, que se guarda en el disco después de ejecutar este gancho.
Este problema surgió cuando agregué manualmente un código externo a mi proyecto AFNetworking, por ejemplo, y luego añadí algunos pods que también lo incluían.
Simplemente eliminando AFNetworking de mi propio Proyecto (no el pod) eliminé el problema.
Si son iguales, puedes combinarlos usando:
libtool (libtool -o merged.a file1.a file2.a)
Si esto no resuelve el error, existe esta opción: http://atnan.com/blog/2012/01/12/avoiding-duplicate-symbol-errors-during-linking-by-removing-classes-from-static-libraries
Tuve el mismo problema. Gestioné las dependencias de mi biblioteca con cocoapods utilizando el siguiente formato de podfile:
platform :ios, ''6.0''
pod ''AFNetworking''
Esto resultó en un archivo Pods-dummy.o en mi archivo .a. Si luego incluí esta biblioteca en otro proyecto con el mismo formato de archivo de pod, ambos crearon un símbolo Pods-dummy.o y dieron como resultado un error de vinculador. La solución es usar un formato de podfile diferente que resulte en un símbolo simulado de Pods:
platform :ios, ''6.0''
target "MyProject" do
pod ''AFNetworking''
end
Esto da como resultado un archivo Pods-MyProject-dummy.o, que no causará símbolos duplicados.
Nota: si cambia su proyecto al uso del nuevo formato de archivo pod, asegúrese de desvincular libPods.a de su proyecto, ya que se quedará como un enlace roto porque la nueva biblioteca de pods se llama Pods-MyProject
agregue entradas para cada uno de los símbolos en conflicto a sus otros indicadores C, por ejemplo, "-DAFHTTPClient = AF2HTTPClient" Xcode múltiples bibliotecas estáticas y símbolos duplicados