| 此帖純粹討論怎樣更改xcode配置來使其支援建立iphone上的dylib工程檔案,不涉及任何其他破解話題! 測試機器:10.6 with Xcode3.2 最近在研究如何建立iphone上的dylib檔案,google出來的都是toolchain的東西,使用makefile來編譯的,像我這種習慣IDE的人來說非常之不爽,所以花了一天時間來破解了下Xcode來讓它可以建立編譯iphone上的dylib檔案的工程。 簡單說下分析思路吧 首先xcode支援建立iphone static libtary和Cocoa的dynamic linrary的工程,通過不同編譯對比可以發現Xcode通過productType = "com.apple.product-type.library.dynamic";配置來確定工程類型的。 開啟**.xcodeproj/project.pbxproj檔案,搜尋productType=定位,可以發現如所示的內容 [attachment=10545] 可以建立一個iphone的static工程把static改成dynamic編譯看看,可以發現xcode提示不支援dynamic類型的工程,無法編譯,那我們讓他支援就好了。 我們需要修改以下檔案 /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/iPhoneOSProductTypes.xcspec /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Specifications/iPhoneOSPackageTypes.xcspec 在iPhoneOSProductTypes.xcspec中添加下列片段 // Dynamic library { Type = ProductType; Identifier = com.apple.product-type.library.dynamic; Class = PBXStaticLibraryProductType; Name = "Dynamic Library"; Description = "Dynamic library"; IconNamePrefix = "TargetLibrary"; DefaultTargetName = "Dynamic Library"; DefaultBuildProperties = { FULL_PRODUCT_NAME = "$(EXECUTABLE_NAME)"; MACH_O_TYPE = "mh_dylib"; REZ_EXECUTABLE = YES; EXECUTABLE_PREFIX = ""; EXECUTABLE_SUFFIX = ".$(EXECUTABLE_EXTENSION)"; EXECUTABLE_EXTENSION = "dylib"; PUBLIC_HEADERS_FOLDER_PATH = "/usr/local/include"; PRIVATE_HEADERS_FOLDER_PATH = "/usr/local/include"; INSTALL_PATH = "/usr/local/lib"; DYLIB_INSTALL_NAME_BASE = "$(INSTALL_PATH)"; LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)"; DYLIB_COMPATIBILITY_VERSION = "1"; DYLIB_CURRENT_VERSION = "1"; FRAMEWORK_FLAG_PREFIX = "-framework"; LIBRARY_FLAG_PREFIX = "-l"; LIBRARY_FLAG_NOSPACE = YES; STRIP_STYLE = "debugging"; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; CODE_SIGNING_ALLOWED = NO; }; PackageTypes = ( com.apple.package-type.mach-o-library // default ); }, 在iPhoneOSPackageTypes.xcspec中添加下列片段 // Mach-O dynamic library { Type = PackageType; Identifier = com.apple.package-type.mach-o-library; Name = "Mach-O Dynamic Library"; Description = "Mach-O dynamic library"; DefaultBuildSettings = { EXECUTABLE_PREFIX = ""; EXECUTABLE_SUFFIX = ".dylib"; EXECUTABLE_NAME = "$(EXECUTABLE_PREFIX)$(PRODUCT_NAME)$(EXECUTABLE_VARIANT_SUFFIX)$(EXECUTABLE_SUFFIX)"; EXECUTABLE_PATH = "$(EXECUTABLE_NAME)"; }; ProductReference = { FileType = compiled.mach-o.dylib; Name = "$(EXECUTABLE_NAME)"; IsLaunchable = NO; }; }, 檔案附上,可以直接下載替換,替換/修改前做好備份 [attachment=10546] 現在再編譯應該不會提示工程不支援了,那麼剩下的就是改變其編譯選項了,就是libtool的參數問題。 我們需要修改下列檔案 /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/Contents/Resources/Libtool.xcspec /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS Build System Support.xcplugin/Contents/Resources/iPhoneLinkerOptions.xcspec 在Libtool.xcspec中添加下列片段 { Identifier = com.apple.pbx.linkers.libtooldynamic; Type = Linker; Class = PBXLinkerSpecificationLibtool; Name = "Libtool"; Description = "Create a dynamic library using Apple Mach-O Librarian (libtool)"; IsAbstract = Yes; // This is an internal tool, so we keep it out of the user interface BinaryFormats = (mach-o); Architectures = (ppc, ppc7400, ppc7450, ppc970, ppc64, i386, x86_64); CommandLine = "$(LIBTOOL) -dynamic -arch_only $(arch) -compatibility_version $(DYLIB_COMPATIBILITY_VERSION) -current_version $(DYLIB_CURRENT_VERSION) [options] [special-args] -o $(OutputPath)"; // 'special-args' includes the input files RuleName = "Libtool $(OutputPath) $(variant) $(arch)"; ExecDescription = "Create Dynamic Library $(OutputPath:file)"; InputFileTypes = ( compiled.mach-o.objfile ); Outputs = ( // We're a linker-like task, so we expect to be given an output path in 'OutputPath'. "$(OutputPath)" ); CommandOutputParser = XCGccCommandOutputParser; Options = ( // LIBTOOL { Name = LIBTOOL; Type = Path; DefaultValue = "$(PLATFORM_DEVELOPER_BIN_DIR)/libtool"; }, // SDK { Name = SDKROOT; Type = Path; CommandLineFlag = "-syslibroot"; IsInputDependency = Yes; }, // Search paths { Name = LIBRARY_SEARCH_PATHS; Type = PathList; FlattenRecursiveSearchPathsInValue = Yes; // causes any paths that have a '/**' suffix to be replaced with matching paths CommandLinePrefixFlag = "-L"; }, // Input file lists { Name = __INPUT_FILE_LIST_PATH__; Type = Path; DefaultValue = "$(LINK_FILE_LIST_$(variant)_$(arch))"; // this is set up for us as a read-only property CommandLineFlag = "-filelist"; IsInputDependency = Yes; }, { Name = auxiliary_file_lists; Type = PathList; CommandLineFlag = "-filelist"; IsInputDependency = Yes; }, // Various flags { Name = ALL_OTHER_LIBTOOLFLAGS; Type = StringList; DefaultValue = "$(LD_FLAGS) $(SECTORDER_FLAGS) $(OTHER_LDFLAGS) $(OTHER_LDFLAGS_$(variant)) $(OTHER_LDFLAGS_$(arch)) $(OTHER_LDFLAGS_$(variant)_$(arch)) $(OTHER_LIBTOOLFLAGS) $(OTHER_LIBTOOLFLAGS_$(variant)) $(OTHER_LIBTOOLFLAGS_$(arch)) $(OTHER_LIBTOOLFLAGS_$(variant)_$(arch)) $(PRODUCT_SPECIFIC_LIBTOOLFLAGS)"; CommandLinePrefixFlag = ""; }, { Name = EXPORTED_SYMBOLS_FILE; Type = Path; Condition = "$(SEPARATE_SYMBOL_EDIT) == NO"; CommandLineFlag = "-exported_symbols_list"; IsInputDependency = Yes; }, { Name = UNEXPORTED_SYMBOLS_FILE; Type = Path; Condition = "$(SEPARATE_SYMBOL_EDIT) == NO"; CommandLineFlag = "-unexported_symbols_list"; IsInputDependency = Yes; }, { Name = AdditionalCommandLineArguments; Type = StringList; CommandLinePrefixFlag = ""; }, { Name = MACOSX_DEPLOYMENT_TARGET; Type = String; SetValueInEnvironmentVariable = "MACOSX_DEPLOYMENT_TARGET"; }, ); }, 在iPhoneLinkerOptions.xcspec中搜尋 BasedOn = "default:com.apple.pbx.linkers.libtool"; 替換成 BasedOn = "default:com.apple.pbx.linkers.libtooldynamic"; 這樣修改後編譯iphone的library工程師都會使用dynamic的參數來編譯, 注意:如果要編譯iphone static library這裡需要將libtooldynamic修改回libtool並重啟Xcode(唯一的小缺陷,應該可以通過hook xcode編譯設定函數來動態修改,很麻煩,需要很多時間去找到相應的方法,找了一會兒就沒高興繼續,先將就用吧) 做好以上工作後就可以建立並編譯iphone上dynamic library的工程了。 這裡附上工程和target模板檔案 [attachment=10547] 解壓此zip得到Cocoa Touch Dynamic Library檔案夾,將其放到 /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Project Templates/Library/下面 [attachment=10548] 解壓此zip得到Dynamic Library.trgttmpl檔案,將其放到 /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Target Templates/Cocoa Touch/下面 重啟Xcode就可以看到了, [attachment=10549] [attachment=10550] 測試結果 [attachment=10551] 使用otool查看編譯出來的dylib檔案 [attachment=10552] 成功! 謹記!!!!!需要修改檔案來切換回編譯static library!!! |