1.Opencv源码交叉编译Android库
2.Flutter(å)ä¹Flutterçå¸å±Widget
3.Nginx源码交叉编译-保姆级移植ARM
4.ITX-RK3588J上固件与驱动的无源交叉编译与烧写流程概述
5.怎么做数据分析(做数据分析的软件)
6.说人话——啥是交叉编译
Opencv源码交叉编译Android库
本文主要介绍了如何在Android平台上进行OpenCV(版本2.4.)的源码交叉编译,并将其集成到Android应用中。码交首先,叉图你需要确保已下载并配置好NDK(yourNDKPath),用无源码以及指定编译文件的交叉存放路径(yourInstallPath)。在OpenCV根目录下,图用spring项目实战源码运行特定命令开始编译过程,无源这将生成所需的码交头文件、静态库和动态库。叉图
接下来,用无源码你需要在你的交叉项目中引入编译好的OpenCV库。这包括在CMakeLists.txt文件中配置工程,图用以便正确链接OpenCV库。无源完成配置后,码交进行工程的叉图编译,确保所有的依赖项都已正确集成。
在Android设备上进行测试时,将编译的可执行文件与文件一起推送至设备,然后在终端执行程序。执行过程会输出相关结果。
总结来说,将标准编译工具链替换为NDK提供的交叉编译工具链是关键步骤。整个过程虽然需要一些设置,但一旦理清流程,实际操作并不复杂。有兴趣的开发者可以参考GitHub上的相关代码,通过star来表示支持。
Flutter(å)ä¹Flutterçå¸å±Widget
ä¸.ååå¸å±ç»ä»¶
ååå¸å±ç»ä»¶çå«ä¹æ¯å ¶åªæä¸ä¸ªåç»ä»¶ï¼å¯ä»¥éè¿è®¾ç½®ä¸äºå±æ§è®¾ç½®è¯¥åç»ä»¶æå¨çä½ç½®ä¿¡æ¯çã
æ¯è¾å¸¸ç¨çååå¸å±ç»ä»¶æï¼AlignãCenterãPaddingãContainerã
1.1.Alignç»ä»¶1.1.1.Alignä»ç»çå°Alignè¿ä¸ªè¯ï¼æ们就ç¥éå®ææ们ç对é½æ¹å¼æå ³ã
å¨å ¶ä»ç«¯çå¼åä¸ï¼iOSãAndroidãå端ï¼Aligné常åªæ¯ä¸ä¸ªå±æ§èå·²ï¼ä½æ¯Flutterä¸Alignä¹æ¯ä¸ä¸ªç»ä»¶ã
æ们å¯ä»¥éè¿æºç æ¥çä¸ä¸Alignæåªäºå±æ§ï¼
constAlign({ Keykey,this.alignment:Alignment.center,//对é½æ¹å¼ï¼é»è®¤å± ä¸å¯¹é½this.widthFactor,//宽度å åï¼ä¸è®¾ç½®çæ åµï¼ä¼å°½å¯è½å¤§this.heightFactor,//é«åº¦å åï¼ä¸è®¾ç½®çæ åµï¼ä¼å°½å¯è½å¤§Widgetchild//è¦å¸å±çåWidget})è¿éæ们ç¹å«è§£éä¸ä¸widthFactoråheightFactorä½ç¨ï¼
å 为åç»ä»¶å¨ç¶ç»ä»¶ä¸ç对é½æ¹å¼å¿ é¡»æä¸ä¸ªåæï¼å°±æ¯ç¶ç»ä»¶å¾ç¥éèªå·±çèå´ï¼å®½åº¦åé«åº¦ï¼ï¼
å¦æwidthFactoråheightFactorä¸è®¾ç½®ï¼é£ä¹é»è®¤Alignä¼å°½å¯è½ç大ï¼å°½å¯è½å æ®èªå·±æå¨çç¶ç»ä»¶ï¼ï¼
æ们ä¹å¯ä»¥å¯¹ä»ä»¬è¿è¡è®¾ç½®ï¼æ¯å¦widthFactor设置为3ï¼é£ä¹ç¸å¯¹äºAlignç宽度æ¯åç»ä»¶è·¨åº¦ç3åï¼
1.1.2.Alignæ¼ç»æ们ç®åæ¼ç»ä¸ä¸Align:
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}1.2.Centerç»ä»¶1.2.1.Centerä»ç»Centerç»ä»¶æ们å¨åé¢å·²ç»ç¨è¿å¾å¤æ¬¡äºã
äºå®ä¸Centerç»ä»¶ç»§æ¿èªAlignï¼åªæ¯å°alignment设置为Alignment.centerã
æºç åæï¼
classCenterextendsAlign{ constCenter({ Keykey,doublewidthFactor,doubleheightFactor,Widgetchild}):super(key:key,widthFactor:widthFactor,heightFactor:heightFactor,child:child);}1.2.2.Centeræ¼ç»æ们å°ä¸é¢ç代ç Alignæ¢æCenter
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnCenter(child:Icon(Icons.pets,size:,color:Colors.red),widthFactor:3,heightFactor:3,);}}1.3.Paddingç»ä»¶1.3.1.Paddingä»ç»Paddingç»ä»¶å¨å ¶ä»ç«¯ä¹æ¯ä¸ä¸ªå±æ§èå·²ï¼ä½æ¯å¨Flutterä¸æ¯ä¸ä¸ªWidgetï¼ä½æ¯Flutterä¸æ²¡æMarginè¿æ ·ä¸ä¸ªWidgetï¼è¿æ¯å 为å¤è¾¹è·ä¹å¯ä»¥éè¿Paddingæ¥å®æã
Paddingé常ç¨äºè®¾ç½®åWidgetå°ç¶Widgetçè¾¹è·ï¼ä½ å¯ä»¥ç§°ä¹ä¸ºæ¯ç¶ç»ä»¶çå è¾¹è·æåWidgetçå¤è¾¹è·ï¼ã
æºç åæï¼
constPadding({ Keykey,@requiredthis.padding,//EdgeInsetsGeometryç±»åï¼æ½è±¡ç±»ï¼ï¼ä½¿ç¨EdgeInsetsWidgetchild,})1.3.2.Paddingæ¼ç»ä»£ç æ¼ç»ï¼
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnPadding(padding:EdgeInsets.all(),child:Text("è«å¬ç©¿ææå¶å£°ï¼ä½å¦¨åå¸ä¸å¾è¡ã竹æèéè½»è马ï¼è°æï¼ä¸èçé¨ä»»å¹³çã",style:TextStyle(color:Colors.redAccent,fontSize:),),);}}1.4.Containerç»ä»¶Containerç»ä»¶ç±»ä¼¼äºå ¶ä»Androidä¸çViewï¼iOSä¸çUIViewã
å¦æä½ éè¦ä¸ä¸ªè§å¾ï¼æä¸ä¸ªèæ¯é¢è²ãå¾åãæåºå®ç尺寸ãéè¦ä¸ä¸ªè¾¹æ¡ãåè§çææï¼é£ä¹å°±å¯ä»¥ä½¿ç¨Containerç»ä»¶ã
.1.Containerä»ç»Containerå¨å¼åä¸è¢«ä½¿ç¨çé¢çæ¯é常é«çï¼ç¹å«æ¯æ们ç»å¸¸ä¼å°å ¶ä½ä¸ºå®¹å¨ç»ä»¶ã
ä¸é¢æ们æ¥çä¸ä¸Containeræåªäºå±æ§ï¼
Container({ this.alignment,this.padding,//容å¨å è¡¥ç½ï¼å±äºdecorationçè£ é¥°èå´Colorcolor,//èæ¯è²Decorationdecoration,//èæ¯è£ 饰DecorationforegroundDecoration,//åæ¯è£ 饰doublewidth,//容å¨ç宽度doubleheight,//容å¨çé«åº¦BoxConstraintsconstraints,//容å¨å¤§å°çéå¶æ¡ä»¶this.margin,//容å¨å¤è¡¥ç½ï¼ä¸å±äºdecorationçè£ é¥°èå´this.transform,//åæ¢this.child,})大å¤æ°å±æ§å¨ä»ç»å ¶å®å®¹å¨æ¶é½å·²ç»ä»ç»è¿äºï¼ä¸åèµè¿°ï¼ä½æ两ç¹éè¦è¯´æï¼
容å¨ç大å°å¯ä»¥éè¿widthãheightå±æ§æ¥æå®ï¼ä¹å¯ä»¥éè¿constraintsæ¥æå®ï¼å¦æåæ¶åå¨æ¶ï¼widthãheightä¼å ãå®é ä¸Containerå é¨ä¼æ ¹æ®widthãheightæ¥çæä¸ä¸ªconstraintsï¼
colorådecorationæ¯äºæ¥çï¼å®é ä¸ï¼å½æå®coloræ¶ï¼Containerå ä¼èªå¨å建ä¸ä¸ªdecorationï¼
decorationå±æ§ç¨åæ们详ç»å¦ä¹ ï¼
1.4.2.Containeræ¼ç»ç®åè¿è¡ä¸ä¸ªæ¼ç¤ºï¼
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnCenter(child:Container(color:Color.fromRGBO(3,3,,.5),width:,height:,child:Icon(Icons.pets,size:,color:Colors.white),),);}}1.4.3.BoxDecorationContaineræä¸ä¸ªé常éè¦çå±æ§decorationï¼
ä»å¯¹åºçç±»åæ¯Decorationç±»åï¼ä½æ¯å®æ¯ä¸ä¸ªæ½è±¡ç±»ã
å¨å¼åä¸ï¼æ们ç»å¸¸ä½¿ç¨å®çå®ç°ç±»BoxDecorationæ¥è¿è¡å®ä¾åã
BoxDecoration常è§å±æ§ï¼
constBoxDecoration({ this.color,//é¢è²ï¼ä¼åContainerä¸çcolorå±æ§å²çªthis.image,//èæ¯å¾çthis.border,//è¾¹æ¡ï¼å¯¹åºç±»åæ¯Borderç±»åï¼éé¢æ¯ä¸ä¸ªè¾¹æ¡ä½¿ç¨BorderSidethis.borderRadius,//åè§ææthis.boxShadow,//é´å½±ææthis.gradient,//æ¸åææthis.backgroundBlendMode,//èæ¯æ··åthis.shape=BoxShape.rectangle,//å½¢å})é¨åæææ¼ç¤ºï¼
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnCenter(child:Container(//color:Color.fromRGBO(3,3,,.5),width:,height:,child:Icon(Icons.pets,size:,color:Colors.white),decoration:BoxDecoration(color:Colors.amber,//èæ¯é¢è²border:Border.all(color:Colors.redAccent,width:3,style:BorderStyle.solid),//è¿éä¹å¯ä»¥ä½¿ç¨Border.allç»ä¸è®¾ç½®//top:BorderSide(//color:Colors.redAccent,//width:3,//style:BorderStyle.solid//),borderRadius:BorderRadius.circular(),//è¿éä¹å¯ä»¥ä½¿ç¨.onlyåå«è®¾ç½®boxShadow:[BoxShadow(offset:Offset(5,5),color:Colors.purple,blurRadius:5)],//shape:BoxShape.circle,//ä¼åborderRadiuså²çªgradient:LinearGradient(colors:[Colors.green,Colors.red])),),);}}1.4.4.å®ç°åè§å¾åä¸ä¸ä¸ªç« èæ们æå°å¯ä»¥éè¿Container+BoxDecorationæ¥å®ç°åè§å¾åã
å®ç°ä»£ç å¦ä¸ï¼
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}0äº.å¤åå¸å±ç»ä»¶å¨å¼åä¸ï¼æ们ç»å¸¸éè¦å°å¤ä¸ªWidgetæ¾å¨ä¸èµ·è¿è¡å¸å±ï¼æ¯å¦æ°´å¹³æ¹åãåç´æ¹åæåï¼çè³ææ¶åéè¦ä»ä»¬è¿è¡å±å ï¼æ¯å¦å¾çä¸é¢æ¾ä¸æ®µæåçï¼
è¿ä¸ªæ¶åæ们éè¦ä½¿ç¨å¤åå¸å±ç»ä»¶ï¼Multi-childlayoutwidgetsï¼ã
æ¯è¾å¸¸ç¨çå¤åå¸å±ç»ä»¶æ¯RowãColumnãStackï¼æ们æ¥å¦ä¹ ä¸ä¸ä»ä»¬ç使ç¨ã
2.1.Flexç»ä»¶äºå®ä¸ï¼æ们å³å°å¦ä¹ çRowç»ä»¶åColumnç»ä»¶é½ç»§æ¿èªFlexç»ä»¶ã
Flexç»ä»¶åRowãColumnå±æ§ä¸»è¦çåºå«å°±æ¯å¤ä¸ä¸ªdirectionã
å½directionçå¼ä¸ºAxis.horizontalçæ¶åï¼åæ¯Rowã
å½directionçå¼ä¸ºAxis.verticalçæ¶åï¼åæ¯Columnã
å¨å¦ä¹ RowåColumnä¹åï¼æ们å å¦ä¹ 主轴å交åè½´çæ¦å¿µã
å 为Rowæ¯ä¸è¡æå¸ï¼Columnæ¯ä¸åæå¸ï¼é£ä¹å®ä»¬é½åå¨ä¸¤ä¸ªæ¹åï¼å¹¶ä¸ä¸¤ä¸ªWidgetæåçæ¹ååºè¯¥æ¯å¯¹ç«çã
å®ä»¬ä¹ä¸é½æ主轴ï¼MainAxisï¼å交åè½´ï¼CrossAxisï¼çæ¦å¿µï¼
对äºRowæ¥è¯´ï¼ä¸»è½´ï¼MainAxisï¼å交åè½´ï¼CrossAxisï¼åå«æ¯ä¸å¾
对äºColumnæ¥è¯´ï¼ä¸»è½´ï¼MainAxisï¼å交åè½´ï¼CrossAxisï¼åå«æ¯ä¸å¾
2.1.Rowç»ä»¶2.1.1.Rowä»ç»Rowç»ä»¶ç¨äºå°ææçåWidgetææä¸è¡ï¼å®é ä¸è¿ç§å¸å±åºè¯¥æ¯åé´äºWebçFlexå¸å±ã
å¦æçæFlexå¸å±ï¼ä¼åç°é常ç®åã
ä»æºç ä¸æ¥çRowçå±æ§ï¼
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}1mainAxisSizeï¼
表示Rowå¨ä¸»è½´(æ°´å¹³)æ¹åå ç¨ç空é´ï¼é»è®¤æ¯MainAxisSize.maxï¼è¡¨ç¤ºå°½å¯è½å¤çå ç¨æ°´å¹³æ¹åç空é´ï¼æ¤æ¶æ 论åwidgetså®é å ç¨å¤å°æ°´å¹³ç©ºé´ï¼Rowç宽度å§ç»çäºæ°´å¹³æ¹åçæ大宽度
èMainAxisSize.min表示尽å¯è½å°çå ç¨æ°´å¹³ç©ºé´ï¼å½åwidgets没æå 满水平å©ä½ç©ºé´ï¼åRowçå®é 宽度çäºææåwidgetså ç¨çç水平空é´ï¼
mainAxisAlignmentï¼è¡¨ç¤ºåWidgetså¨Rowæå ç¨ç水平空é´å 对é½æ¹å¼
å¦æmainAxisSizeå¼ä¸ºMainAxisSize.minï¼åæ¤å±æ§æ æä¹ï¼å 为åwidgetsç宽度çäºRowç宽度
åªæå½mainAxisSizeçå¼ä¸ºMainAxisSize.maxæ¶ï¼æ¤å±æ§æææä¹
MainAxisAlignment.start表示沿textDirectionçåå§æ¹å对é½ï¼
å¦textDirectionåå¼ä¸ºTextDirection.ltræ¶ï¼åMainAxisAlignment.start表示左对é½ï¼textDirectionåå¼ä¸ºTextDirection.rtlæ¶è¡¨ç¤ºä»å³å¯¹é½ã
èMainAxisAlignment.endåMainAxisAlignment.startæ£å¥½ç¸åï¼
MainAxisAlignment.centerè¡¨ç¤ºå± ä¸å¯¹é½ã
crossAxisAlignmentï¼è¡¨ç¤ºåWidgetså¨çºµè½´æ¹åç对é½æ¹å¼
Rowçé«åº¦çäºåWidgetsä¸æé«çåå ç´ é«åº¦
å®çåå¼åMainAxisAlignmentä¸æ ·(å å«startãendãcenterä¸ä¸ªå¼)
ä¸åçæ¯crossAxisAlignmentçåèç³»æ¯verticalDirectionï¼å³verticalDirectionå¼ä¸ºVerticalDirection.downæ¶crossAxisAlignment.startæ顶é¨å¯¹é½ï¼verticalDirectionå¼ä¸ºVerticalDirection.upæ¶ï¼crossAxisAlignment.startæåºé¨å¯¹é½ï¼ècrossAxisAlignment.endåcrossAxisAlignment.startæ£å¥½ç¸åï¼
2.1.2.Rowæ¼ç»æ们æ¥å¯¹é¨åå±æ§è¿è¡ç®åç代ç æ¼ç»ï¼å ¶ä»ä¸äºå±æ§å¤§å®¶èªå·±å¦ä¹ ä¸ä¸
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.1.3.mainAxisSizeé»è®¤æ åµä¸ï¼Rowä¼å°½å¯è½å æ®å¤ç宽度ï¼è®©åWidgetå¨å ¶ä¸è¿è¡æå¸ï¼è¿æ¯å 为mainAxisSizeå±æ§é»è®¤å¼æ¯MainAxisSize.maxã
æ们æ¥çä¸ä¸ï¼å¦æè¿ä¸ªå¼è¢«ä¿®æ¹ä¸ºMainAxisSize.maxä¼ä»ä¹ååï¼
2.1.4.TextBaselineå ³äºTextBaselineçåå¼è§£æ
2.1.5.Expandedå¦ææ们å¸æ红è²åé»è²çContainerWidgetä¸è¦è®¾ç½®åºå®ç宽度ï¼èæ¯å æ®å©ä½çé¨åï¼è¿ä¸ªæ¶ååºè¯¥å¦ä½å¤çå¢ï¼
è¿ä¸ªæ¶åæ们å¯ä»¥ä½¿ç¨Expandedæ¥å 裹ContainerWidgetï¼å¹¶ä¸å°å®ç宽度ä¸è®¾ç½®å¼ï¼
flexå±æ§ï¼å¼¹æ§ç³»æ°ï¼Rowä¼æ ¹æ®ä¸¤ä¸ªExpandedçå¼¹æ§ç³»æ°æ¥å³å®å®ä»¬å æ®å©ä¸ç©ºé´çæ¯ä¾
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.2.Columnç»ä»¶Columnç»ä»¶ç¨äºå°ææçåWidgetææä¸åï¼å¦ä¼äºåé¢çRowåï¼Columnåªæ¯årowçæ¹åä¸åèå·²ã
2.2.1.Columnä»ç»æ们ç´æ¥çå®çæºç ï¼æ们åç°åRowå±æ§æ¯ä¸è´çï¼ä¸å解é
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.2.2.Columnæ¼ç»æ们ç´æ¥å°Rowç代ç ä¸Rowæ¹ä¸ºColumnï¼æ¥ç代ç è¿è¡ææ
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}.3.Stackç»ä»¶å¨å¼åä¸ï¼æ们å¤ä¸ªç»ä»¶å¾æå¯è½éè¦éå æ¾ç¤ºï¼æ¯å¦å¨ä¸å¼ å¾çä¸æ¾ç¤ºæåæè ä¸ä¸ªæé®çã
å¨Androidä¸å¯ä»¥ä½¿ç¨Frameæ¥å®ç°ï¼å¨Web端å¯ä»¥ä½¿ç¨ç»å¯¹å®ä½ï¼å¨Flutterä¸æ们éè¦ä½¿ç¨å±å å¸å±Stackã
2.3.1.Stackä»ç»æ们è¿æ¯éè¿æºç æ¥çä¸ä¸Stackæåªäºå±æ§ï¼
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}6åæ°j解æï¼
alignmentï¼æ¤åæ°å³å®å¦ä½å»å¯¹é½æ²¡æå®ä½ï¼æ²¡æ使ç¨Positionedï¼æé¨åå®ä½çåwidgetãæè°é¨åå®ä½ï¼å¨è¿éç¹æ没æå¨æä¸ä¸ªè½´ä¸å®ä½ï¼leftãright为横轴ï¼topãbottom为纵轴ï¼åªè¦å å«æ个轴ä¸çä¸ä¸ªå®ä½å±æ§å°±ç®å¨è¯¥è½´ä¸æå®ä½ã
textDirectionï¼åRowãWrapçtextDirectionåè½ä¸æ ·ï¼é½ç¨äºå³å®alignment对é½çåèç³»å³ï¼textDirectionçå¼ä¸ºTextDirection.ltrï¼åalignmentçstart代表左ï¼end代表å³ï¼textDirectionçå¼ä¸ºTextDirection.rtlï¼åalignmentçstart代表å³ï¼end代表左ã
fitï¼æ¤åæ°ç¨äºå³å®æ²¡æå®ä½çåwidgetå¦ä½å»éåºStackç大å°ãStackFit.loose表示使ç¨åwidgetç大å°ï¼StackFit.expand表示æ©ä¼¸å°Stackç大å°ã
overflowï¼æ¤å±æ§å³å®å¦ä½æ¾ç¤ºè¶ åºStackæ¾ç¤ºç©ºé´çåwidgetï¼å¼ä¸ºOverflow.clipæ¶ï¼è¶ åºé¨åä¼è¢«åªè£ï¼éèï¼ï¼å¼ä¸ºOverflow.visibleæ¶åä¸ä¼ã
2.3.2.Stackæ¼ç»Stackä¼ç»å¸¸åPositionedä¸èµ·æ¥ä½¿ç¨ï¼Positionedå¯ä»¥å³å®ç»ä»¶å¨Stackä¸çä½ç½®ï¼ç¨äºå®ç°ç±»ä¼¼äºWebä¸çç»å¯¹å®ä½ææã
ä¸ä¸ªç®åçæ¼ç»ï¼
注æï¼Positionedç»ä»¶åªè½å¨Stackä¸ä½¿ç¨ã
classMyHomeBodyextendsStatelessWidget{ @overrideWidgetbuild(BuildContextcontext){ returnAlign(child:Icon(Icons.pets,size:,color:Colors.red),alignment:Alignment.bottomRight,widthFactor:3,heightFactor:3,);}}7\
åæï¼/post/Nginx源码交叉编译-保姆级移植ARM
在Ubuntu..7 位系统上,使用arm-linux-gnueabihf-gcc作为交叉编译器,针对arm内核4.1.和恩智浦imx6ul嵌入式平台,进行了一次详细的Nginx源码的交叉编译移植过程。
准备工作包括了下载Nginx(1..0)、pcre(8.)、zlib(1.3.1)和openssl(1.1.1)的最新版本。在编译过程中,作者尝试了openssl的3.0.版本,但遇到编译问题,最终选择1.1.1版本进行编译。
在进入Nginx源码目录后,需要对部分源码进行修改,如移除退出函数并调整size大小。增加PCRE配置后,对Nginx进行配置,如果不需要ssl,应移除相关部分。配置完成后生成Makefile,但在此阶段并未进行编译。
Pcre源码的处理包括切换目录、配置和编译,编译成功且无误。对于openssl(选配),需要确保安装路径设置正确,配置后删除部分Makefile内容,进行编译,可能需要清理缓存以解决编译问题。
在Nginx部分的后续操作中,添加了必要的酷狗apk源码定义以避免malloc未引用错误,并调整了Makefile以排除之前手动编译的影响。最后进行编译,安装完成后,检查可执行文件类型和大小,进行优化以减少调试信息,使文件减小至2.8M。
测试阶段,将编译后的文件复制到arm设备,通过修改配置文件解决报错后,成功运行并访问测试页面,完成了基础的移植工作。
ITX-RKJ上固件与驱动的交叉编译与烧写流程概述
本文档着重阐述了如何在Linux虚拟机环境下,通过交叉编译在Firefly的ITX-RKJ开发板上实现Ubuntu固件与驱动的制作过程,涵盖环境配置、固件与驱动的编译、烧写与安装步骤,并总结了在实现过程中可能遇到的问题及解决策略。
在进行交叉编译时,我们采用win物理机上搭载的VisualBox管理的Ubuntu.虚拟机环境。此过程包括编译环境的配置、源码资源的下载与更新、固件与驱动的编译。在执行过程中,确保在root下执行命令并检查文件权限,使用"chmod"命令调整权限至,以解决可能出现的问题。
配置编译环境时,推荐使用Ubuntu.版本,由于官方建议的.版本不再维护,我们发现其sources.list内的软件源地址无法正常更新,导致配置不便。因此,实测使用.版本能够顺利完成固件编译。建议在虚拟机配置之初完成虚拟内存大小、虚拟硬盘大小的设置、网络连接方式、共享文件夹的配置等步骤,并设置root密码。
编译环境配置涉及多个软件的安装,如repo、git、ssh、make、gcc等,并根据需要安装python2.6-2.7版本和7-zip等工具。安装步骤包括在终端输入安装命令,并完成软件列表和软件的更新。对于其他可能需要的软件,根据编译过程中的报错信息直接下载安装。
SDK初始化与更新部分,涉及资源文件的下载与校验、SDK的解压、初始化与更新。确保下载的资源完整无损,并使用repo工具链接Firefly仓库进行SDK初始化与更新。
固件编译过程中,spring项目源码下载下载并解压根文件,使用repo工具链进行配置,选择对应板子型号的配置文件并直接编译完整固件。编译生成的固件部分以链接形式保存,完整固件位于指定目录下。对于部分编译,参考Wiki教程调整编译命令。
驱动编译涉及对原始驱动源文件的修改,使其能在新平台上运行。具体修改包括更改makefile文件中的目标平台架构、交叉编译工具链和内核源码路径,以及驱动源文件"xxx.c"的具体代码修改。根据错误信息进行调整,确保驱动能正确编译生成。
固件烧写与驱动安装阶段,将编译好的固件和驱动传输至PC端,通过USB线缆连接至开发板进行固件烧写。使用RKDevTool完成驱动安装与固件烧写流程。驱动安装则通过FTP、TFTP或U盘拷贝至开发板,并在上电时连接外设,使用命令进行驱动安装。
在整个过程中,可能出现的一些问题及解决策略,如repo安装失败时使用特定命令,或U盘无法正常使用时尝试安装ntfs-3g驱动,以确保系统能够正常识别与读取U盘内容。
本文档通过详细的步骤指导,旨在提供一个全面的指南,帮助开发者在Firefly的ITX-RKJ开发板上完成Ubuntu固件与驱动的交叉编译、烧写与驱动安装,以实现开发板的正常运行。
怎么做数据分析(做数据分析的软件)
怎么做数据分析
常见的数据分析方法有哪些?
1.趋势分析
当有大量数据时,我们希望更快,更方便地从数据中查找数据信息,这时我们需要使用图形功能。所谓的图形功能就是用EXCEl或其他绘图工具来绘制图形。
趋势分析通常用于长期跟踪核心指标,例如点击率,GMV和活跃用户数。通常,只制作一个简单的数据趋势图,但并不是分析数据趋势图。它必须像上面一样。数据具有那些趋势变化,无论是周期性的,是否存在拐点以及分析背后的原因,还是内部的或外部的。趋势分析的最佳输出是比率,有环比,同比和固定基数比。例如,年4月的GDP比3月增加了多少,这是环比关系,该环比关系反映了近期趋势的变化,但具有季节性影响。eclipse spark源码编译为了消除季节性因素的影响,引入了同比数据,例如:年4月的GDP与年4月相比增长了多少,这是同比数据。更好地理解固定基准比率,即固定某个基准点,例如,以年1月的数据为基准点,固定基准比率是年5月数据与该数据年1月之间的比较。
2.对比分析
水平对比度:水平对比度是与自己进行比较。最常见的数据指标是需要与目标值进行比较,以了解我们是否已完成目标;与上个月相比,要了解我们环比的增长情况。
纵向对比:简单来说,就是与其他对比。我们必须与竞争对手进行比较以了解我们在市场上的份额和地位。
许多人可能会说比较分析听起来很简单。让我举一个例子。有一个电子商务公司的登录页面。昨天的PV是。您如何看待此类数据?您不会有任何感觉。如果此签到页面的平均PV为,,则意味着昨天有一个主要问题。如果签到页面的平均PV为,则昨天有一个跳跃。数据只能通过比较才有意义。
3.象限分析
根据不同的数据,每个比较对象分为4个象限。如果将IQ和EQ划分,则可以将其划分为两个维度和四个象限,每个人都有自己的象限。一般来说,智商保证一个人的下限,情商提高一个人的上限。
说一个象限分析方法的例子,在实际工作中使用过:通常,p2p产品的注册用户由第三方渠道主导。如果您可以根据流量来源的质量和数量划分四个象限,然后选择一个固定的时间点,比较每个渠道的流量成本效果,则该质量可以用作保留的总金额的维度为标准。对于高质量和高数量的通道,继续增加引入高质量和低数量的通道,低质量和低数量的通过,低质量和高数量的尝试策略和要求,例如象限分析可以让我们比较和分析时间以获得非常直观和快速的结果。
4.交叉分析
比较分析包括水平和垂直比较。如果要同时比较水平和垂直方向,则可以使用交叉分析方法。交叉分析方法是从多个维度交叉显示数据,并从多个角度执行组合分析。
分析应用程序数据时,通常分为iOS和Android。
交叉分析的主要功能是从多个维度细分数据并找到最相关的维度,以探究数据更改的原因。
做数据分析的php付费问答源码软件
数据分析软件最好用的有:
一、大数据分析工具——Hadoop
Hadoop是一个能够对大量数据进行分布式处理的软件框架。但是Hadoop是以一种可靠、高效、可伸缩的方式进行处理的。Hadoop是可靠的,因为它假设计算元素和存储会失败,因此它维护多个工作数据副本,确保能够针对失败的节点重新分布处理。
Hadoop是高效的,因为它以并行的方式工作,通过并行处理加快处理速度。Hadoop还是可伸缩的,能够处理PB级数据。此外,Hadoop依赖于社区服务器,因此它的成本比较低,任何人都可以使用。
二、大数据分析工具——思迈特软件Smartbi
融合传统BI、自助BI、智能BI,满足BI定义所有阶段的需求;提供数据连接、数据准备、数据分析、数据应用等全流程功能;提供复杂报表、数据可视化、自助探索分析、机器学习建模、预测分析、自然语言分析等全场景需求;满足数据角色、分析角色、管理角色等所有用户的需求。
三、大数据分析工具——Bokeh
这套可视化框架的主要目标在于提供精致且简洁的图形处理结果,用以强化大规模数据流的交互能力。其专门供Python语言使用。
四、大数据分析工具——Storm
Storm是自由的开源软件,一个分布式的、容错的实时计算系统。Storm可以非常可靠的处理庞大的数据流,用于处理Hadoop的批量数据。Storm很简单,支持许多种编程语言,使用起来非常有趣。
Storm由Twitter开源而来,其它知名的应用企业包括Groupon、淘宝、支付宝、阿里巴巴、乐元素、Admaster等等。
五、大数据分析工具——Plotly
这是一款数据可视化工具,可兼容JavaScript、MATLAB、Python以及R等语言。Plotly甚至能够帮助不具备代码编写技能或者时间的用户完成动态可视化处理。这款工具常由新一代数据科学家使用,因为其属于一款业务开发平台且能够快速完成大规模数据的理解与分析。
数据分析的三大方法
一个产品,如果你不能衡量它,你就不能了解它,自然而然,你就无法改进它。数据说到底,就是这样一个工具——通过数据,我们可以衡量产品,可以了解产品,可以在数据驱动下改进产品。数据分析和数据处理本身是一个非常大的领域,这里主要总结一些我个人觉得比较基础且实用的部分,在日常产品工作中可以发挥比较大作用。
本文主要讨论一些数据分析的三个常用方法:
1. 数据趋势分析
趋势分析一般而言,适用于产品核心指标的长期跟踪,比如,点击率,GMV,活跃用户数等。做出简单的数据趋势图,并不算是趋势分析,趋势分析更多的是需要明确数据的变化,以及对变化原因进行分析。
趋势分析,最好的产出是比值。在趋势分析的时候需要明确几个概念:环比,同比,定基比。环比是指,是本期统计数据与上期比较,例如年2月份与年1月份相比较,环比可以知道最近的变化趋势,但是会有些季节性差异。为了消除季节差异,于是有了同比的概念,例如年2月份和年2月份进行比较。定基比更好理解,就是和某个基点进行比较,比如年1月作为基点,定基比则为年2月和年1月进行比较。
比如:年2月份某APP月活跃用户数我万,相比1月份,环比增加2%,相比去年2月份,同比增长%。趋势分析另一个核心目的则是对趋势做出解释,对于趋势线中明显的拐点,发生了什么事情要给出合理的解释,无论是外部原因还是内部原因。
2. 数据对比分析
数据的趋势变化独立的看,其实很多情况下并不能说明问题,比如如果一个企业盈利增长%,我们并无法判断这个企业的好坏,如果这个企业所处行业的其他企业普遍为负增长,则5%很多,如果行业其他企业增长平均为%,则这是一个很差的数据。
对比分析,就是给孤立的数据一个合理的参考系,否则孤立的数据毫无意义。在此我向大家推荐一个大数据技术交流圈:??突破技术瓶颈,提升思维能力 。
一般而言,对比的数据是数据的基本面,比如行业的情况,全站的情况等。有的时候,在产品迭代测试的时候,为了增加说服力,会人为的设置对比的基准。也就是A/B test。
比较试验最关键的是A/B两组只保持单一变量,其他条件保持一致。比如测试首页改版的效果,就需要保持A/B两组用户质量保持相同,上线时间保持相同,来源渠道相同等。只有这样才能得到比较有说服力的数据。
3. 数据细分分析
在得到一些初步结论的时候,需要进一步地细拆,因为在一些综合指标的使用过程中,会抹杀一些关键的数据细节,而指标本身的变化,也需要分析变化产生的原因。这里的细分一定要进行多维度的细拆。常见的拆分方法包括:
分时 :不同时间短数据是否有变化。
分渠道 :不同来源的流量或者产品是否有变化。
分用户 :新注册用户和老用户相比是否有差异,高等级用户和低等级用户相比是否有差异。
分地区 :不同地区的数据是否有变化。
组成拆分 :比如搜索由搜索词组成,可以拆分不同搜索词;店铺流量由不用店铺产生,可以分拆不同的店铺。
细分分析是一个非常重要的手段,多问一些为什么,才是得到结论的关键,而一步一步拆分,就是在不断问为什么的过程。
4. 小结
趋势,对比,细分,基本包含了数据分析最基础的部分。无论是数据核实,还是数据分析,都需要不断地找趋势,做对比,做细分,才能得到最终有效的结论。
在此我向大家推荐一个大数据开发交流圈:
( ?点击即可加入群聊 )
里面整理了一大份学习资料,全都是些干货,包括大数据技术入门,大数据离线处理、数据实时处理、Hadoop 、Spark、Flink、推荐系统算法以及源码解析等,送给每一位大数据小伙伴,让自学更轻松。这里不止是小白聚集地,还有大牛在线解答!欢迎初学和进阶中的小伙伴一起进群学习交流,共同进步!
最后祝福所有遇到瓶颈的大数据程序员们突破自己,祝福大家在往后的工作与面试中一切顺利
如何学做数据分析
如需学习数据分析推荐选择十方融海,成本数据分析的步骤如下:
1、明确目的:要进行成本分析,首先要明确分析目的。
2、确定对象:确定对象指对对象为材料成本、员工成本、销售费用、管理费用还是财务费用等进行分析。分析的原则有两个:一是全面分析,二是重点分析,也即专项分析。
3、数据的收集与汇总:分析对象确定后,企业就要围绕对象收集数据,数据的收集和汇总非常关键。
成本分析方法:
a、比较分析法:成本的比较分析法可细分为两种,即同比分析和环比分析。
b、比率分析法:比率分析法是指将不同项目放在一起进行比较所构成的一种比值。
c、因素分析法:因素分析法是分析过程中应用最多的一种方法。在企业的成本分析中,影响利润的因素有四个:销量、价格、成本、费用。
d、差异分析法。
e、本量利分析法:本量利分析是指在成本习性分析的基础上,运用数学模型和图式,对成本、利润、业务量与单价等因素之间的依存关系进行具体的分析,研究其变动的规律性,以便为企业进行经营决策和目标控制提供有效信息的一种方法。
想要了解更多关于成本数据分析的相关信息,推荐选择十方融海。十方融海作为技术创新型企业,坚持源头核心技术创新,为用户提供听得懂、学得会、用得上的产品。该机构的解决方案和社会价值获得了主流媒体报道,与厦门大学、深圳大学、华南理工大学等高校达成校企合作,探索产教融合、成人教育新模式。用科技推动教育改革,让教育创造美好生活。
说人话——啥是交叉编译
本文将深入探讨计算机世界的语言转换,特别是交叉编译的概念。首先,我们从计算机如何理解指令开始:
想象一下,当我们输入"hello world"(用Python编写的简单问候语),按下回车,计算机看似能理解并输出,但实际上它并不直接理解人类语言,而是翻译成一种它能解读的“语言”——序列。这种序列是人类对电子元器件(如晶体管)物理状态的抽象,这些元器件通过电压和电流变化来执行指令。
以mosfet为例,计算机处理的是连续变化的电压,这在硬件层面处理起来并不直观。因此,我们定义了高电平和低电平这两种状态,它们之间的切换是基于物理规则的。编译器的工作就是将人类编写的源代码转化为这些电子状态,以便计算机能执行。
不同CPU架构,如位或位,就像不同的国家工人,他们的指令集和电平表示方式可能各有不同。这就导致即使输入相同的代码序列,由于架构差异,输出结果在屏幕上显示的可能不同。这就是为什么可执行文件在不同平台间不通用的原因。
接下来,编译过程涉及到的“体力活”是跨平台的——我们想在一台CPU(如x)上编译出可以在另一台CPU(如arm)上运行的代码,这就需要进行“交叉编译”。它就像一个美国人用中文考试,虽然他自己和他人可能都无法理解,但通过翻译工具,中国人可以理解答案。
以x Linux编译器编译arm Linux为例,这个过程像是在x平台上按照arm平台的规则对代码进行转换。然而,生成的可执行文件却无法在x上运行,就像美国人用中文考试后,其他人看不懂但中国人能理解。
Qt+MPlayer音乐播放器开发笔记(二):交叉编译MPlayer以及部署到开发板播放演示
前言
本文详细介绍了在 Ubuntu 上实现 ARM 跨平台编译 MPlayer 播放器,并部署到开发板播放音乐的过程。本教程适合对 Linux 系统下跨平台编译和 ARM 开发有需求的开发者。
MPlayer
MPlayer 是一款功能强大的开源多媒体播放器,支持广泛的操作系统,如 Linux、Windows、Mac OS X 等。它不仅提供了命令行界面,还支持图形界面的安装。MPlayer 的一个显著特点在于其输出设备的多样性,能够适应包括 X、Xv、DGA、OpenGL、SVGAlib、fbdev、AAlib、DirectFB 等多种环境,并且支持通过硬件 MPEG 解码卡显示,如 DVB、DXR3 与 Hollywood+。这款播放器自 年开始开发,最初由 Arpad Gereoffy 所创,后逐渐发展成为跨平台的多媒体播放解决方案。
下载与编译
获取最新 MPlayer 源码,可通过提供的下载链接进行下载。完成下载后,解压并进入 MPlayer 目录,使用命令行进行编译配置。配置时需指定编译目标路径、交叉编译器,以及是否使用 zlib 库。对于遇到的“error impossible constraint in asm”问题,通过调整配置参数解决,确保编译过程顺利。完成编译后,宿主机上可直接测试 MPlayer,确认其功能正常。
部署与测试
编译完成后,将 MPlayer 目录及其依赖的 zlib 库复制到开发板。由于 zlib 库已存在于开发板上,无需再次复制。在 ARM 开发板上执行 MPlayer,通过播放音频文件进行测试,验证其播放功能。
总结与展望
通过本文教程,开发者可以掌握在 Ubuntu 环境下编译 ARM 平台的 MPlayer 播放器,并部署到开发板进行音乐播放的基本步骤。本教程旨在提供一个完整的跨平台编译与部署解决方案,为开发者在不同硬件平台上实现多媒体播放功能提供参考。后续文章将深入探讨更多相关技术细节与应用案例,敬请期待。