修改Xcode配置并支持iPhone上dylib工程 實(shí)例
修改Xcode配置并支持iPhone上dylib工程是本文要介紹的內(nèi)容,逛壇子發(fā)現(xiàn)一篇好文章,與大家分享一下,先來(lái)看內(nèi)容。此帖純粹討論怎樣更改xcode配置來(lái)使其支持創(chuàng)建iphone上的dylib工程文件,不涉及任何其他破解話(huà)題!
測(cè)試機(jī)器:10.6 with Xcode3.2
最近在研究如何創(chuàng)建iphone上的dylib文件,google出來(lái)的都是toolchain的東西,使用makefile來(lái)編譯的,像我這種習(xí)慣IDE的人來(lái)說(shuō)非常之不爽,所以花了一天時(shí)間來(lái)破解了下Xcode來(lái)讓它可以創(chuàng)建編譯iphone上的dylib文件的工程。
簡(jiǎn)單說(shuō)下分析思路吧
首先xcode支持創(chuàng)建iphone static libtary和Cocoa的dynamic linrary的工程,通過(guò)不同編譯對(duì)比可以發(fā)現(xiàn)Xcode通過(guò)productType = "com.apple.product-type.library.dynamic";配置來(lái)確定工程類(lèi)型的。
打開(kāi)**.xcodeproj/project.pbxproj文件,搜索productType=定位,可以發(fā)現(xiàn)如下圖所示的內(nèi)容
[attachment=10545]
可以創(chuàng)建一個(gè)iphone的static工程把static改成dynamic編譯看看,可以發(fā)現(xiàn)xcode提示不支持dynamic類(lèi)型的工程,無(wú)法編譯,那我們讓他支持就好了。
我們需要修改以下文件
- /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]
現(xiàn)在再編譯應(yīng)該不會(huì)提示工程不支持了,那么剩下的就是改變其編譯選項(xiàng)了,就是libtool的參數(shù)問(wèn)題。
我們需要修改下列文件
- /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工程師都會(huì)使用dynamic的參數(shù)來(lái)編譯,
注意:如果要編譯iphone static library這里需要將libtooldynamic修改回libtool并重啟Xcode(***的小缺陷,應(yīng)該可以通過(guò)hook xcode編譯設(shè)置函數(shù)來(lái)動(dòng)態(tài)修改,很麻煩,需要很多時(shí)間去找到相應(yīng)的方法,找了一會(huì)兒就沒(méi)高興繼續(xù),先將就用吧)
做好以上工作后就可以創(chuàng)建并編譯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]
測(cè)試結(jié)果
- [attachment=10551]
使用otool查看編譯出來(lái)的dylib文件
- [attachment=10552]
成功!
謹(jǐn)記?。。。?!需要修改文件來(lái)切換回編譯static library?。?!
小結(jié):關(guān)于修改Xcode配置并支持iPhone上dylib工程的內(nèi)容介紹完了,希望本文對(duì)你有所幫助,更多相關(guān)內(nèi)容請(qǐng)參考便捷而推薦。