• 修改Xcode配置使其支持创建编译iphone上的dylib工程


    此帖纯粹讨论怎样更改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!!!
  • 相关阅读:
    vue-router 中 router-link 与 a 标签的区别
    html select标签 点击选中事件
    ie11卸载不了怎么办
    eclipse导入web项目及Tomcat 部署
    oracle "记录被另一个用户锁定"
    前端jinput:[DOM] Input elements should have autocomplete attributes (suggested: "current-password"): (More info: https://goo.gl/9p2vKq)
    vue 前端报:TypeError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': Value is not a valid ByteString.
    windows 环境下微信js支付 sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException
    JavaSE第25篇:枚举、XML
    JavaSE第23篇:网络编程
  • 原文地址:https://www.cnblogs.com/qq78292959/p/2076936.html
Copyright © 2020-2023  润新知