FFmpeg on Android with Rubberband - ffmpeg

When I try to link librubberband.a I get:
libavfilter/af_rubberband.c:236: error: undefined reference to 'rubberband_set_pitch_scale'
I compiled rubberband for armv7a, and created a static library (rubberband.a).
I checked the library, and It contained the needed symbols (using nm).
I verified that librubberband.a is in the libpath (-L)
I verified that extern C exists in the rubberband.c.h file.
Any ideas?

The error happened in the link stage. Make sure the link directory has been added to -L parameters of your compiler.
-L/directory/of/your/lib
And specify the library with -l option.
So make sure the option -L/directory/of/your/lib -lrubberband set for your compiler when you build ffmpeg with rubberband support.
If you didn't use pkg-config to add the library. You can use the option --extra-ldflags to add when configure ffmpeg before build.
./configure \
# some configure options
--extra-ldflags="-L/directory/of/your/lib -lrubberband" \
# more configure options
If you use pkg-config to find out the libraries. Just add the library.pc directory to PKG_CONFIG_PATH, and let the build system do the remaining.
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/directory/to/your/rubberband.pc
Updated
Finally make sure you link against to the same architecture of your library.
$ arm-linux-androideabi-readelf -h librubberband.a |grep 'Class\|Machine
For armeabi-v7a, it should be ELF32 and ARM.
Updated
I have cloned the source of rubberband from https://bitbucket.org/breakfastquay/rubberband
And found the function call rubberband_set_pitch_scale is defined at src/rubberband-c.cpp, this file is not include in Android.mk when build for Android (WHY?).
So you have to add this file to build.
RUBBERBAND_SRC_FILES = ... \
$(RUBBERBAND_SRC_PATH)/rubberband-c.cpp
After build done, you need to create directory structure like below
.
├── include
│   └── rubberband
│   ├── RubberBandStretcher.h
│   └── rubberband-c.h
└── lib
├── librubberband.a
└── pkgconfig
└── rubberband.pc
The file rubberband.pc was copied from rubberband.in.pc with some minor changes.
prefix=/path/to/rubberband/install/root
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: rubberband
Version: 1.8.1
Description:
Libs: -L${libdir} -lrubberband -L/path/to/android/ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -lgnustl_static
Cflags: -I${includedir}
Then add
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/rubberband/install/root
before ./configure to tell ffmpeg find rubberband by pkg-config.
I have tried with the latest ffmpeg, it works.

Related

Using functions from an xcframework containing an external static C library within an Xcode project

I have a C file containing a function my_library_function() that I have compiled into a static library using gcc and packaged into an xcframework called mylib.xcframework using xcodebuild -create-framework. I have added this framework to an Xcode project for a Mac App. However within my Mac App I am unable to call this function, and am generally unsure about how to do so. I have tried import mylib from within Swift files and tried to directly call the function my_library_function() but in both cases have gotten compiler errors No such module mylib and Use of unresolved identifier 'my_library_function'. The only workaround I have found is to create a bridging header and #include the header file from its path within the xcframework. However, since eventually I would like to work with a more complex library and cross compile and have the xcframework include static libraries for multiple targets this seems like a hacky workaround. Is there some way I can do this without the bridging headers, am I missing something in this process?
Below are exact instructions of exactly what I did.
First I compiled the C code into a static library. The source code for the library contains a single function:
#include <stdio.h>
void my_library_function(void) {
printf("called from a static library");
}
mylib.c
I also have a header for the above:
void my_library_function(void);
mylib.h
The tree for the source code is as follows:
.
├── include
│   └── mylib.h
└── mylib.c
Project source tree
I then compiled the C code into a static library using:
> gcc -c mylib.c -o mylib.o
> ar rcs mylib.a mylib.o
Then I created an xcframework with:
xcodebuild -create-xcframework -library mylib.a -headers include -output mylib.xcframework
This resulted in an xcframework as so:
.
├── Info.plist
└── macos-x86_64
├── Headers
│   └── mylib.h
└── mylib.a
mylib.xcframework source tree
I then created a new Xcode project using Xcode 11.
At the root of the project I created a new group and called it Frameworks. I then dragged and dropped the xcframework into XCode frameworks group and checked the copy items if needed checkbox and the create groups radio button.
In the Xcode projects general tab, under Frameworks, Libraries and Embedded Content I set the framework to Embed & Sign.
Under the Build Settings tab, under Signing, I set Other Code Signing Flags to --deep to prevent a codesign error. In the same Build Settings tab, under Linking, the Runpath Search Paths is set to #executable_path/../Frameworks/. Additionally in the Build Settings tab under Search Paths, I have tried to set the Framework Search Paths, Library Search Paths and Header Search Paths to this same value #executable_path/../Frameworks/ and I have also tried with these paths as empty.
Unfortunately I am not able to use the my_library_function() from anywhere in the application, nor am I able to import mylib from Swift.
The only workaround I have found is to create an objective C bridging header and make a #include explicitly point within the framework folder into the Headers/mylib.h to be able to call my function. This seems like a hacky solution though as eventually I would like to cross compile my code and will have separate header files for each separate library for different architectures and it might get quite complex to do it this way. Is there something I am missing as to how to include my function from within an XCFramework with a MacOS Swift project?
Below are some images of my Xcode configuration:
I built with clang instead of gcc and included a clang modulemap file alongside the header. It now builds and even offers Xcode autocompletion.

Facing issue with makefile for Hello pass in llvm

I am new to llvm, am trying to write a pass for llvm Hello
I have downloaded and built llvm in linux machine by following the link http://llvm.org/docs/GettingStarted.html
I have tried to write a pass by following the link http://llvm.org/docs/WritingAnLLVMPass.html
I have copied the makefile specified in the link to the Hello folder in llvm and tried to perform a make. But I encounter the below error.
Makefile:14: ../../../Makefile.common: No such file or directory
make: *** No rule to make target `../../../Makefile.common'. Stop.
I understand that it is not able to find the Makefile.common. But most of the stuff in llvm is readonly and downloaded from the svn repository.
Can anyone assist me with this issue? Am I missing anything, am I following the correct way?
Is there any better tutorial anyone can refer?
TIA
LLVM now builds with CMake, so that old Makefile won't work. The same tutorial you linked points out how to write the CMakeLists.txt.
Out-of-tree build
Set up a directory structure like this:
HelloPassProject
├── build
├── CMakeLists.txt
└── HelloPass
├── CMakeLists.txt
└── HelloPass.cpp
So there's a top-level HelloPassProject, which contains the root CMakeLists.txt, a build directory where we'll build our pass and a HelloPass directory containing the actual pass source and the pass CMakeLists.txt.
Contents of HelloPassProject/CMakeLists.txt:
find_package(LLVM REQUIRED CONFIG)
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(AddLLVM)
add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})
add_subdirectory(HelloPass)
Contents of HelloPassProject/HelloPass/CMakeLists.txt (list your sources here):
add_llvm_loadable_module(LLVMHelloPass HelloPass.cpp)
To build against an installed LLVM:
cd HelloPassProject/build
cmake ..
make
To build against an LLVM you've built from source (let's say it's been built in ~/llvm-project/build):
cd HelloPassProject/build
cmake -DCMAKE_PREFIX_PATH=~/llvm-project/build ..
make
In-tree build
You just need the HelloPass subdirectory from the out-of-tree build. Copy that inside <LLVM root>/lib/Transform. Add a add_subdirectory(HelloPass) line to <LLVM root>/lib/Transform/CMakeLists.txt. Build LLVM as usual.
There is a Makefile.common under llvm.3.9.0-src, i.e. your llvm source root. So that should not be your problem.
Note that there are some make variables to set in Makefile.common.

Compiling clisp-2.49 on OSX : LIBFFI not found

TL;DR :
Even if libffi seems installed, the configure script doesn't find it even if I give it the (correct?) prefix.
/!\ The last part (*) of this post is where I'm stuck. /!\
I only put the other information to explain how I get there. I apologize for the big post, if something seems irrelevant to you, feel free to tell me, I'll consider making my post shorter.
Why I want to compile CLISP by myself :
I have a lisp programm I would like to run but when running it with CLISP installed with brew (I have no root access) I get the following error :
*** - CFFI requires CLISP compiled with dynamic FFI support.
So I would like to compile CLISP by myself.
I was using SBCL thus far but I had a problem and was looking for an other implementation.
The problems I have when trying to compile :
I downloaded the sources, untared it.
I then trying to run ./configure.
But I get this :
Configure findings:
FFI: no (user requested: default)
readline: no (user requested: default)
libsigsegv: no, consider installing GNU libsigsegv
./configure: libsigsegv was not detected, thus some features, such as
generational garbage collection and
stack overflow detection in interpreted Lisp code
cannot be provided.
Please install libsigsegv like this:
mkdir tools; cd tools; prefix=`pwd`/x86_64-apple-darwin15.4.0
wget http://ftp.gnu.org/pub/gnu/libsigsegv/libsigsegv-2.8.tar.gz
tar xfz libsigsegv-2.8.tar.gz
cd libsigsegv-2.8
./configure --prefix=${prefix} && make && make check && make install
cd ../..
rm -f src/config.cache
./configure --with-libsigsegv-prefix=${prefix}
If you insist on building without libsigsegv, please pass
--ignore-absence-of-libsigsegv
to this script:
./configure --ignore-absence-of-libsigsegv
If you have installed libsigsegv, but clisp does not detect it,
you might have installed it incorrectly, see section 2 in in unix/INSTALL.
IMPORTANT :
libffi and libsigsegv are both installed with homebrew. But aren't found.
I tried adding --with-libsigsegv-prefix=<several values amongst ~/.brew/{opt,opt/libsigsegv,lib,Cellar/libsigsegv,...} : Still the same problem.
This is also almost the same as this post or this one. But the validated solutions doesn't work for me (OSX without root access).
When running configure with --with-dynamic-ffi and --ignore-absence-of-libsigsegv :
I tried to run ./configure --ignore-absence-of-libsigsegv and added --with-dynamic-ffi as someone suggested me in comments.
But then I got this :
Configure findings:
FFI: no (user requested: default)
readline: no (user requested: default)
libsigsegv: no, consider installing GNU libsigsegv
As you requested, we will proceed without libsigsegv...
./makemake --with-dynamic-ffi > Makefile
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
when trying to manually install libffi and libsigsegv :
I also tried the suggestion in the first error message :
When running ./configure --with-libsigsegv-prefix=${prefix} I got :
Configure findings:
FFI: no (user requested: default)
readline: no (user requested: default)
libsigsegv: yes
./makemake --with-libsigsegv-prefix=/nfs/2013/v/vmonteco/Documents/clisp-2.49/tools/x86_64-apple-darwin15.4.0 > Makefile
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
make: `config.lisp' is up to date.
even if I add --with-dynamic-ffi or if I try to install libffi by hand like the first error message suggested (and adding --with-ffi-prefix=${prefix} as well)
If I try to manually build and install libffcall as well :
I get many
avcall-i386.s:7:2: error: instruction requires: Not 64-bit mode
when running make
(*) So now, it does find libsigsegv, but doesn't find libffi.
Yet the tree at ${prefix} looks like this :
.
├── include
│   └── sigsegv.h
├── lib
│   ├── libffi-3.2.1
│   │   └── include
│   │   ├── ffi.h
│   │   └── ffitarget.h
│   ├── libffi.6.dylib
│   ├── libffi.a
│   ├── libffi.dylib -> libffi.6.dylib
│   ├── libffi.la
│   ├── libsigsegv.a
│   ├── libsigsegv.la
│   └── pkgconfig
│   └── libffi.pc
└── share
├── info
│   ├── dir
│   └── libffi.info
└── man
└── man3
├── ffi.3
├── ffi_call.3
├── ffi_prep_cif.3
└── ffi_prep_cif_var.3
I'm out of ideas.
On OSX (and developing for OSX only) it is a very good idea to check Clozure. http://ccl.clozure.com It includes an IDE and from speed and general performance it is comparable to SBCL. You can develop native OSX UI apps using Clozure, of course these will not be portable. If you keep to the standard, then you might even use Clozure on Linux etc.

Compiling and linking subproject library with CMake

I have 2 projects (prj1 and prj2). One (prj2) depends on the other (prj1) that is a static library. I arrive to compile them separately with CMake.
But I needed to integrate one (prj1) to the other one (prj2). So I would like CMake to compile the static library (prj1) before the other (prj2) and then link the static library. I tried things, but id did not work.
prj1 "core" is https://gitlab.com/RyDroid/PlanetWars2dRT-core
prj2 "SDL2" is https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/ (see branch adding-core)
In prj2, externals/core is a git submodule (for non git users, you can see this directory as a copy-paste of prj1).
I tried (without success) this CMakeLists.txt in prj2 "SDL2":
cmake_minimum_required(VERSION 2.8)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wformat=2 -Wpedantic -D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# TODO
endif()
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# if (CMAKE_VERSION VERSION_LESS "3.1")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
# CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# endif()
# else()
# set(CMAKE_CXX_STANDARD 11)
# endif()
project(PlanetWars2dRT-SDL2)
# Version number
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_MICRO "0")
# Configure a header file to pass some of the CMake settings
# to the source code.
configure_file (
"src/compilation_config.h.in"
"${PROJECT_BINARY_DIR}/compilation_config.h"
)
# Add the binary tree to the search path for include files
# so that we will find compilation_config.h
include_directories("${PROJECT_BINARY_DIR}")
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
include_directories(src/)
file(
GLOB_RECURSE
source_files
src/*
)
add_executable(planet-wars-2d-rt-sdl2 ${source_files})
#include(ExternalProject)
#ExternalProject_Add(PlanetWars2dRT PREFIX externals/core/)
include_directories(externals/core/src/utils/ externals/core/src/specific/)
add_subdirectory(externals/core/)
#find_package(PlanetWars2dRT-core REQUIRED)
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(SDL2GFX REQUIRED SDL2_gfx)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
target_link_libraries(
planet-wars-2d-rt-sdl2
planet-wars-2d-rt-core
${SDL2_LIBRARIES} ${SDL2GFX_LIBRARIES}
)
That is a simplified version of the tree of prj2:
.
├── build (with CMake stuff generated with "cmake ..")
├── CMakeLists.txt
├── externals
│   └── core
│ ├── build (with CMake stuff generated with "cmake ..")
│   ├── CMakeLists.txt
│   ├── makefile
│   └── src
├── makefile
├── README.md
└── src
    ├── compilation_config.h.in
   └── planet-wars-2d-rt-sdl2.cpp
How can I compile the library of prj1 "core" in prj2 "SDL2" with CMake, and then link the library of prj1 with prj2 (again with CMake)?
If your solution does not work with a non GNU/Linux OS, it is not a big problem. Note: my PC is running on Debian GNU/Linux 8 "Jessie".
Regards.
I cannot access your repo https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/, perhaps the servers are down for maintenance. If I understand your problem correctly, you may create a structure like that:
root/
CMakeLists.txt // 1
src/
CMakeLists.txt // 2
main.cpp
SDL2/
some sources
CMakeLists.txt // 3
core/
some sources
CMakeLists.txt // 4
In the CMakeLists.txt [1] you should declare your project name, required packages, common flags, include paths etc.:
cmake_minimum_required( VERSION 2.x )
project(name)
include_directories(inc inc/core inc/SDL2 inc/SthElse)
add_subdirectory(src)
In CMakeLists.txt [2] for subdir src you should declare your main executable and also add subdirs with your prj1 and prj2
add_subdirectory(core)
add_subdirectory(SDL2)
add_executable(main main.cpp)
target_link_libraries(main core SDL2 SomeOtherLib)
Finally, in your CMakeLists.txt [3] && [4] in your lib dirs you should declare static libraries:
add_library(core STATIC ${YourSourceFiles})
This approach always worked for me. If you used to compile and run "core" and "SDL2" as standalone binaries, perhaps you will have to reorganize them a little bit.
Both project have a file "compilation_config.h". At compilation time, the wrong was taken so compilation failed, because the code used was #include "compilation_config.h" that was ambigous.
So I created a "include/project-name" dir in both project and I changed the include path : "prj1/compilation_config.h" or "prj2/compilation_config.h". Thanks to that there was no ambiguity anymore, so it works now!

SWIG, perl, DynaLoader can't find boot_$Module on OS X

I am trying to build and install a SWIG-generated perl API on OS X 10.10.2. (It's for the FreeLing 3.1 language analysis toolkit.) I have generated and compiled the SWIG files, producing freeling.so.
But when I try to use freeling in a perl script, I get the error:
Can't find 'boot_freeling' symbol in /usr/local/lib/libfreeling.dylib at freeling.pm line 11.
But boot_freeling should be defined in the SWIG-generated freeling.so, not in libfreeling.dylib (the FreeLing package lib). (nm -U confirms this: _boot_freeling is defined in freeling.so; I'm assuming the leading underscore is just part of the object file format.)
I have made sure that freeling.so comes before libfreeling.dylib in LD_LIBRARY_PATH. I've also tried unshifting the path to freeling.so onto #DynaLoader::dl_library_path.
I suspect this is not a path problem, but something about building for OS X. In the past, I have built this on Ubuntu and it works fine. I have tweaked the gcc options (-bundle instead of -shared).
Additional info:
perl -V:dlext => dlext='bundle';
Building SOso-0.01.patch.txt produces:
blib
├── blib/arch
│   └── blib/arch/auto
│   └── blib/arch/auto/SOso
│   └── blib/arch/auto/SOso/SOso.bundle
├── blib/bin
├── blib/lib
│   ├── blib/lib/SOso.pm
│   └── blib/lib/auto
│   └── blib/lib/auto/SOso
├── blib/man1
├── blib/man3
└── blib/script
Makefile target:
freeling.bundle: freeling_perlAPI.cxx
g++ -v -bundle -o freeling.bundle freeling_perlAPI.cxx -lfreeling -lperl -lboost_system -I $(FREELINGDIR)/include -I $(BOOSTDIR)/include -I $(ICU4CDIR)/include -L $(FREELINGDIR)/libfreeling -I $(PERLDIR)/CORE -L $(LIBDIR) -L $(BOOSTDIR)/lib -L $(PERLDIR)/CORE -fPIC
Ok, promoting to answer :)
What do you get for perl -V:dlext ?
When you compile this module SOso-0.01.patch.txt what files are created in blib?
Well :) if your os/perl is configured to look for a freeling.bundle, I don't think its going to try to look at freeling.so .... so I'd try to do something about that ... rename the file to use the dlext

Resources