I'm trying to compile a relatively simple C++ program using emscripten for use in javascript (wasm). When I compile with the following settings
emcc ./lttb.cpp \
--bind \
--target=wasm32-unknown-unknown-wasm \
--optimize=3 \
-v \
-nostdlib \
-Wl,--export-all \
-Wl,--no-entry \
-Wl,--allow-undefined \
-s ALLOW_MEMORY_GROWTH=1 \
-o lttb.wasm
I get the following error:
In file included from ./lttb.cpp:3:
In file included from /usr/local/Cellar/emscripten/2.0.12/libexec/system/include/emscripten/bind.h:14:
In file included from /usr/local/Cellar/emscripten/2.0.12/libexec/system/include/libcxx/stddef.h:39:
/usr/local/Cellar/emscripten/2.0.12/libexec/system/include/libcxx/__config:1134:6: error: "No thread API"
# error "No thread API"
More details here
Most likely you are creating thread within lttb.cpp
In that case you must add:
-s USE_PTHREADS=1
It is also recommended to define in advance number of threads, e.g.:
-s PTHREAD_POOL_SIZE=7
Fixed it by changing build args to following
rm lttb.wasm
emcc ./lttb.cpp \
--bind \
--optimize=3 \
-Wl,--export-all \
-Wl,--allow-undefined \
-s ALLOW_MEMORY_GROWTH=1 \
--no-entry \
-o lttb.wasm
I believe it was the -nostdlib that was causing this particular issue (note: original build args were for a C wasm I was making, thus the necessary reconfiguration
Related
Using a Dockerfile, I'm attempting to build Clang version v8 along with its dependencies on Ubuntu 18.04. The reason I'm going through all this trouble is because I can't find a 32-bit version of the LLVM libraries. Even the LLVM packages themselves have only 64-bit variants of everything. Because of this, I'm not able to build my 32-bit applications using the LLVM toolchain at version 8. Using version 8 of LLVM is mandatory for reasons I won't go into here.
So far, here is what I have:
FROM ubuntu:18.04 AS build
ARG NUM_PARALLEL=8
RUN true \
&& dpkg --add-architecture i386 \
&& apt-get -qq update \
&& apt-get -qq install \
software-properties-common \
build-essential \
gcc-multilib \
g++-multilib \
git \
wget \
autoconf \
pkg-config \
m4 \
python-dev:i386 \
libcurl4-gnutls-dev:i386 \
libncurses-dev:i386 \
uuid-dev:i386 \
libx11-dev:i386 \
libxext-dev:i386 \
libtinfo-dev:i386 \
libedit-dev:i386 \
swig \
libedit-dev
python-dev
ENV CMAKE_BUILD_PARALLEL_LEVEL=$NUM_PARALLEL
# Ninja
RUN true \
&& git clone --depth 1 --branch v1.8.2 https://github.com/ninja-build/ninja.git \
&& cd ninja \
&& ./configure.py --bootstrap \
&& cp ninja /usr/local/bin
# CMake
RUN true \
&& git clone --depth 1 --branch v3.13.4 https://gitlab.kitware.com/cmake/cmake.git \
&& cd cmake \
&& ./bootstrap --parallel=$NUM_PARALLEL \
&& make -j$NUM_PARALLEL install
# Clang (See: https://clang.llvm.org/get_started.html)
RUN true \
&& git clone --depth 1 --branch llvmorg-8.0.0 https://github.com/llvm/llvm-project.git \
&& cd llvm-project \
&& cmake -G Ninja -B build -S llvm \
-D CMAKE_BUILD_TYPE=Release \
-D LLVM_BUILD_32_BITS:BOOL=ON \
-D LLVM_ENABLE_PROJECTS=all \
-D LLVM_BUILD_TESTS:BOOL=OFF \
-D LLVM_BUILD_EXAMPLES:BOOL=OFF \
-D LLVM_INCLUDE_EXAMPLES:BOOL=OFF \
-D LLVM_INCLUDE_TESTS:BOOL=OFF \
-D LLVM_INCLUDE_BENCHMARKS:BOOL=OFF \
&& cmake --build build -j $NUM_PARALLEL --target install
I get through compiling a little over 5200 translation units, which takes over an hour, only for it to fail:
[5232/6435] Linking CXX shared library lib/readline.so
FAILED: lib/readline.so
: && /usr/bin/c++ -fPIC -fPIC -fvisibility-inlines-hidden -m32 -Werror=date-time -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wno-comment -fdiagnostics-color -ffunction-sections -fdata-sections -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -Wno-macro-redefined -O3 -DNDEBUG -Wl,-z,defs -Wl,-z,nodelete -m32 -shared -Wl,-soname,readline.so -o lib/readline.so tools/lldb/scripts/Python/modules/readline/CMakeFiles/readline.dir/readline.cpp.o /usr/lib/x86_64-linux-gnu/libpython2.7.so /usr/lib/x86_64-linux-gnu/libedit.so && :
/usr/lib/x86_64-linux-gnu/libpython2.7.so: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
I followed the getting started page to understand how to build LLVM so far, but I must be missing something. They don't exactly go into 32-bit compilation in their examples. Can someone help me get this building? Or at least (and probably better), point me to a version of Clang v8 that has 32-bit LLVM libraries bundled with it?
Seems like you are linking against the wrong Python: usr/lib/x86_64-linux-gnu/libpython2.7.so.
You may want to for it and add it to the CMake commands:
-DPYTHON_EXECUTABLE=PATH_TO_PYTHON-DEV:i686
You may also need to set PYTHON_LIBRARY and PYTHON_INCLUDE_DIR to make sure that the i386 versions are used.
I'm building my first OpenCV based application in C++. My goal is to build an intermediate docker image that can compile the application statically so that it can run standalone in the resulting smaller image. I'm open to using any docker image for this step, but just so that you can see exactly what I have, here's the dockerfile to reproduce the entire environment:
FROM ubuntu:18.04 as compiler
ENV OPENCV_VERSION='3.4.2' DEBIAN_FRONTEND=noninteractive
RUN apt-get -y update && \
apt-get -y upgrade && \
apt-get -y dist-upgrade && \
apt-get -y autoremove && \
apt-get install -y build-essential cmake
RUN apt-get install -y qt5-default libvtk6-dev
RUN apt-get install -y zlib1g-dev libjpeg-dev libwebp-dev libpng-dev libtiff5-dev libopenexr-dev libgdal-dev
RUN apt-get install -y libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev libtheora-dev libvorbis-dev libxvidcore-dev libx264-dev yasm libopencore-amrnb-dev libopencore-amrwb-dev libv4l-dev libxine2-dev
RUN apt-get install -y unzip wget
RUN wget --progress=dot:giga https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.zip && \
unzip -q ${OPENCV_VERSION}.zip && \
rm ${OPENCV_VERSION}.zip && \
mv opencv-${OPENCV_VERSION} OpenCV && \
cd OpenCV && \
mkdir build && \
cd build && \
cmake \
-D BUILD_SHARED_LIBS=OFF \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D FORCE_VTK=ON \
-D WITH_TBB=ON \
-D WITH_GDAL=ON \
-D WITH_XINE=ON \
-D BUILD_EXAMPLES=OFF \
-D ENABLE_PRECOMPILED_HEADERS=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_opencv_apps=OFF \
.. && \
make -j4 && \
make install && \
ldconfig
COPY compile-test.cpp compile-test.cpp
RUN g++ -std=c++11 -static compile-test.cpp -o /app $(pkg-config --cflags --libs opencv)
I can currently compile my c++ apps without issue using the dyanmic libs, but this creates a massive docker image, and I really want to be able to build standalone binaries for distribution, with minimal size.
As you can see I'm compiling OpenCV from source including the flag BUILD_SHARED_LIBS=OFF to make sure I get the .a static libs, rather than the .so dynamic libs. I took a hint from a highly recommended build script, and modified it for use with docker omitting a few python things as I'm using c++.
Because I was having so much trouble with my real application, I've gone ahead and created a much simpler app, which also blows up during compilation. I believe this has something to do with the included cflags and libs. The problem is currently beyond my comprehension. I get mountains of errors that seem to change when I adjust a single include on my compile command. Here's the simplest app I'm trying to compile. It really doesn't do anything, but it does include a lib.
#include "opencv2/imgcodecs.hpp"
using namespace cv;
Mat img;
int main( int argc, char** argv ) {
img = cv::imread( argv[1], IMREAD_COLOR );
}
Then I try to compile this like so:
g++ -std=c++11 -static compile-test.cpp -o /app $(pkg-config --cflags --libs opencv)
And it ends up in a pile of errors much too long to completely paste here.
//usr/local/lib/libopencv_imgcodecs.a(grfmt_jpeg.cpp.o): In function `cv::JpegEncoder::write(cv::Mat const&, std::vector<int, std::allocator<int> > const&)':
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0xf8): undefined reference to `jpeg_CreateCompress'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x105): undefined reference to `jpeg_std_error'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x2b5): undefined reference to `jpeg_set_defaults'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x2d0): undefined reference to `jpeg_set_quality'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x2fe): undefined reference to `jpeg_quality_scaling'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x30d): undefined reference to `jpeg_quality_scaling'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x367): undefined reference to `jpeg_default_qtables'
grfmt_jpeg.cpp:(.text._ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0x379): undefined reference to `jpeg_start_compress'
grfmt_jpeg.cpp:
...
collect2: error: ld returned 1 exit status
Some Things I've Already Tried
Beginning to google each of the seemingly unique compile errors and adding related flags to the end of my compile code.
Reordering some of the include flags, but there are just too many to do this effectively
Using the opencv-dev package instead of compiling it myself, but it seems you can't do this and expect to use static libs.
After a lot of experimentation I finally got something working! There were a few issues that are all fixed in this Dockerfile. In order to reproduce this, create a Dockerfile with the following contents, and create another file called app.cpp with the simple code from my question above, in the same folder.
I will explain what the issues were below:
FROM alpine:3.8 as compiler
RUN echo -e '#edgunity http://nl.alpinelinux.org/alpine/edge/community \
#edge http://nl.alpinelinux.org/alpine/edge/main \
#testing http://nl.alpinelinux.org/alpine/edge/testing \
#community http://dl-cdn.alpinelinux.org/alpine/edge/community' \
>> /etc/apk/repositories
RUN apk add --update --no-cache \
build-base \
openblas-dev \
unzip \
wget \
cmake \
g++ \
libjpeg \
libjpeg-turbo-dev \
libpng-dev \
jasper-dev \
tiff-dev \
libwebp-dev \
clang-dev \
linux-headers
ENV CC /usr/bin/clang
ENV CXX /usr/bin/g++
ENV OPENCV_VERSION='3.4.2' DEBIAN_FRONTEND=noninteractive
RUN mkdir /opt && cd /opt && \
wget https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.zip && \
unzip ${OPENCV_VERSION}.zip && \
rm -rf ${OPENCV_VERSION}.zip
RUN mkdir -p /opt/opencv-${OPENCV_VERSION}/build && \
cd /opt/opencv-${OPENCV_VERSION}/build && \
cmake \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_TESTS=OFF \
-D CMAKE_BUILD_TYPE=RELEASE \
-D ENABLE_PRECOMPILED_HEADERS=OFF \
-D FORCE_VTK=OFF \
-D WITH_FFMPEG=OFF \
-D WITH_GDAL=OFF \
-D WITH_IPP=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENGL=OFF \
-D WITH_QT=OFF \
-D WITH_TBB=OFF \
-D WITH_XINE=OFF \
-D BUILD_JPEG=ON \
-D BUILD_TIFF=ON \
-D BUILD_PNG=ON \
.. && \
make -j$(nproc) && \
make install && \
rm -rf /opt/opencv-${OPENCV_VERSION}
RUN wget --progress=dot:giga https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.0.0-linux-x86-64.tar.gz && \
pwd && \
tar -xzf libwebp-1.0.0-linux-x86-64.tar.gz && \
mv /libwebp-1.0.0-linux-x86-64/lib/libwebp.a /usr/lib && \
rm -rf /libwebp*
RUN wget --progress=dot:giga http://www.ece.uvic.ca/~frodo/jasper/software/jasper-2.0.10.tar.gz && \
tar -xzf jasper-2.0.10.tar.gz && \
cd jasper-2.0.10 && \
mkdir BUILD && \
cd BUILD && \
cmake -DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SKIP_INSTALL_RPATH=YES \
-DCMAKE_INSTALL_DOCDIR=/usr/share/doc/jasper-2.0.10 \
-DJAS_ENABLE_SHARED=FALSE \
.. && \
make install && \
rm -rf /jasper-2.0.10*
ENV PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/lib/pkgconfig
COPY app.cpp app.cpp
RUN g++ -Wl,-Bstatic -static-libgcc -std=c++11 \
app.cpp \
-o /app \
$(pkg-config --cflags --libs -static opencv) \
-lgfortran -lquadmath
FROM alpine
COPY --from=compiler /app /bin/app
Problems
Linker
There were indeed files that needed linking that weren't present, there were two reasons for this:
The pkg-config command is supposed to emit all of the necessary flags for compilation, but in my earlier attempt I hadn't included the -static flag to pkg-config. When you add the -static flag it makes sure to link the extra required packages. I saw a few people run into this problem with the solution of adding the extra flags like -pthread, but I found that the -static flag did this for me and so was preferable.
ld: cannot find -lgcc_s error. This appeared to be fixed by adding the -static-libgcc flag to g++. Some of this is still a mystery to me.
Missing Static Libraries
There were two libraries that I wanted to be included as static which needed to be acquired from sources other than apk. These were libjasper and libwebp. There are build steps above that acquire and build these as necessary and copy the resources into the required place.
More missing links
For reasons I can't yet explain pkg-config didn't provide the last two necessary flags. Those were -lgfortran and -lquadmath.
Notes about this Solution
I switched to alpine linux, just because I had read that some people had success with that, I'm sure the same could be done with Ubuntu. It did result in a much smaller image, so I do like that. This is about 900mb for the intermediate image, which, while huge, is much smaller than the 1.9GB Ubuntu image.
The actual resulting image is about 44mb including all of the statically linked OpenCV libs. This seems like a good solution for those that need a small docker image to run a single C++ bin.
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.
I've got a Stellaris Launchpad board with a Cortex M4F on it. I want to use FreeRTOS on the board with some of my own C++ code. FreeRTOS, however, is written in C so will not compile with G++; I've tried.
I read somewhere that I should compile FreeRTOS with gcc, then compile my application code with g++, then pull them together using the linker. This makes sense, but I'm really struggling with how to put this behaviour down in a Makefile. I found this Makefile which just confused me more.
Currently, I'm just using the Makefile distributed with the FreeRTOS example in the Stellaris demos, but that's set up for C code only. This question is asking something similar to what I'm after, but I can't wrap my head around how to compile FreeRTOS with GCC and the rest of my code with G++.
FreeRTOS apparently wraps it's code in extern "C" { } directives but attempting using G++ still fails when compiling the FreeRTOS codebase.
I don't like posting large amounts of code on SO, but the more information the better I suppose. The Stellaris demos have a common makedefs file:
# Get the operating system name. If this is Cygwin, the .d files will be
# munged to convert c: into /cygdrive/c so that "make" will be happy with the
# auto-generated dependencies.
os:=${shell uname -s}
# The compiler to be used.
ifndef COMPILER
COMPILER=gcc
endif
# Definitions for using GCC.
ifeq (${COMPILER}, g++)
# Get the prefix for the tools to use. Use arm-stellaris-eabi if it exists,
# otherwise fall back to arm-none-eabi.
PREFIX=${shell type arm-stellaris-eabi-gcc > /dev/null 2>&1 && \
echo arm-stellaris-eabi || echo arm-none-eabi}
# The command for calling the compiler.
CC=${PREFIX}-${COMPILER}
# The location of the C compiler
# ARMGCC_ROOT is used by some makefiles that need to know where the compiler
# is installed. It is not used further for normal stellarisware apps
ARMGCC_ROOT:=${shell dirname '${shell sh -c "which ${CC}"}'}/..
# Determine the compiler CPU/FPU options based on the processor variant.
ifndef VARIANT
CPU=-mcpu=cortex-m3
FPU=
else
ifeq (${VARIANT}, cm3)
CPU=-mcpu=cortex-m3
FPU=
else
ifeq (${VARIANT}, cm4f)
CPU=-mcpu=cortex-m4
FPU=-mfpu=fpv4-sp-d16 -mfloat-abi=softfp
else
$(error Unknown processor variant ${VARIANT}!)
endif
endif
endif
# The flags passed to the assembler.
AFLAGS=-mthumb \
${CPU} \
${FPU} \
-MD
# The flags passed to the compiler.
CFLAGS=-mthumb \
${CPU} \
${FPU} \
-Os \
-ffunction-sections \
-fdata-sections \
-MD \
-Wall \
-pedantic \
-DPART_${PART} \
-c
# The command for calling the library archiver.
AR=${PREFIX}-ar
# The command for calling the linker.
LD=${PREFIX}-ld
# The flags passed to the linker.
LDFLAGS=--gc-sections
# Get the location of libgcc.a from the GCC front-end.
LIBGCC=${shell ${CC} ${CFLAGS} -print-libgcc-file-name}
# Get the location of libc.a from the GCC front-end.
LIBC=${shell ${CC} ${CFLAGS} -print-file-name=libc.a}
# Get the location of libm.a from the GCC front-end.
LIBM=${shell ${CC} ${CFLAGS} -print-file-name=libm.a}
# The command for extracting images from the linked executables.
OBJCOPY=${PREFIX}-objcopy
# Tell the compiler to include debugging information if the DEBUG environment
# variable is set.
ifdef DEBUG
CFLAGS+=-g -D DEBUG
endif
# Add the tool specific CFLAGS.
CFLAGS+=${CFLAGSgcc}
# Add the include file paths to AFLAGS and CFLAGS.
AFLAGS+=${patsubst %,-I%,${subst :, ,${IPATH}}}
CFLAGS+=${patsubst %,-I%,${subst :, ,${IPATH}}}
# The rule for building the object file from each C source file.
${COMPILER}${SUFFIX}/%.o: %.c
#if [ 'x${VERBOSE}' = x ]; \
then \
echo " CC ${<}"; \
else \
echo ${CC} ${CFLAGS} -D${COMPILER} -o ${#} ${<}; \
fi
#${CC} ${CFLAGS} -D${COMPILER} -o ${#} ${<}
ifneq ($(findstring CYGWIN, ${os}), )
#sed -i -r 's/ ([A-Za-z]):/ \/cygdrive\/\1/g' ${#:.o=.d}
endif
# The rule for building the object file from each assembly source file.
${COMPILER}${SUFFIX}/%.o: %.S
#if [ 'x${VERBOSE}' = x ]; \
then \
echo " AS ${<}"; \
else \
echo ${CC} ${AFLAGS} -D${COMPILER} -o ${#} -c ${<}; \
fi
#${CC} ${AFLAGS} -D${COMPILER} -o ${#} -c ${<}
ifneq ($(findstring CYGWIN, ${os}), )
#sed -i -r 's/ ([A-Za-z]):/ \/cygdrive\/\1/g' ${#:.o=.d}
endif
# The rule for creating an object library.
${COMPILER}${SUFFIX}/%.a:
#if [ 'x${VERBOSE}' = x ]; \
then \
echo " AR ${#}"; \
else \
echo ${AR} -cr ${#} ${^}; \
fi
#${AR} -cr ${#} ${^}
# The rule for linking the application.
${COMPILER}${SUFFIX}/%.axf:
#if [ 'x${SCATTERgcc_${notdir ${#:.axf=}}}' = x ]; \
then \
ldname="${ROOT}/${COMPILER}/standalone.ld"; \
else \
ldname="${SCATTERgcc_${notdir ${#:.axf=}}}"; \
fi; \
if [ 'x${VERBOSE}' = x ]; \
then \
echo " LD ${#} ${LNK_SCP}"; \
else \
echo ${LD} -T $${ldname} \
--entry ${ENTRY_${notdir ${#:.axf=}}} \
${LDFLAGSgcc_${notdir ${#:.axf=}}} \
${LDFLAGS} -o ${#} $(filter %.o %.a, ${^}) \
'${LIBM}' '${LIBC}' '${LIBGCC}'; \
fi; \
${LD} -T $${ldname} \
--entry ${ENTRY_${notdir ${#:.axf=}}} \
${LDFLAGSgcc_${notdir ${#:.axf=}}} \
${LDFLAGS} -o ${#} $(filter %.o %.a, ${^}) \
'${LIBM}' '${LIBC}' '${LIBGCC}'
#${OBJCOPY} -O binary ${#} ${#:.axf=.bin}
endif
The above file is included by the Makefile itself (below):
# Defines the part type that this project uses.
PART=LM4F120H5QR
# Set the processor variant.
VARIANT=cm4f
# The base directory for StellarisWare.
ROOT=../lib
COMPILER=gcc
# Include the common make definitions.
include ${ROOT}/makedefs
# Where to find source files that do not live in this directory.
VPATH=${ROOT}/FreeRTOS/Source/portable/GCC/ARM_CM4F
VPATH+=${ROOT}/FreeRTOS/Source/portable/MemMang/
VPATH+=${ROOT}/FreeRTOS/Source
VPATH+=${ROOT}/drivers
VPATH+=${ROOT}/utils
# Where to find header files that do not live in the source directory.
IPATH=.
IPATH+=..
IPATH+=${ROOT}
IPATH+=${ROOT}/FreeRTOS/Source/portable/GCC/ARM_CM4F
IPATH+=${ROOT}/FreeRTOS
IPATH+=${ROOT}/FreeRTOS/Source/include
IPATH+=${ROOT}
# The default rule, which causes the FreeRTOS example to be built.
all: ${COMPILER}
all: ${COMPILER}/freertos_demo.axf
# The rule to clean out all the build products.
clean:
#rm -rf ${COMPILER} ${wildcard *~}
# The rule to create the target directory.
${COMPILER}:
#mkdir -p ${COMPILER}
# Rules for building the FreeRTOS example.
${COMPILER}/freertos_demo.axf: ${COMPILER}/buttons.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/freertos_demo.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/heap_2.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/led_task.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/list.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/port.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/queue.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/rgb.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/startup_${COMPILER}.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/switch_task.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/tasks.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/uartstdio.o
${COMPILER}/freertos_demo.axf: ${COMPILER}/ustdlib.o
${COMPILER}/freertos_demo.axf: ${ROOT}/driverlib/${COMPILER}-cm4f/libdriver-cm4f.a
${COMPILER}/freertos_demo.axf: freertos_demo.ld
SCATTERgcc_freertos_demo=freertos_demo.ld
ENTRY_freertos_demo=ResetISR
CFLAGSgcc=-DTARGET_IS_BLIZZARD_RA1
# Include the automatically generated dependency files.
ifneq (${MAKECMDGOALS},clean)
-include ${wildcard ${COMPILER}/*.d} __dummy__
endif
Some of my directory structure is as follows:
Projects/
lib/
FreeRTOS/
driverlib/
drivers/
inc/
utils/
makedefs
TestProject/
loads.cpp
of.cpp
files.h
here.h
Makefile
If I'm correct in saying that FreeRTOS must be compiled with GCC, then linked with my C++ project code, how can I modify my current Makefile to do that? I want a reasonably generic solution so I can re-use it in other projects, but I don't know much about the C/C++ build process or Makefiles, hence me asking this (lengthy) question. I don't want/mean to sound like I'm asking a "do this for me" question, but I really cannot work out how to do this despite searching on Google and on SO.
I don't use FreeRTOS with C++ myself, but it has been discussed many times on the FreeRTOS forum and there are a few C++ frameworks in the FreeRTOS Interactive site.
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