当前位置: 首页 > news >正文

长沙做网站好的公司长春免费网站建站模板

长沙做网站好的公司,长春免费网站建站模板,公职人员可以做网站吗,wordpress支付功能简介 Makefile 是和 make 命令一起配合使用的#xff0c;很多大型项目的编译都是通过 Makefile 来组织的,。 我建立工程的方法有以下三点#xff1a; 1.makefile#xff1a; 优点#xff1a;使用非常广泛#xff0c;通用性强#xff0c;可跨平台。 缺点#xff1a;语法比… 简介 Makefile 是和 make 命令一起配合使用的很多大型项目的编译都是通过 Makefile 来组织的,。 我建立工程的方法有以下三点 1.makefile 优点使用非常广泛通用性强可跨平台。 缺点语法比较蛋疼。要写出一个通用便于管理且兼容性强的makefile比较困难。 2.cmake 优点简单易用使用较广泛方便管理可跨平台。 缺点自动生成的makefile太臃肿。 3.sh脚本 优点自由高度定制。简单易用可操作性强。方便维护。甚至还可以生成makefile 缺点sh建的工程太少了估计没人这么搞吧 但我考虑到方便移植和管理其他人的工程还是选择了第一种以makefile建立管理工程。其实我的内心是比较向往第三种sh脚本建工程的。下面来介绍下makefile的规则以及语法 PS:我本意是想写短一点的只是想写点常用的东西方便大家查阅。精炼了这么久可还有这么多内容15000字。所以大家还是耐心的学习吧想学好linux这是必不可少的一步。 规则 说明 target1 target2.... : prerequisites1 prerequisites2... [TAB] command1 [TAB] command2 ... target可以是一个object file(目标文件)也可以是一个执行文件还可以是一个标签label。对于标签这种特性在后续的“伪目标”章节中会有叙述。 prerequisites就是要生成那个target所需要的文件或是目标。 command也就是make需要执行的命令。任意的shell命令 这是一个文件的依赖关系也就是说target这一个或多个的目标文件依赖于prerequisites中的文件其生成规则定义在 command中。说白一点就是说prerequisites中如果有一个以上的文件比target文件要新的话command所定义的命令就会被执行。这就是makefile的规则。也就是makefile中最核心的内容。 经典示例 原始版本 objects main.o kbd.o command.o display.o \insert.o search.o files.o utils.oedit : $(objects)cc -o edit $(objects) main.o : main.c defs.hcc -c main.c kbd.o : kbd.c defs.h command.hcc -c kbd.c command.o : command.c defs.h command.hcc -c command.c display.o : display.c defs.h buffer.hcc -c display.c insert.o : insert.c defs.h buffer.hcc -c insert.c search.o : search.c defs.h buffer.hcc -c search.c files.o : files.c defs.h buffer.h command.hcc -c files.c utils.o : utils.c defs.hcc -c utils.c clean :rm edit $(objects)自动推导版本 objects main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ gccedit : $(objects)cc -o edit $(objects)main.o : defs.h kbd.o : defs.h command.h command.o : defs.h command.h display.o : defs.h buffer.h insert.o : defs.h buffer.h search.o : defs.h buffer.h files.o : defs.h buffer.h command.h utils.o : defs.h.PHONY : clean clean :rm edit $(objects)理解 1.内容展开 list_a 1.a 2.a list_b 1.b 2.b 3.b#list_a中的元素每次单个展开连接list_b中的所有元素 #结果如下 test:list_a %.a:list_b #展开1.a1.b 2.b 3.b #此时1.a $1.b 2.b 3.b2.a1.b 2.b 3.b #此时2.a $1.b 2.b 3.b#内容还可以继续展开 %.b:%.x #自动推导展开1.b:1.x2.b:2.x3.b:3.x2.include 相当于将内容复制展开export可以共享全局变量。 3.用make遍历子目录makefile时相当于用新进程开启make。因此export不能共享全局变量。 注意 1.注意空格与TAB有些编辑器会自动将TAB转换成4个空格难以发现 2.注意 与 : 的区别 包括export 在内的所有变量都不能共享 如果使用cd make进行遍历。那么最好转换成绝对路径 3.如果使用cd make进行遍历。那么最好转换成绝对路径 语法 1.符号 1) 命令前缀 [不用前缀 ]输出执行的命令以及命令执行的结果, 出错的话停止执行 [前缀 ]只输出命令执行的结果, 出错的话停止执行 [前缀 -]命令执行有错的话, 忽略错误, 继续执行 2) 通配符 *表示任意一个或多个字符? 表示任意一个字符[...] [abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字 3) 自动变量 在下文的 自动变量 4) 赋值 与 : 相同点都是给内容赋值 区别与Verilog的和类似。 其中 和 : 的区别在于 : 只能使用前面定义好的变量, 可以使用后面定义的变量 赋值符号 [] 最后再赋值 # Makefile内容 OBJS2 $(OBJS1) programC.o OBJS1 programA.o programB.oall:echo $(OBJS2)# bash中执行 make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使用 $ make programA.o programB.o programC.o赋值符号 [:] : 立即赋值 # Makefile内容 OBJS2 : $(OBJS1) programC.o OBJS1 : programA.o programB.oall:echo $(OBJS2)# bash中执行 make, 可以看出 OBJS2 中的 $(OBJS1) 为空 $ make programC.o赋值符号 [] 变量追加值 # Makefile内容 SRCS : programA.c programB.c programC.c SRCS programD.call:echo SRCS: $(SRCS)# bash中运行make $ make SRCS: programA.c programB.c programC.c programD.c5) 伪目标 .PHONY .PHONY : clean clean :-rm edit $(objects)2. 隐含规则 1) 自动推倒命名 编译C时*.o 的目标会自动推导为 *.c 2) 隐含变量 [RM] rm -f [AR] ar [CC] cc [CXX] g [ARFLAGS] AR命令的参数 [CFLAGS] 语言编译器的参数 [CXXFLAGS] C语言编译器的参数 3) 自动变量 [$] 目标集合 [$%] 当目标是函数库文件时, 表示其中的目标文件名 [$] 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标 [$?] 比目标新的依赖目标的集合 [$^] 所有依赖目标的集合, 会去除重复的依赖目标 [$] 所有依赖目标的集合, 不会去除重复的依赖目标 [$*] 这个是GNU make特有的, 其它的make不一定支持 1.o: 1.cecho $ : $ # bash中执行 make: 1.o : 1.c3.定义 不限于makefile还有部分shell指令 1) 查看依赖关系 gcc -MM $ gcc -MM kvm_main.c kvm_main.o: kvm_main.c iodev.h coalesced_mmio.hasync_pf.h #这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系2) 定义命令包 define command-name command ... endef # Makefile 内容 define run-hello-makefile echo -n Hello echo Makefile! echo 这里可以执行多条 Shell 命令! endefall:$(run-hello-makefile)# bash 中运行make $ make Hello Makefile! 这里可以执行多条 Shell 命令!3) 条件判断 # Makefile 内容 all: ifeq (aa, bb)echo equal elseecho not equal endif# bash 中执行 make $ make not equal4) 自定义函数 $(call expression,parm1,parm2,parm3...) # Makefile 内容 hello hello $(1) worldall:echo $(call hello,我是参数1)# bash 中执行 make $ make hello 我是参数1 world5) 执行shell指令 $(shell shell command) 与 shell command 作用:执行一个shell命令, 并将shell命令的结果作为返回.注意 是反引号(英文状态下键盘的ESC下面那个键) 4.函数 不限于makefile还有部分shell指令 1) 传参同一个进程 export export EX_VAR value export EX_VAR : value export EX_VAR value # : 与上面的描述基本相同注意是同一个进程下的make才有用。当多级遍历make时是无法全局的。 2) 字符串处理 (1) 字符串替换函数 $( substsource,new,text) 功能: 把字符串text 中的source 替换为new 返回: 替换过的字符串 # Makefile 内容 all:echo $(subst t,e,maktfilt) -- 将t替换为e# bash 中执行 make $ make makefile(2) 字符串中每个元素替换函数 $( patsubst source,new,text) 功能: 把字符串 text 中的的每个元素 source 替换为new 返回: 替换过的字符串 # Makefile 内容 all:echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执行 make $ make programA.o programB.o(3) 去空格函数 $(strip text) 功能: 去掉 string 字符串中开头和结尾的空字符 返回: 被去掉空格的字符串值 # Makefile 内容 VAL : aa bb cc all:echo 去除空格前: $(VAL)echo 去除空格后: $(strip $(VAL))# bash 中执行 make $ make 去除空格前: aa bb cc 去除空格后: aa bb cc(4) 判断字符串内是否存在特定字符串 $(findstringtext,elem) 功能: 在字符串 text 中查找 elem 字符串是否存在 返回: 如果找到, 返回 elem 字符串, 否则返回空字符串 # Makefile 内容 VAL : aa bb cc all:echo $(findstring aa,$(VAL))echo $(findstring ab,$(VAL))# bash 中执行 make $ make aa3) 文件元素相关 (1) 取文件函数 保留符合条件的元素 $(filter elem1 elem2...,text) # Makefile 内容 all:echo $(filter %.o %.a,program.c program.o program.a)# bash 中执行 make $ make program.o program.a program.c去掉符合条件的元素 $(filter-out elem1 elem2...,text) # Makefile 内容 all:echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执行 make $ make program.c获取该目录下所有文件 获取该目录下所有.x文件 $(wildcard *.x) # Makefile 内容 all:echo $(wildcard *.c)# bash 中执行 make $ make a.x b.x c.x(2) 路径函数 去掉路径 $(notdir elem elem...) 功能: 去掉序列的路径 返回: 文件名序列 elem 中的非目录部分 # Makefile 内容 all:echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执行 make $ make a.c bb.c c.c d.c取路径 $(dir elem1 elem2...) 功能: 从文件名序列 elem 中取出目录部分 返回: 文件名序列 elem 中的目录部分 # Makefile 内容 all:echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执行 make $ make /home/ ./ ../ ./(3) 取前后缀 取后缀函数 $(suffix elem1 elem2...) 功能: 从文件名序列 elem 中取出各个文件名的后缀 返回: 文件名序列 elem 中各个文件名的后缀, 没有后缀则返回空字符串 # Makefile 内容 all:echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执行 make $ make .c .o .a取前缀函数 $(basename elem1 elem2...) 功能: 从文件名序列 elem 中取出各个文件名的前缀 返回: 文件名序列 elem 中各个文件名的前缀, 没有前缀则返回空字符串 # Makefile 内容 all:echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执行 make $ make /home/a ./b ../c /home/(3) 增添前后缀 增添后缀函数 $(addsuffix suffix,elem1 elem2...) 功能: 把后缀 suffix 加到 elem 中的每个单词后面 返回: 加过后缀的文件名序列 # Makefile 内容 all:echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执行 make $ make /home/a.c b.c ./c.o.c ../d.c.c增添前缀函数 $(addprefix prefix, elem1 elem2...) 功能: 把前缀 prefix 加到 elem 中的每个单词前面 返回: 加过前缀的文件名序列 # Makefile 内容 all:echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执行 make $ make test_/home/a.c test_b.c test_./d.c我写的管理大型项目的makefile 以下内容为基础版本。可以混编C和C。 但没有加入平台兼容性验证等功能。 在ubuntu16.04下测试通过。 tree . ├── app │ ├── app1 │ │ ├── main.c │ │ └── makefile │ └── makefile ├── make_conf.mk ├── makefile ├── make_fun.mk ├── module │ ├── makefile │ └── test │ ├── drive │ │ ├── cpp_test.cpp │ │ ├── cpp_test.h │ │ ├── test.c │ │ └── test.h │ ├── hal │ │ ├── test_hal.c │ │ └── test_hal.h │ └── makefile └── output├── bin│ ├── app1.bin│ └── app2.bin├── lib│ └── libobj.a└── obj├── app│ ├── app1│ │ └── main.o│ └── app2│ └── main.o└── module└── test├── drive│ ├── cpp_test.o│ └── test.o└── hal└── test_hal.o17 directories, 22 files顶层 makefile # ------------------------------------------- # FileName :makefile # Author :wind # Date :2018-1-16 # Description # # Top makefile. # # ------------------------------------------- # 设置当前路径 DIR_ROOT:.# 设置递归子目录 DIR_LIST_SUB :module appinclude $(DIR_ROOT)/make_conf.mk all:make_root clean:make_clean include $(DIR_ROOT)/make_fun.mk中间遍历层 makefile # ------------------------------------------- # FileName :xx/makefile # Author :wind # Date :2018-1-16 # Description # # Level1 makefile. # # ------------------------------------------- # 设置当前路径 DIR_ROOT:..# 添加递归子目录 DIR_LIST_SUB :\ app1\ app2\# 添加源文件 FILE_LIST_C \FILE_LIST_CPP \FILE_LIST_S \# 添加头文件路径 DIR_LIST_INCLUDE\include $(DIR_ROOT)/make_conf.mk all:make_show make_subdir clean:make_clean include $(DIR_ROOT)/make_fun.mk app的makefile # ------------------------------------------- # FileName :xx/xx/makefile # Author :wind # Date :2018-1-16 # Description # # Level2 makefile. # # ------------------------------------------- # 设置当前路径 DIR_ROOT:../..# 添加递归子目录 DIR_LIST_SUB :\# 添加源文件 FILE_LIST_C \ main.c\FILE_LIST_CPP \FILE_LIST_S \# 添加头文件路径 DIR_LIST_INCLUDE\ $(DIR_ROOT)/module/test/hal\ $(DIR_ROOT)/module/test/drive\include $(DIR_ROOT)/make_conf.mk all:make_show make_app clean:make_clean include $(DIR_ROOT)/make_fun.mk drive的makefile # ------------------------------------------- # FileName :xx/xx/makefile # Author :wind # Date :2018-1-16 # Description # # Level2 makefile. # # ------------------------------------------- # 设置当前路径 DIR_ROOT:../..# 添加递归子目录 DIR_LIST_SUB :\# 添加源文件 FILE_LIST_C \ drive/test.c\ hal/test_hal.c\FILE_LIST_CPP \ drive/cpp_test.cpp\FILE_LIST_S \# 添加头文件路径 DIR_LIST_INCLUDE\ hal\ drive\include $(DIR_ROOT)/make_conf.mk all:make_show make_lib_a clean:make_clean include $(DIR_ROOT)/make_fun.mk 配置文件 make_conf.mk # ------------------------------------------- # FileName :make_set.inc # Author :wind # Date :2018-1-16 # Description # # 工程相关设置。 # # -------------------------------------------# 设置常用指令 # ------------------------------------------- RM rm -f MV mv -f MKDIR mkdir -p RMDIR rm -rf # 颜色输出 # ------------------------------------------- ECHO_END:\033[0m ECHO_GREEN:echo \033[32m ECHO_RED:echo \033[31m ECHO_YELLOW:echo \033[33m ECHO_BLUE:echo \033[34m ECHO_GREEN_YELLOW:echo \033[42;30m# 编译缺省设置 # -------------------------------------------# 默认编译 CXX:g#编译选项 COMPILE_C ? $(CXX) COMPILE_CXX ? $(CXX) COMPILE_ASM ? $(CXX) COMPILE_AR ? ar# 设置优化等级 OPT ?0# 设置警告开关 COMPILE_WARN ? -Wall # 设置静态编译 COMPILE_STATIC ? -s# 在环境基础下添加设置 CFLAGS $(DIR_LIST_INCLUDE_I) $(COMPILE_WARN) -O$(OPT) $(COMPILE_STATIC) CXXFLAGS $(DIR_LIST_INCLUDE_I) $(COMPILE_WARN) -O$(OPT) $(COMPILE_STATIC) ASFLAGS -Wa,-adhlns$(:.S.lst),-gstabs $(DIR_LIST_INCLUDE_I)# 编译设置汇总 COMPILE_CFLAGS $(CFLAGS) COMPILE_CXXFLAGS $(CXXFLAGS) COMPILE_ASFLAGS $(ASFLAGS)#链接选项 LDFLAGS -lstdc#编译C LDFLAGS -lpthread#使用了线程 LDFLAGS -fPIC#编译为位置独立的代码 LDFLAGS -ldl#引用动态库 LDFLAGS $(DIR_LIST_INCLUDE_I)#引用其他静态库 FILE_LIST_LIB_A\ 功能文件 make_fun.mk # ------------------------------------------- # FileName :make_fun.mk # Author :wind # Date :2018-1-16 # Description # # 实际编译过程。 #s # ------------------------------------------- # 路径关系 # ------------------------------------------- DIR_ROOT_REAL$(realpath $(DIR_ROOT)) NAME_MODULE : $(notdir $(CURDIR))#所在的文件夹名称 DIR_OUTPUT:$(DIR_ROOT)/output DIR_BIN:$(DIR_OUTPUT)/bin DIR_OBJ:$(DIR_OUTPUT)/obj DIR_LIB:$(DIR_OUTPUT)/lib# 路径处理成可用参数 # ------------------------------------------- DIR_LIST_INCLUDE_I:$(addprefix -I,$(DIR_LIST_INCLUDE))#添加编译选项-I DIR_LIST_SUB:$(addprefix $(CURDIR)/,$(DIR_LIST_SUB))#转换成绝对路径 DIR_CURDIR:$(subst $(DIR_ROOT_REAL),,$(CURDIR))#相对路径 DIR_OBJ_OUT:$(DIR_OBJ)$(DIR_CURDIR)#文件处理 FILE_LIST_OBJ:$(FILE_LIST_C:%.c%.o) FILE_LIST_OBJ$(FILE_LIST_CPP:%.cpp%.o) FILE_LIST_OBJ$(FILE_LIST_S:%.s%.o)FILE_LIST_OBJ:$(addprefix $(DIR_OBJ_OUT)/,$(FILE_LIST_OBJ))#转换成带绝对路径的中间文件 FILE_LIB_A:$(DIR_LIB)/libobj.a FILE_LIST_LIB_APP:$(DIR_BIN)/$(NAME_MODULE).bin# 函数库 # ------------------------------------------- make_root:make_start make_subdir make_end# 工程开始 make_start:$(ECHO_BLUE)\t-----------------------------$(ECHO_END)$(ECHO_BLUE)\t-\t [编译开始] \t -$(ECHO_END)$(ECHO_BLUE)\t-----------------------------$(ECHO_END)$(ECHO_BLUE)[COMPILE_C]$(COMPILE_C) [COMPILE_CFLAGS]$(COMPILE_CFLAGS)$(ECHO_END)$(ECHO_BLUE)[COMPILE_CXX]$(COMPILE_CXX) [COMPILE_CXXFLAGS]$(COMPILE_CXXFLAGS)$(ECHO_END)$(ECHO_BLUE)[COMPILE_ASM]$(COMPILE_ASM) [COMPILE_ASFLAGS]$(COMPILE_ASFLAGS)$(ECHO_END)$(ECHO_BLUE)[COMPILE_AR]$(COMPILE_AR) [LDFLAGS]$(LDFLAGS)$(ECHO_END)$(ECHO_BLUE)[OPT]$(OPT) $(ECHO_END)$(ECHO_BLUE)[COMPILE_STATIC]$(COMPILE_STATIC) $(ECHO_END)$(ECHO_BLUE)[FILE_LIST_LIB_A]$(FILE_LIST_LIB_A) $(ECHO_END)# 工程完成 make_end: $(ECHO_BLUE)[编译完成]$(ECHO_END) # 递归子目录 make_subdir:for list in $(DIR_LIST_SUB);\do\cd $$list make all|| exit 1;\done# 生成可执行文件 make_app:make_lib_a make_bin# 生成静态链接库 make_lib_a:make_obj$(MKDIR) dirname $(FILE_LIB_A)$(ECHO_YELLOW)[$(COMPILE_AR)]-rcs $(FILE_LIB_A) $(FILE_LIST_OBJ)$(ECHO_END)$(COMPILE_AR) -rcs $(FILE_LIB_A) $(FILE_LIST_OBJ)# 链接 make_bin:$(FILE_LIST_LIB_APP)# 编译 make_obj:$(FILE_LIST_OBJ)# 清除 make_clean:$(RMDIR) $(DIR_OUTPUT)# 显示参数方便调试 make_show:$(ECHO_GREEN_YELLOW)[DIR_CURDIR] $(DIR_CURDIR) $(ECHO_END)$(ECHO_GREEN)[FILE_LIST_C] $(FILE_LIST_C) $(ECHO_END)$(ECHO_GREEN)[DIR_LIST_INCLUDE] $(subst $(DIR_ROOT)/,[DIR_ROOT]/,$(DIR_LIST_INCLUDE)) $(ECHO_END)# 文件操作过程 # ------------------------------------------- # 编译过程成中间文件 $(DIR_OBJ_OUT)/%.o: %.c$(MKDIR) dirname $$(ECHO_YELLOW)[$(COMPILE_C)]$ -o $ $(ECHO_END)$(COMPILE_C) -c $(COMPILE_CFLAGS) $ -o $$(DIR_OBJ_OUT)/%.o: %.cpp$(MKDIR) dirname $$(ECHO_YELLOW)[$(COMPILE_CXX)]$ -o $ $(ECHO_END)$(COMPILE_CXX) -c $(COMPILE_CXXFLAGS) $ -o $$(DIR_OBJ_OUT)/%.o: %.s$(MKDIR) dirname $$(ECHO_YELLOW)[$(COMPILE_C)]$ -o $ $(ECHO_END)$(COMPILE_ASM) -c $(COMPILE_ASFLAGS) $ -o $# 链接成二进制文件 $(FILE_LIST_LIB_APP): $(FILE_LIB_A)$(MKDIR) dirname $$(ECHO_YELLOW)[$(COMPILE_C)]$ -o $ $(ECHO_END)$(COMPILE_C) $(LDFLAGS) -L$(DIR_LIB) -lobj $ $(FILE_LIST_LIB_A) -o $ 内容推荐 跟我一起写MakefileMakefile 使用总结项目实用makefileMakefile之大型工程项目子目录Makefile的一种通用写法 引用本地址 https://www.cnblogs.com/wittxie/p/9836097.html 转载于:https://www.cnblogs.com/wittxie/p/9836097.html
http://www.sadfv.cn/news/161044/

相关文章:

  • 某网络公司网站源码 蓝色建站企业网站源码wordpress添加新文章类型
  • 破解网站后台账号密码做打牌的网站怎么办
  • 淮安市建设局网站洛阳建设信息网站
  • html网站引导页模板免费域名注册个人服务器搭建
  • 中江建设银行网站网站建设怎样创建链接
  • 建设农家书屋官方网站做建材去什么网站
  • 建设银行的网站你打不开物业管理系统价格
  • 这么做国外网站的国内镜像站免费怎样搭建网站
  • html手机网站模板下载广东公司网站建设企业
  • 做自媒体怎么在其它网站搬运内容查看自己网站访问量
  • 网站收缩栏电脑iis做网站
  • 唐山诚达建设集团网站街区网站建设
  • 西安微信商城网站设计网站制作一键生成
  • 一个网站的优势有哪些百度网盘官方下载
  • 重庆正云环保建设网站网站开发包含上线吗
  • wordpress开发工作流6网站优化 代码优化
  • h5网站建设功能计划表cmseasy去版权
  • 网站建设南宁广告设计案例网站
  • 宝华路桥建设集团网站建网站 需要签署协议
  • 用wordpress开发网站模板下载商品推广
  • 做软装有什么网站找图片北京天津网站建设
  • 找网络公司做网站wordpress 考试系统
  • 关于医院网站建设的通知网站 f型
  • 找人做辅助的网站在线视频用什么网址
  • 杭州手机建站模板襄阳商城网站建设
  • 自己买服务器做视频网站做微商能利用的网站有哪些问题
  • 网站设计步骤及流程如何做网站教学
  • 医疗软件网站建设公司网站的建设建议
  • 杭州网站开发 网站建设免费发布招聘信息的平台有哪些
  • 建设公司起名卢镇seo网站优化排名