I Installed boost and created a make file that will link my static boost libraries to the main program, here is a snapshot of the Makefile that includes boost libs (please scroll down):
LIBRARY_PATH="-L/usr/lib \
-lboost_chrono-mt \
-lboost_date_time-mt \
-lboost_filesystem-mt \
-lboost_graph-mt \
-lboost_graph_parallel-mt \
-lboost_iostreams-mt \
-lboost_locale-mt \
-lboost_math_c99f-mt \
-lboost_math_c99l-mt \
-lboost_math_c99-mt \
-lboost_math_tr1f-mt \
-lboost_math_tr1l-mt \
-lboost_math_tr1-mt \
-lboost_mpi-mt \
-lboost_mpi_python-mt-py26 \
-lboost_mpi_python-mt-py27 \
-lboost_mpi_python-mt-py32 \
-lboost_prg_exec_monitor-mt \
-lboost_program_options-mt \
-lboost_python-mt-py26 \
-lboost_python-mt-py27 \
-lboost_python-mt-py32 \
-lboost_random-mt \
-lboost_regex-mt \
-lboost_serialization-mt \
-lboost_signals-mt \
-lboost_system-mt \
-lboost_test_exec_monitor-mt \
-lboost_thread-mt \
-lboost_timer-mt \
-lboost_unit_test_framework-mt \
-lboost_wave-mt \
-lboost_wserialization-mt"
all : main
$(CC) $(LIBRARY_PATH) $(OBJECTS) -o $(APPLICATION)
When running build there is an error saying this:
/usr/include/boost/system/error_code.hpp:214: undefined reference to
`boost::system::generic_category()'
To solve the problem I moved -lboost_system-mt to the command line of the compiler like so:
all : main
$(CC) $(LIBRARY_PATH) $(OBJECTS) -lboost_system-mt -o $(APPLICATION)
When I did that it works fine but I want my LIBRARY_PATH to be in one place and not on the command line.
How do solve LIBRARY_PATH variable to make this work?
so that this will run:
$(CC) $(LIBRARY_PATH) $(OBJECTS) -o $(APPLICATION)
The order of the libraries matter and in g++ libraries are read from right to left and this why the command line works. I would try to do something like
$(CC) $(OBJECTS) $(LIBRARY_PATH) -o $(APPLICATION)
If this is not enough try to sort the libraries in LIBRARY_PATH in such a way that libraries with less dependencies are on the right and libraries with more dependencies are on the left.
Related
I'm attempting to integrate an L2CAP server (in C - uses BlueKitchen's btstack) with a UDP server (in C++). To start, I've attempted to just add the code from the L2CAP server into the "main.cpp" file of the UDP server. I included all of the relevant C libraries and headers using extern "C" {...}. At first, I'd get errors on the include statements for the btstack files. I solved this by modifying the make file to include "INC = -I./directory/...". Next, I dealt with problems the g++ compiler found with the pasted C code (ex. adding spaces between literals and strings). After resolving those, it seems that none of the bstack files/functions are being linked properly as this is what I get when I attempt to "make":
"undefined reference to 'every single btstack function call in main.cpp'
My makefile. Note that a lot of this is probably unnecessary/does nothing. I was just trying anything and everything and borrowing lines from the btstack port makefile and seeing if they'd work.
CORE += \
btstack_chipset_bcm.c \
btstack_chipset_bcm_download_firmware.c \
btstack_control_raspi.c \
btstack_link_key_db_tlv.c \
btstack_run_loop_posix.c \
btstack_tlv_posix.c \
btstack_uart_posix.c \
btstack_slip.c \
hci_dump_posix_fs.c \
hci_transport_h4.c \
hci_transport_h5.c \
le_device_db_tlv.c \
main.c \
wav_util.c \
btstack_stdin_posix.c \
raspi_get_model.c \
rijndael.c
.INCLUDE : home/pi/udpDemo/inc/btstack-master/example/Makefile.inc
CC=g++
CFLAGS=-Wall -Wextra -pedantic -std=c++11
SRC=$(wildcard ./src/*.cpp)
OBJ=$(patsubst ./src/%.cpp, ./obj/%.o, $(SRC))
INC=-I./inc \
-I./inc/btsrc \
-I./inc/btsrc/ble \
-I./inc/btsrc/ble/gatt-service \
-I./inc/platform/embedded \
-I./inc/platform/posix \
-I./inc/chipset/bcm \
-I./inc/3rd-party/tinydir \
-I./inc/3rd-party/rijndael \
-I./inc/port/raspi \
-I./src
LDFLAGS += -lrt
VPATH += src
VPATH += inc/3rd-party/rijndael
VPATH += inc
VPATH += inc/btsrc \
VPATH += inc/btsrc/ble \
VPATH += inc/btsrc/ble/gatt-service \
VPATH += inc/platform/embedded \
VPATH += inc/platform/posix \
VPATH += inc/chipset/bcm \
VPATH += inc/3rd-party/tinydir \
VPATH += inc/3rd-party/rijndael \
VPATH += inc/port/raspi \
LIBS=
TARGET=test
bindir=/usr/local/bin
$(TARGET):$(OBJ)
$(CC) -o $# $^ $(CFLAGS)
$(OBJ):./obj/%.o:./src/%.cpp
$(CC) $(CFLAGS) -c $^ -o $# -I$(INC)
clean:
rm -rf $(TARGET) $(OBJ)
install:$(TARGET)
install -g root -o root $(TARGET) $(bindir)/$(TARGET)
uninstall:$(bindir)/$(TARGET)
rm $(bindir)/$(TARGET)
It looks like there are both makefile issues and compile issues here. Solving both at the same time is hard. Below is a simplified and commented (but untested) version of your makefile that might be a good starting point for you.
Your original makefile looks like it was including a lot of stuff from the btstack build system. It's usually not a good idea to mesh two separate projects together like that, both for technical and licensing reasons. The typical way to use third-party code is to compile that code into a library and then have your code link against that library. You'll have to consult the documentation for btstack for details on how to do that, I'm not familiar with that particular library.
# Which compiler to use
CC=g++
# Options to pass to the compiler
CFLAGS=-Wall -Wextra -pedantic -std=c++11
# Options to pass to the linker
LDFLAGS=-Wall -Wextra
LDFLAGS+=-lbtstack # Link with 'libbtstack.a'
LDFLAGS+=-L/path/to/btstack # Where to find the btstack libraries that were built separately
# Source files to compile (everything in 'src' directory)
SRC=$(wildcard src/*.cpp)
# Convert names of source files into their corresponding object files
OBJ=$(patsubst src/%.cpp, obj/%.o, $(SRC))
# Directories where headers are kept
INC=-Isrc
INC+=-I/path/to/btstack/headers
# Name of the program
TARGET=test
# Rule for linking the .o files together to build the program
$(TARGET): $(OBJ)
$(CC) $(LDFLAGS) -o $# $^
# Rule for making a .o file from a .cpp file
obj/%.o: src/%.cpp
$(CC) $(CFLAGS) -c $^ -o $# -I$(INC)
# Rule for deleting output and temporary files
clean:
rm -rf $(TARGET) $(OBJ)
This will compile all the .cpp files in your src directory and link them with libbtstack.a to create a program named test. After you build the btstack library, update the LDFLAGS and INC variables with the actual paths to the btstack library and headers, respectively.
I have the following make file:
CC=g++
CFLAGS=-c -Wall
REST_LIBS = -lssl -lcrypto -lboost_system -lcpprest
all: main
main: static_pack
g++ -std=c++14 -D DEBUG -Wfatal-errors -static -pthread -I$(basepath)/vendors/cpp-jwt/include -I$(basepath)/vendors/json/include \
-DTS=\"/ctts.json\" \
-DCS_PATH=\"/bin\" \
-DCTFS_ENC=\"/ctfs.enc\" \
-DUNTAR_PATH=\"/\" \
-DCLUSTER_PATH=\"/.clusters\" \
-o run main.cpp \
libmain.a && \
rm -rf debpkg/cs/usr/bin/cs debpkg/cs.deb && \
cp run debpkg/cs/usr/bin/cs && \
dpkg-deb -b debpkg/cs && \
mv debpkg/cs.deb .
static_pack: rest.o aes.o random.o
ar rcs libmain.a random.o aes/aes.o rest/rest.o
rest.o:
g++ -std=c++14 -Wfatal-errors -c $(REST_LIBS) -o rest/rest.o rest/rest.cpp
aes.o: random.o
g++ -std=c++14 -D DEBUG -Wfatal-errors -c -lcrypto -o aes/aes.o random.o aes/aes.cpp
random.o:
g++ -std=c++14 -Wfatal-errors -c -o random.o random.cpp
If I compile this to be dynamically linked I have no problems. However, when I try static compilation I get tons of errors such as:
aes.cpp:(.text+0x706): undefined reference to `EVP_DecryptInit_ex'
aes.cpp:(.text+0x732): undefined reference to `EVP_DecryptUpdate'
aes.cpp:(.text+0x763): undefined reference to `EVP_CIPHER_CTX_ctrl'
aes.cpp:(.text+0x792): undefined reference to `EVP_DecryptFinal_ex'
aes.cpp:(.text+0x7a1): undefined reference to `EVP_CIPHER_CTX_free'
Essentially none of the symbols are being found. I'm not sure what I need to do now. I've tried build my object files as static to but that fails. I've looked into linking order, but that seems right.
My question boils down to two things:
When static linking other objects, do those objects need to be statically compiled as well + archived?
What is wrong with my setup?
You don't need REST_LIBS for your rest.o rule, as it only compiles a source file. You need to pass those libraries to g++ in main rule - as part of it, g++ will call linker.
Ok so apparently linking happens in the opposite order than I thought... and I think it's possible I might have not been linking either originally as a fufu mistake.
REST_LIBS = -lboost_filesystem -lboost_system -lcpprest -lssl -lcrypto -ldl
# /usr/local/lib/libyaml-cpp.a
all: main
main: static_pack
g++ -std=c++14 -D DEBUG -Wfatal-errors -I$(basepath)/vendors/cpp-jwt/include -I$(basepath)/vendors/json/include \
-DTS=\"/ctts.json\" \
-DCS_PATH=\"/bin\" \
-DCTFS_ENC=\"/ctfs.enc\" \
-DUNTAR_PATH=\"/\" \
-DCLUSTER_PATH=\"/.clusters\" \
-o run main.cpp \
libmain.a $(REST_LIBS) -pthread && \
rm -rf debpkg/cs/usr/bin/cs debpkg/cs.deb && \
cp run debpkg/cs/usr/bin/cs && \
dpkg-deb -b debpkg/cs && \
mv debpkg/cs.deb .
I am trying to build one alljoyn application for openwrt.
I am getting the following error
usr/include/qcc/platform.h:32:2 error: #error No OS GROUP defined.
I am using Makefile to build my application.
I have two makefiles.
My top level Makefile's compile section looks like
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
C_INCLUDE_PATH="$(STAGING_DIR)/usr/include" \
CPLUS_INCLUDE_PATH="$(STAGING_DIR)/usr/include" \
CC="$(TARGET_CC)" \
WS=off \
EXTRA_CFLAGS="$(TARGET_CFLAGS) -DQCC_OS_GROUP_POSIX -DQCC_OS_LINUX" \
CROSS_COMPILE="$(TARGET_CROSS)" \
CPPFLAGS="-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/uClibc++ -fno-builtin -fno-rtti \
-nostdinc++ -fpermissive -Wno-error" \
LDFLAGS="$(TARGET_LDFLAGS) -lalljoyn -lcrypt -ldl $(GpioLdflags-y)"
endef
and the makefile inside src directory looks like as follows.
CC := $(CROSS_COMPILE)g++
all : aj-sample
%.o : %.cc
$(CC) -c $(EXTRA_CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $# $<
LIBS := -lalljoyn -luClibc++ -lpthread
aj-sample : aj-sample.o
$(LD) aj-sample.o $(LIBS) $<
clean :
-rm -f *.o
I also tried adding -DQCC_OS_GROUP_POSIX -DQCC_OS_LINUX in src level makefile. But the issue still remains same.
I have already installed the alljoyn from openwrt feeds which compiles successfully.
I appreciate any help.
I have massive cross compilation of omxplayer whcih I am trying to debug. The file is downloaded from here. Unfortunately there are over 5000 files so I can not upload the directory tree. Here is the make command that gets issued:
/path/to/cross/compiler/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ --sysroot=/mnt/root -Wall -L/mnt/root/lib -L/mnt/root/lib -L/mnt/root/usr/lib -L/mnt/root/usr/lib/omxplayer -L/mnt/root/opt/vc/lib -L/mnt/root/usr/lib/arm-linux-gnueabihf -L./ -ldbus-1 -lc -lWFC -lGLESv2 -lEGL -lbcm_host -lopenmaxil -lfreetype -lz -Lffmpeg_compiled/usr/local/lib/ -o omxplayer.bin linux/XMemUtils.o utils/log.o DynamicDll.o utils/PCMRemap.o utils/RegExp.o OMXSubtitleTagSami.o OMXOverlayCodecText.o BitstreamConverter.o linux/RBP.o OMXThread.o OMXReader.o OMXStreamInfo.o OMXAudioCodecOMX.o OMXCore.o OMXVideo.o OMXAudio.o OMXClock.o File.o OMXPlayerVideo.o OMXPlayerAudio.o OMXPlayerSubtitles.o SubtitleRenderer.o Unicode.o Srt.o KeyConfig.o OMXControl.o Keyboard.o omxplayer.o -lvchiq_arm -lvcos -lrt -lpthread -lavutil -lavcodec -lavformat -lavdevice -lavfilter -lswscale -lswresample -lpcre ./arm-linux-gnueabihf-pkg-config --libs dbus-1 -lrt
But then I get the following errors:
/path/to/cross/compiler/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.7.2/../../../../arm-linux-gnueabihf/bin/ld: warning: libavutil.so.51, needed by /mnt/root/usr/lib/arm-linux-gnueabihf/libpostproc.so.52, may conflict with libavutil.so.52
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_move_ref(AVFrame*, AVFrame*)':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase17av_frame_move_refEP7AVFrameS1_[_ZN13DllAvUtilBase17av_frame_move_refEP7AVFrameS1_]+0x8): undefined reference to `av_frame_move_ref'
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_unref(AVFrame*)':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase14av_frame_unrefEP7AVFrame[_ZN13DllAvUtilBase14av_frame_unrefEP7AVFrame]+0x4): undefined reference to `av_frame_unref'
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_alloc()':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase14av_frame_allocEv[_ZN13DllAvUtilBase14av_frame_allocEv]+0x0): undefined reference to `av_frame_alloc'
BitstreamConverter.o: In function `DllAvUtilBase::av_frame_free(AVFrame**)':
BitstreamConverter.cpp:(.text._ZN13DllAvUtilBase13av_frame_freeEPP7AVFrame[_ZN13DllAvUtilBase13av_frame_freeEPP7AVFrame]+0x4): undefined reference to `av_frame_free'
collect2: error: ld returned 1 exit status
make: *** [omxplayer.bin] Error 1
I traced the av_frame_unref function and the others to frame.h which is in both ffmpeg_compiled/usr/local/include/libavutil/frame.h and ffmpeg/libavutil/frame.h. Normally I would link to the .so library with -lframe or -Lffmpeg/libavutil/ -lframe, however, this is not a shared library (.so file) but an object file (.o file). I am pretty sure I do not have to link these manually, that's what the make file is for. Anyone shed some light on what is going on. Also, I will include my Makefile below (I also have a Makefile.include showing the cross compile options, I can post that as well if necessary)
Makefile:
SRC=linux/XMemUtils.cpp \
utils/log.cpp \
DynamicDll.cpp \
utils/PCMRemap.cpp \
utils/RegExp.cpp \
OMXSubtitleTagSami.cpp \
OMXOverlayCodecText.cpp \
BitstreamConverter.cpp \
linux/RBP.cpp \
OMXThread.cpp \
OMXReader.cpp \
OMXStreamInfo.cpp \
OMXAudioCodecOMX.cpp \
OMXCore.cpp \
OMXVideo.cpp \
OMXAudio.cpp \
OMXClock.cpp \
File.cpp \
OMXPlayerVideo.cpp \
OMXPlayerAudio.cpp \
OMXPlayerSubtitles.cpp \
SubtitleRenderer.cpp \
Unicode.cpp \
Srt.cpp \
KeyConfig.cpp \
OMXControl.cpp \
Keyboard.cpp \
omxplayer.cpp \
OBJS+=$(filter %.o,$(SRC:.cpp=.o))
all: omxplayer.bin
%.o: %.cpp
#rm -f $#
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $# -Wno-deprecated-declarations
version:
bash gen_version.sh > version.h
omxplayer.bin: version $(OBJS)
$(CXX) $(LDFLAGS) -o omxplayer.bin $(OBJS) -lvchiq_arm -lvcos -lrt -lpthread -lavutil -lavcodec -lavformat -lavdevice -lavfilter -lswscale -lswresample -lpcre `./arm-linux-gnueabihf-pkg-config --libs dbus-1` -lrt
#arm-unknown-linux-gnueabi-strip omxplayer.bin
clean:
for i in $(OBJS); do (if test -e "$$i"; then ( rm $$i ); fi ); done
#rm -f omxplayer.old.log omxplayer.log
#rm -f omxplayer.bin
#rm -rf $(DIST)
#rm -f omxplayer-dist.tar.gz
ffmpeg:
#rm -rf ffmpeg
make -f Makefile.ffmpeg
make -f Makefile.ffmpeg install
dist: omxplayer.bin
mkdir -p $(DIST)/usr/lib/omxplayer
mkdir -p $(DIST)/usr/bin
mkdir -p $(DIST)/usr/share/doc
cp omxplayer omxplayer.bin $(DIST)/usr/bin
cp COPYING $(DIST)/usr/share/doc/
cp README.md $(DIST)/usr/share/doc/README
cp -a ffmpeg_compiled/usr/local/lib/*.so* $(DIST)/usr/lib/omxplayer/
tar -czf omxplayer-dist.tar.gz $(DIST)
It looks like you need to pull in the function definition from the .o files at compile time. I found this article very helpful in explaining the theory behind this:
http://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking/
For more information on linking and compiling, I also highly recommend this book: http://www.network-theory.co.uk/docs/gccintro/index.html
I went around and mule-headedly started adding foo/bar.o instructions after g++, luckily I only had to put two of these: ffmpeg/libavutil/frame.o and ffmpeg/libavutil/buffer.o. I finally got omxplayer to install. Note, if Linux has taught me anything it's that just because something compiles doesn't mean that it will work.
In hindsight, this makes perfect sense and I should have done it before, problem is that most websites either deal with insanely trivial situations, like g++ -o foo.o bar.o or insanely complex cases where you are redefining pkg-config to be cross compile capable and then setting up a dozen flags before even using that. I find these large Makefiles are always difficult to deal with for novice programmers.
I am trying to build FFMPEG with libx264 for Android.
I can successfully build and use FFMPEG for Android but I realized that I need the ability to encode, therefore I am trying to build FFMPEG with x264.
I am using this tutorial to build FFmpeg for Android http://www.roman10.net/how-to-build-ffmpeg-for-android/
When trying to build FFMPEG I get an error:
"ERROR: libx264 not found"
And in my log it says:
"/usr/local/lib/libx264.a: could not read symbols: Archive has no
index; run ranlib to add one..."
I have the latest versions of both FFMPEG and x264.
I understand that FFMPEG looks for the header and libraries in usr/lib and usr/include, so in order to make it find x264 I use the cflags and ldflags:
--extra-cflags = " -I/usr/local/include "
--extra-ldflags = " -L/usr/local/lib "
I have tried building x264 with many different options that other people on the internet have said that i need. eg. --enable-shared, --enable-static, --disable-pthreads etc.
Some forums say enable this, others say no disable that.
Any help would be much appreciated,
Thanks
EDIT:
If I build FFmpeg with the simplest commands to include libx264 then it works.
ie.
./configure --enable-gpl --enable-libx264 --extra-cflags="-I/usr/local/include" --extra-ldflags="-L/usr/local/lib" --enable-static --enable-shared
However I need it to work for Android. The script I am using is:
NDK=~/Desktop/android-ndk-r7
PLATFORM=$NDK/platforms/android-8/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/darwin-x86
function build_one
{
./configure --target-os=linux \
--prefix=$PREFIX \
--enable-cross-compile \
--enable-shared \
--enable-static \
--extra-libs="-lgcc" \
--arch=arm \
--cc=$PREBUILT/bin/arm-linux-androideabi-gcc \
--cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \
--nm=$PREBUILT/bin/arm-linux-androideabi-nm \
--sysroot=$PLATFORM \
--extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS -I/usr/local/include" \
--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L $PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog -L/usr/local/lib " \
--enable-gpl \
--enable-libx264 \
--disable-everything \
--enable-demuxer=mov \
--enable-demuxer=h264 \
--disable-ffplay \
--enable-protocol=file \
--enable-avformat \
--enable-avcodec \
--enable-decoder=rawvideo \
--enable-decoder=mjpeg \
--enable-decoder=h263 \
--enable-decoder=mpeg4 \
--enable-decoder=h264 \
--enable-encoder=mjpeg \
--enable-encoder=h263 \
--enable-encoder=mpeg4 \
--enable-encoder=h264 \
--enable-parser=h264 \
--disable-network \
--enable-zlib \
--disable-avfilter \
--disable-avdevice \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make -j4 install
$PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
$PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -soname libffmpeg.so -shared -nostdlib -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a -lc -lm -lz -ldl -llog --warn-once --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a
}
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfpv3-d16 -marm -march=$CPU "
PREFIX=./android/$CPU
ADDITIONAL_CONFIGURE_FLAG=
build_one
I am guessing that some option in my configure command is conflicting with enabling libx264
NOTE: If I remove --enable-libx264 then it works
I had the same problem. But after downgrading NDK to version 5c it works as described by halfninja. (ubuntu 64bit). there seem to be some changes in the toolchain from 5 to 7.
timo#serverplusplus:/tmp/android-ffmpeg-x264/Project/jni$ ndk-build
Compile thumb : ffmpeg <= ffmpeg.c
Compile thumb : ffmpeg <= cmdutils.c
Executable : ffmpeg
Install : ffmpeg => libs/armeabi/ffmpeg
Compile thumb : videokit <= uk_co_halfninja_videokit_Videokit.c
Compile thumb : videokit <= ffmpeg.c
Compile thumb : videokit <= cmdutils.c
SharedLibrary : libvideokit.so
Install : libvideokit.so => libs/armeabi/libvideokit.so
The ffmpeg source code seems to be updated, and I could compile ffmpeg with x264 for Android NDK as the following.
1 Download the halfninja's android-ffmpeg-x264 git file from https://github.com/halfninja/android-ffmpeg-x264
2 At "halfninja-android-ffmpeg-x264-fe12be0/Project/jni" directory, modify "configure_ffmpeg.sh" to link "libgcc.a" for solving a problem that can not resolve "__aeabi_f2uiz".
./configure $DEBUG_FLAG --enable-cross-compile \
--arch=arm5te \
--enable-armv5te \
--target-os=linux \
--disable-stripping \
--prefix=../output \
--disable-neon \
--enable-version3 \
--disable-shared \
--enable-static \
--enable-gpl \
--enable-memalign-hack \
--cc=arm-linux-androideabi-gcc \
--ld=arm-linux-androideabi-ld \
--extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -I../x264 -Ivideokit" \
$featureflags \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-network \
--enable-filter=buffer \
--enable-filter=buffersink \
--disable-demuxer=v4l \
--disable-demuxer=v4l2 \
--disable-indev=v4l \
--disable-indev=v4l2 \
--extra-ldflags="-L../x264 -L../toolchain/lib/gcc/arm-linux-androideabi/4.4.3" \
--extra-libs="-lgcc"
3 Modify "Android.mk" to link new library "libswresample.a".
FFMPEG_LIBS := $(addprefix ffmpeg/, \
libavdevice/libavdevice.a \
libavformat/libavformat.a \
libavcodec/libavcodec.a \
libavfilter/libavfilter.a \
libswscale/libswscale.a \
libavutil/libavutil.a \
libswresample/libswresample.a \
libpostproc/libpostproc.a )
4 Replace ffmpeg.c and cmdutils.c in videokit directory with ones in ffmpeg directory.
5 Follow a procedure described in README.textile.
These are my working flags:
x264 (a recent stable):
./configure --cross-prefix=arm-linux-androideabi- \
--enable-pic \
--enable-static \
--disable-cli \
--disable-asm \
--host=arm-linux
ffmpeg (release/0.10):
./configure --enable-cross-compile \
--arch=arm5te \
--enable-armv5te \
--target-os=linux \
--disable-stripping \
--prefix=../output \
--disable-neon \
--enable-version3 \
--disable-shared \
--enable-static \
--enable-gpl \
--enable-memalign-hack \
--cc=arm-linux-androideabi-gcc \
--ld=arm-linux-androideabi-gcc \
--extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated" \
--disable-everything \
--enable-decoder=h264 \
--enable-demuxer=mov \
--enable-muxer=mp4 \
--enable-encoder=libx264 \
--enable-libx264 \
--enable-protocol=file \
--enable-decoder=aac \
--enable-encoder=aac \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-network \
--enable-filter=buffer \
--enable-filter=buffersink \
--enable-filter=scale \
--disable-demuxer=v4l \
--disable-demuxer=v4l2 \
--disable-indev=v4l \
--disable-indev=v4l2 \
--extra-cflags="-I../x264" \
--extra-ldflags="-L../x264" \
--extra-libs="-lgcc"
Obviously you will have to adjust the paths.
I've put together a Android build system for ffmpeg+x264 here:
https://github.com/guardianproject/android-ffmpeg
We're working on some wrapper Java too for running it, but that's not really usable yet.
I've discovered the --enable-static option does not have any effect on ffmpeg linking behaviour for libx264. I managed to build a copy of ffmpeg with libx264 included statically by editing the config.mak after I'd run ./configure
Build x264 from source in another directory
Add libx264.a to EXTRALIBS line in config.mak
Remove -lx264 from EXTRALIBS line in config.mak
Before
EXTRALIBS=-ldl -lX11 -lx264 etc.
After
EXTRALIBS=/home/adam/x264sourcebuild/libx264.a -ldl -lX11 etc.
I have met the same issue before, and I tried several times to find out the reason:
You must make sure the x264 and the ffmpeg are using same way to compile. like: using Android NDK. Using the same gcc compiler.
So you can not compile ffmpeg with this command:"--cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-", but compile the x264 without that.
Here is my x264 compile script:
./configure --prefix=$PREFIX \
--enable-static \
--enable-pic \
--disable-asm \
--disable-cli \
--host=arm-linux \
--cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi- \
--sysroot=$PLATFORM
make
sudo make install
sudo ldconfig