文件夹目录结构
mediaTest
├── android //具体平台对应的文件夹
│ ├── arm64
│ │ ├── include
│ │ ├── jni
│ │ │ ├── Android.mk
│ │ │ ├── Application.mk
│ │ │ └── compile_android_r16b_x64.sh
│ │ └── media_libs
│ └── arm
│ ├── include
│ ├── jni
│ │ ├── Android.mk
│ │ ├── Application.mk
│ │ ├── compile_android_r16b_x86.sh
│ │ └── readme
│ ├── media_libs
│ └── ndk_build
├── linux
│ ├── x64
│ │ ├── bin
│ │ ├── include
│ │ └── media_libs
│ └── x86
│ ├── bin
│ ├── include
│ └── media_libs
├── compile_android_x86.sh
├── compile_linux_x64.sh
├── compile_linux_x86.sh
├── makefile
├── media_files //使用到的数据文件
│ ├── g7221c
│ ├── g722_240
│ ├── g728
│ ├── g728_240
│ ├── red_opus_127
│ ├── test_mpeg.mp4
│ └── wo.h264
├── readme.todo
└── source
└── MediaDeadlockCheck.cpp
makefile
# Rules for all Makefiles
# 作者: yjj
# 日期: 2021/01/07
#
# 使用前必须传入以下参数
# ARCHNAME 编译平台
# DEMO_DIR 存放生成得执行文件得目录
# MEDIA_FILES_DIR 代码中使用到文件存放目录
.PHONY: init clean show check demo install
.PHONY: test1 test2 test3 test4
TOP := $(shell pwd)
INC_BASE_PATH = $(TOP)/$(PLATFORM)/$(ARCHNAME)/include
LNK_BASE_PATH = $(TOP)/$(PLATFORM)/$(ARCHNAME)/media_libs
DEMO_DIR = $(TOP)/$(PLATFORM)/$(ARCHNAME)/$(DEMODIR)
MEDIA_FILES_DIR = $(TOP)/$(MEDIAFILESDIR)
SRC_FILES_PATH = $(TOP)/source
#不同平台得参数配置
ifeq ($(PLATFORM),linux)
ifeq ($(ARCHNAME),x86)
CXXCOMPILER := g++
DEMONAME := MediaDeadlockCheck
PLATFORM_ARCH_SPECIAL := -m32
PLATFORM_ARCH_SPECIAL_LD := -m32
CXXDEF := -D_LINUX_ $(DEFINE_LIST)
CXXFLAG := -g -frtti -fexceptions -Wall -Wno-strict-aliasing -fPIE -pie
#-L指定链接库的搜索路径 -l 指定搜索链接库的名称 不指定-static默认使用动态链接
CXXLDFLAG := -L$(LNK_BASE_PATH) -fPIE -pie
LINKLIBS := -ldl -lpthread
EXTRAFLAG :=
#头文件搜索路径
INCFLAG := -I$(INC_BASE_PATH)
endif
ifeq ($(ARCHNAME),x64)
CXXCOMPILER := g++
DEMONAME := MediaDeadlockCheck
PLATFORM_ARCH_SPECIAL := -m64
PLATFORM_ARCH_SPECIAL_LD := -m64
CXXDEF := -D_LINUX_ $(DEFINE_LIST)
CXXFLAG := -g -frtti -fexceptions -Wall -Wno-strict-aliasing -fPIE -pie
#-L指定链接库的搜索路径 -l 指定搜索链接库的名称 不指定-static默认使用动态链接
CXXLDFLAG := -L$(LNK_BASE_PATH) -fPIE -pie
LINKLIBS := -ldl -lpthread
EXTRAFLAG :=
#头文件搜索路径
INCFLAG := -I$(INC_BASE_PATH)
endif
endif
ifeq ($(PLATFORM),android)
ifeq ($(ARCHNAME),x86)
CXXCOMPILER := arm-linux-androideabi-g++
ANDROID_NDK_ROOT := $(ANDROID_NDK_ROOT_R16)
DEMONAME := MediaDeadlockCheck
PLATFORM_ARCH_SPECIAL := --sysroot=$(ANDROID_NDK_ROOT)/sysroot -isystem $(ANDROID_NDK_ROOT)/sysroot/usr/include/arm-linux-androideabi -I$(ANDROID_NDK_ROOT)/sources/cxx-stl/llvm-libc++/include/ -I$(ANDROID_NDK_ROOT)/sources/cxx-stl/llvm-libc++abi/include -I$(ANDROID_NDK_ROOT)/sources/android/support/include -pie -fPIE
PLATFORM_ARCH_SPECIAL_LD := --sysroot=$(ANDROID_NDK_ROOT)/platforms/android-14/arch-arm -L$(ANDROID_NDK_ROOT)/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a -lc++_shared -pie -fPIE
CXXDEF := -D_LINUX_ -D_ANDROID_ -D__ANDROID_API__=14
CXXFLAG := -g -frtti -fexceptions -Wall -Wno-strict-aliasing
CXXLDFLAG := -L$(LNK_BASE_PATH)
LINKLIBS := -ldl
EXTRAFLAG :=
INCFLAG := -I$(INC_BASE_PATH)
endif
endif
#$(foreach <var>,<list>,<text>)
#这个函数的意思是,把参数<list>;中的单词逐一取出放到参数<var>;所指定的变量中,然后再执行< text>;所包含的表达式。每一次<text>;会返回一个字符串,循环过程中,<text>;的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>;所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
CXXFILES = $(foreach dir,$(SRC_FILES_PATH),$(wildcard $(dir)/*.cpp))
#替换文件后缀 ,也可以写成 OBJS = $(FILES:%.cpp=%.o)
OBJS_FILES := $(patsubst %.cpp,%.o, $(CXXFILES))
#替换OBJS_FILES前面的路径 为实际存放.o得路径
OUTPUT_OBJS_DIR = $(DEMO_DIR)/obj
OBJS_FILES := $(foreach files, $(OBJS_FILES), $(subst $(SRC_FILES_PATH), $(OUTPUT_OBJS_DIR), $(files)))
show:
@#make会打印每条命令,然后再执行,这就叫做回声(echoing)
@#在命令的前面加上@,就可以关闭回声
@echo "=============== $(ARCHNAME) show start==============="
@echo INC_BASE_PATH : $(INC_BASE_PATH)
@echo LNK_BASE_PATH : $(LNK_BASE_PATH)
@echo CXXCOMPILER : $(CXXCOMPILER)
@echo DEMO_DIR : $(DEMO_DIR)
@echo PLATFORM_ARCH_SPECIAL : $(PLATFORM_ARCH_SPECIAL)
@echo PLATFORM_ARCH_SPECIAL_LD : $(PLATFORM_ARCH_SPECIAL_LD)
@echo CXXDEF : $(CXXDEF)
@echo CXXFLAG : $(CXXFLAG)
@echo CXXLDFLAG : $(CXXLDFLAG)
@echo LINKLIBS : $(LINKLIBS)
@echo EXTRAFLAG : $(EXTRAFLAG)
@echo INCFLAG : $(INCFLAG)
@echo "=============== $(ARCHNAME) show end ==============="
#拆解编译过程到.o为止,然后统一链接
#g++ hello.cpp -o test
#1.预处理
#g++ -E hello.cpp -o hello.i
#2.编译
#g++ -S hello.i -o hello.s
#3.汇编
#g++ -c hello.s -o hello.o
#4.链接
#g++ hello.o -o hello
#可以考虑在之后添加静态库和动态库的生成
#Make命令允许对文件名,进行类似正则运算的匹配,主要用到的匹配符是%。比如,假定当前目录下有 f1.c 和 f2.c 两个源码文件,需要将它们编译为对应的对象文件。
#%.o: %.c
#等同于下面的写法。
#f1.o: f1.c
#f2.o: f2.c
#使用匹配符%,可以将大量同类型的文件,只用一条规则就完成构建。
$(OUTPUT_OBJS_DIR)/%.o: $(SRC_FILES_PATH)/%.cpp
@echo "小夫我要进来了!"
$(CXXCOMPILER) $(CXXDEF) $(PLATFORM_ARCH_SPECIAL) $(CXXFLAG) $(EXTRAFLAG) $(INCFLAG) -c -o $@ $<
demo: $(OBJS_FILES)
$(CXXCOMPILER) $(PLATFORM_ARCH_SPECIAL_LD) $(CXXLDFLAG) $(LINKLIBS) $(OBJS_FILES) -o $(DEMONAME)
clean:
@rm -rf $(DEMO_DIR)
check:
@if [ -z "${CXXCOMPILER}" ]; then echo "please set CXXCOMPILER "; exit 1; fi
init:
@if [ ! -d "$(DEMO_DIR)" ]; then mkdir $(DEMO_DIR); fi
@if [ ! -d "$(OUTPUT_OBJS_DIR)" ]; then mkdir $(OUTPUT_OBJS_DIR); fi
install: check show clean init demo
@cp $(LNK_BASE_PATH)/*.so $(DEMO_DIR)/
@mv $(DEMONAME) $(DEMO_DIR)/
@cp $(MEDIA_FILES_DIR)/* $(DEMO_DIR)/
test1:
@echo "放你妈屁,RNG会3:0 ?"
test2:
@echo "我不知道,我是猪!"
test3: test1 test2
@echo $<
@echo $@
@echo $?
@echo $^
test4:
@echo $(CXXFILES)
@echo $(OBJS_FILES)
编译脚本
linux_x86
compile_linux_x86.sh
#! /bin/sh
function compile_help()
{
echo "Usage: $0"
echo " $0 [options] [args]"
echo " "
echo "Options:"
echo " "
echo " -d 要传入的预编译宏"
echo " 当前支持如下预编译宏:USE_127 TEST_EnableCrypt"
}
function define_join()
{
cmd_list=`echo $* | sed -nr 's/-d //p'`
for arg in $cmd_list
do
echo "外部传入参数:"$arg
define_list=$define_list"-D"$arg" "
done
echo "预编译宏拼接:"$define_list
}
if [ "$1" == "-h" ]; then
compile_help
exit 0
elif [ "$1" == "-d" ]; then
define_join $*
else
echo "nothing to do before make !"
fi
make DEFINE_LIST="$define_list" PLATFORM=linux ARCHNAME=x86 DEMODIR=bin MEDIAFILESDIR=media_files -f makefile install
Android_arm
Android不采用makefile编译,使用jni,当然你也可以试试makefile,我的makefile里有Android的选项你可以参照linux_x86的编译脚本来改一下,但是它只支持r16b。
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#export LD_LIBRARY_PATH=./
LOCAL_MODULE:= MediaDeadlockCheck
MY_PROC_BASE_PATH := $(LOCAL_PATH)/../../..
LIB_PATH := $(MY_PROC_BASE_PATH)/android/x86/media_libs
LINK_LIB_PATH := -L$(LIB_PATH)
LOCAL_C_INCLUDES := $(MY_PROC_BASE_PATH)/android/x86/include
SRC_FILES_PATH := $(MY_PROC_BASE_PATH)/source
LOCAL_SRC_FILES := $(foreach dir,$(SRC_FILES_PATH),$(wildcard $(dir)/*.cpp))
LOCAL_CFLAGS += -D_LINUX_ -D_ANDROID_ -pie -fPIE
LOCAL_CFLAGS += -fvisibility=hidden -Wall -Wstrict-prototypes
LOCAL_LDFLAGS += $(LINK_LIB_PATH)
LOCAL_LDLIBS += -lz -ldl -pie -fPIE
LOCAL_SHARED_LIBRARIES :=
LOCAL_PRELINK_MODULE:= false
include $(BUILD_EXECUTABLE)
Application.mk
# it is needed for ndk-r5
APP_STL := c++_shared
#APP_STL := gnustl_shared
APP_CPPFLAGS := -frtti
APP_MODULES += MediaDeadlockCheck
APP_ABI := armeabi-v7a
APP_PLATFORM := android-14
compile_android_r16b_x86.sh
DEMO_DIR="../ndk_build"
LNK_BASE_PATH="../media_libs"
MEDIA_FILES_DIR="../../../media_files"
if [ ! -d "$DEMO_DIR" ]; then
mkdir $DEMO_DIR
else
rm -rf $DEMO_DIR
fi
echo "Android R16b x86 build start"
$ANDROID_NDK_ROOT_R16/ndk-build V=1 B=1 NDK_DEBUG=1 NDK_LIBS_OUT=$DEMO_DIR NDK_OUT=$DEMO_DIR
if [ $? != 0 ]; then
echo "Android R16b x86 build fail"
exit 1
else
echo "Android R16b x86 build success"
cp $LNK_BASE_PATH/*.so $DEMO_DIR/armeabi-v7a
cp $MEDIA_FILES_DIR/* $DEMO_DIR/armeabi-v7a
fi
readme
1.export ANDROID_NDK_ROOT_R16=/opt/android-ndk-r16b
2.usage: make_standalone_toolchain.py [-h] --arch
{arm,arm64,mips,mips64,x86,x86_64}
[--api API]
[--stl {gnustl,libc++,stlport}] [--force]
[-v]
[--package-dir PACKAGE_DIR | --install-dir INSTALL_DIR]
build standalone tools built by ${ANDROID_NDK_ROOT_R16}/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 --stl libc++ --force --install-dir /opt/myndk/standalone/android-ndk-r16b-arm