FrameWork既可能是动态库,也可能是静态库,我们这里创建的是动态库。
选择FrameWork。默认创建的是Framework动态库
设置动态库名称
修改项目的iOS Deployment Target为10.0(与使用动态库项目保持一致,或者低于使用的项目)
MyFramework.h是默认生成的,会自动添加到暴露的header中,可以在内部import一些自己需要暴露使用的头文件。
创建文件,并添加想要暴露的头文件
(可选)设置动态库支持bitcode,如果不支持bitcode,使用动态库的项目就不能支持bitcode
动态库支持bitcode: https://www.jianshu.com/p/c5570751fdbc
第一步,DEPLOYMENT_POSTPROCESSING = YES
第二步,设置 STRIP_STYLE 为 Debugging Symbols(默认是)
第三步,Build Settings ->Compiler Flags添加 -fembed-bitcode 参数
第四步,确认Build Settings ->Enable Bitcode 为YES(默认是)
设置Edit Scheme的Run的build Configuration为Release,以便于打出来的framework是凳培release的。当然你也可以使用debug的进行调试。
simulator和真机的framework包如果需要进行合成一个调试包,需要去掉模拟器的arm64,因为xcode12合成的时候,会因为simulator和真机的包都包含arm64的而产生冲突。
选择任何simulator进行build,生成simulator的包,使用Any iOS Device进行build,生成真机的包。
生成之后在项目目录的products下的Myframework.framework进行Show in Finder,就可以看到生成的framework包。我们可以把两个包拷贝出来然后
两个包都可以单独进行调试,但是真机的包需要使用本地的证书进行重签名。
将两个包的可执行文件进行合成:
1>cd到你合成文件想要放置的文件夹下(避免当前文件夹下有和可执行文件名称相同的文件或者文件夹,有的话会报错)
2>终端执行命令:lipo -create sumulator的framework的可执行文件的目录 真机的framework的可执行文件的目录 -output 可执行文件名
lipo -create /Users/admin/Desktop/work/dylib/Release-iphonesimulator/MyFramework.framework/MyFramework /Users/admin/Desktop/告困work/dylib/Release-iphoneos/MyFramework.framework/MyFramework -output MyFramework
3>将生成的可执行文件替换Release-iphoneos中的MyFramework.framework下的可执行文件。MyFramework.framework则就是合袜粗念成的包。
4>对合成的包进行开发者证书(使用动态库项目的开发者证书)签名,签名之后就生成了可进行sumulator和真机调试的framework动态包。
签名方式:重新打开终端输入/usr/bin/security find-identity -v -p codesigning 列出电脑上可用的签名,cd到XX.framework所在的目录,然后codesign -fs "Apple Development: xxxx (XXXX)" xx.framework进行签名。
注意:打包测试或者发布的时候是直接使用没有签名过的真机的framework,xcode会自动进行签名。
项目使用动态库framework
把动态库添加到项目,然后在Build Phases的Copy Bundle Resources中添加动态库,这样动态库在打包的时候可以打包到bundle中。Link Binary Libraries如果添加了的话,动态库在程序运行的时候就会自动动态加载,可以直接使用,如果没有添加,则需要我们使用loadAndReturnError或者dlopen(私有api不能上线使用)进行加载,加载成功之后进行使用。
动态加载库方式:
1> Build Phases的Copy Bundle Resources中添加动态库,Link Binary Libraries删掉动态库。如果Link Binary Libraries需要链接的话需要在Build Settings->Links->Runpath Search Paths中添加@executable_path/
2>使用
如果重复添加动态库,则后面添加的动态库失效。
如果framework中使用到了Category那么在使用framework的工程中要设置Build Settings中的Other Link Flag为-ObjC或者-all_load
先说明下”all:“和”clean:“。这两个语句类似于:if (arg=="all") then.... 和 if (arg=="clean") then...也就是说,如果你执行make all,all后面的语句就会被执行。
如果make clean,clean后面的语句就会被执行。
另外,all和clean后面的语句应该都是要缩进的。
EXEC = hello // 生成的可执行文件名为hello
OBJS = hello.o // 编译产生的仔橘中间文件名为hello.o
CROSS= iwmmxt_le- //设置iwmmxt_Ie-为交叉编空和译环境
CC = $(CROSS)gcc // 编译器是gcc
STRIP= $(CROSS)strip // 设置优化器斗戚盯(用来删除debug信息)
CFLAGS = -Wall -g -O2 // 设置编译选项
all: clean $(EXEC) // 如果是make all,先掉用下clean后面的指令,再执行自己下面的指令
$(EXEC):$(OBJS) // 创建依赖关系。这里表示hello依赖于hello.o。也就是说,先产生hello.o再产生hello
$(CC) $(CFLAGS) -o $@ $(OBJS) // 编译
$(STRIP) $@ // 删除debug信息
clean: // make clean就会来这里
-rm -f $(EXEC) *.o // 删除产生的中间文件
C++#ifndef与#ifdef的区别是什么? #ifndef 表示如果没有定义宏 则条件成立,如:#ifndef EXTERNchar globle_str[100]#elseextern char globle_str[]#endif如果没有定义宏 EXTERN 则定义一个变量char globle_str[100] 否则,引用声明该变量extern char globle_str[]把这个信息写入一个头文件,如:globe.h,可在多个源代码中引用这个头文件。源文件中,如果加了#define EXTERN,则在编译时,就会调用extern char globle_str[]进行编译,如果没有加,就会调用char globle_str[100]
#ifdef 表示如果定义了宏 则条件成立,如,上面的例子,可改写成:
#ifdef EXTERNextern char globle_str[]#elsechar globle_str[100]#endif如果定义了宏 EXTERN 则引用声明变量extern char globle_str[]否则,定义一个变量char globle_str[100]
相关代码引用:
globe.h: 如上面内容
out.c:
#define EXTERN定义宏EXTERN后引用头文件globe.h#include "globe.h" #include <stdio.h>void output(){puts(globe_str)}
main.c:
这里没有定义EXTERN#include "globe.h" void output()int main(){sprintf( globe_str, "hello world") output() return 0}
C++中if、#if与#ifdef、#ifndef彼此的区别
以#开头的都是预编译指令,就是在正式编译之前,编译器做一些预处理的工作
#if 条件语颤粗句
程序段1 如果条件语句成立,那么就编译程改洞笑序段1
#endif
程序段2如果条件不语句成立,那么就编译程序段2
#ifndef x先测试x是否被宏定义过
#define 程序段1 如果x没有被宏定义过,那么就编译程序段1
#endif
程序段2 如果x已经定义过了则编译程序段2的语句,“忽视”程序段1。
#ifdef x 先测试x是否被宏定义过
程序段1 如果x被宏定义过,那么就编译程序段1
#endif
程序段2 如果x没有被定义过则编译程序段2的语句,“忽视”程序段1。
if就是判断语句,不是预编译指令
makefile中ifeq,ifneq,ifdef和ifndef的区别与用法
1,Makefile中的ifeq:ifeq($(ABC), XXX) CFLAGS += -DABC endif 注意: 逗号和xxx之间必须有一个空格 更需要注意的是: ifeq中的XXX后面不能带空格,如果XXX后面带了一个空格,那空格和XXX会被认为是一个整体 export ABC = XXX[ ][ ] 这里用【】表示一核含个空格 那么 ifeq($(ABC), XXX ...
2,Makefile中四种变量赋值的区别:Ask: What is the difference beeen : VARIABLE = value VARIABLE ?= value VARIABLE := value VARIABLE += value I have read the section in GNU Make's manual, but it still doesn't ...
3,,Makefile 中:= ?= += =的区别:在Makefile中我们经常看到 = := ?= +=这几个赋值运算符,那么他们有什么区别呢?我们来做个简单的实验 新建一个Makefile,内容为:ifdef DEFINE_VREVRE = “Hello Wo ...
,4,zz makefile中=和:=的区别:在Makefile中我们经常看到 = := ?= +=这几个赋值运算符,那么他们有什么区别呢?我们来做个简单的实验 新建一个Makefile,内容为:ifdef DEFINE_VREVRE = “Hello W ...
,5,嵌入式 Makefile中:=与=与+=与=的区别$@,$^,$<区别:在Makefile中我们经常看到 = := ?= +=这几个赋值运算符,那么他们有什么区别呢?我们来做个简单的实验 新建一个Makefile,内容为: ifdef DEFINE_VRE VRE = "HelloWorld!" else endif ifeq ($(OPT),define) VRE ?="Hello 。
makefile中ifeq,ifneq,ifdef和ifndef的区别与用法
使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支。条件表达式可以是比较变量的值,或是比较变量和常量的值。
一、示例
下面的例子,判断$(CC)变量是否“g”,如果是的话,则使用GNU函数编译目标。
libs_for_g = -lgnu
normal_libs =
foo: $(objects)
ifeq ($(CC),g)
$(CC) -o foo $(objects) $(libs_for_g)
else
$(CC) -o foo $(objects) $(normal_libs)
endif
可见,在上面示例的这个规则中,目标“foo”可以根据变量“$(CC)”值来选取不同的函数库来编译程序。
我们可以从上面的示例中看到三个关键字:ifeq、else和endif。ifeq的意思表示条件语句的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括起。else表示条件表达式为假的情况。endif表示一个条件语句的结束,任何一个条件表达式都应该以endif结束。
当我们的变量$(CC)值是“g”时,目标foo的规则是:
foo: $(objects)
$(CC) -o foo $(objects) $(libs_for_g)
而当我们的变量$(CC)值不是“g”时(比如“”),目标foo的规则是:
foo: $(objects)
$(CC) -o foo $(objects) $(normal_libs)
当然,我们还可以把上面的那个例子写得更简洁一些:
libs_for_g = -lgnu
normal_libs =
ifeq ($(CC),g)
libs=$(libs_for_g)
else
libs=$(normal_libs)
endif
foo: $(objects)
$(CC) -o foo $(objects) $(libs)
二、语法
条件表达式的语法为:
<conditional-directive>
<text-if-true>
endif
以及:
<conditional-directive>
<text-if-true>
else
<text-if-false>
endif
其中<conditional-directive>表示条件关键字,如“ifeq”。这个关键字有四个。
第一个是我们前面所见过的“ifeq”
ifeq (<arg1>, <arg2>)
ifeq '<arg1>' '<arg2>'
ifeq "<arg1>" "<arg2>"
ifeq "<arg1>" '<arg2>'
ifeq '<arg1>' "<arg2>"
比较参数“arg1”和“arg2”的值是否相同。当然,参数中我们还可以使用make的函数。如:
ifeq ($(strip $(foo)),)
<text-if-empty>
endif
这个示例中使用了“strip”函数,如果这个函数的返回值是空(Empty),那么<text-if-empty>就生效。
第二个条件关键字是“ifneq”。语法是:
ifneq (<arg1>, <arg2>)
ifneq '<arg1>' '<arg2>'
ifneq "<arg1>" "<arg2>"
ifneq "<arg1>" '<arg2>'
ifneq '<arg1>' "<arg2>"
其比较参数“arg1”和“arg2”的值是否相同,如果不同,则为真。和“ifeq”类似。
第三个条件关键字是“ifdef”。语法是:
ifdef <variable-name>
如果变量<variable-name>的值非空,那到表达式为真。否则,表达式为假。当然,<variable-name>同样可以是一个函数的返回值。注意,ifdef只是测试一个变量是否有值,其并不会把变量扩展到当前位置。还是来看两个例子:
示例一:
bar =
foo = $(bar)
ifdef foo
frobozz = yes
else
frobozz = no
endif
示例二:
foo =
ifdef foo
frobozz = yes
else
frobozz = no
endif
第一个例子中,“$(frobozz)”值是“yes”,第二个则是“no”。
第四个条件关键字是“ifndef”。其语法是:
ifndef <variable-name>
这个就不多说了,和“ifdef”是相反的意思。
在<conditional-directive>这一行上,多余的空格是被允许的,但是不能以[Tab]键做为开始(不然就被认为是命令)。而注释符“#”同样也是安全的。“else”和“endif”也一样,只要不是以[Tab]键开始就行了。
特别注意的是,make是在读取Makefile时就计算条件表达式的值,并根据条件表达式的值来选择语句,所以,最好不要把自动化变量(如“$@”等)放入条件表达式中,因为自动化变量是在运行时才有的。
而且,为了避免混乱,make不允许把整个条件语句分成两部分放在不同的文件中。
C++中*与*&的区别是什么
*是取值运算符,对地址使用可以获得地址中储存的数值;&是地址运算符,对变量使用可以获得该变量的地址。恩,简单说就是这样,有疑问请继续追问。。。
C++中,break与return的区别是什么?
最本质的区别:
break是用来跳出循环的,例如for,while,do-while都可以跳出,但不跳出函数
return是使整个函数返回的,后面的不管是循环里面还是循环外面的都不执行
再说一下,break语句通常用在循环语句和开关语句中,当break语句用于do-while、for、while循环语句中时,可使程序终止循环而执行循环后面的语句, 通常break语句总是与if语句联在一起,即满足条件时便跳出循环
return语句是将函数的值返回主调函数。
还有一个continue语句的作用是跳过循环本中剩余的语句而强行执行下一次循环。continue语句只用在for、while、do-while等循环体中,常与if条件语句一起使用,用来加速循环
c++==========getparent与afxgetmainwnd的区别是什么。
GetParent获得是父窗口指针(一般是CFrameWnd*主窗口指针)。但是GetParent获得上级父窗口指针,他不一定是主窗口。 GetParent()是获得父窗体的cwnd 而对话框的父窗体不一定mainWnd
AfxGetMainWnd获取自身窗口句柄。
如果你的应用程序是一个OLE服务器,应该调用这个函数以获得应用程序的活动主窗口指针,而不是直接引用应用程序对象的m_pMainWnd成员。
如果你的应用程序不是OLE服务器,那么调用这个函数与直接引用应用程序对象的m_pMainWnd成员是等价的。
注意:如果AfxGetMainWnd被应用程序主线程调用,它返回应用程序的主窗口。如果该函数被应用程序的次线程调用,该函数返回与引起该调用线程连接的主窗口。
赛扬C与D的区别是什么?
赛扬没有C只有赛扬4跟赛扬D之分,赛扬4是100MHz外频、FSB400MHz。赛扬D是133MHz外频、FSB533MHz。赛扬D420之后的所有赛扬就是core核心的了,跟以前的半点关系都没了。
C++中::Vac与Vac的区别是什么?
Vac前面的两个冒号(::)是全局作用域解析符, 用来表示内部函数里的全局变量
举个例子来说吧
==========================
#include<iostream>
using namespace std
int Vac = 0全局的Vac
int main(int argc, char *argv[])
{
int Vac = 1局部的Vac
cout <<::Vac <<" \n" <<Vac <<"\n"
return 0
}
===========
::Vac 表示的是那个全局的Vac
Vac表示的是局部的那个
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)