I've created an application to read QR code using OpenCv.
When I try to build it using NDK, everything works well
NDK=/opt/android-ndk-r23c
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
export TARGET=aarch64-linux-android
export API=21
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
$NDK/ndk-build
But when I've tried to build it as a system application as part of the AOSP build I've got an error:
read_qr/jni/../../OpenCV-android-sdk/sdk/native/jni/OpenCV.mk: error: "read_qr (EXECUTABLES android-arm) missing opencv_features2d (STATIC_LIBRARIES android-arm)"
You can set ALLOW_MISSING_DEPENDENCIES=true in your environment if this is intentional, but that may defer real problems until later in the build.
read_qr/jni/../../OpenCV-android-sdk/sdk/native/jni/OpenCV.mk: error: "read_qr (EXECUTABLES android-arm) missing opencv_dnn (STATIC_LIBRARIES android-arm)"
You can set ALLOW_MISSING_DEPENDENCIES=true in your environment if this is intentional, but that may defer real problems until later in the build.
build/make/core/main.mk:1118: error: exiting from previous errors.
22:44:58 ckati failed with: exit status 1
And I have no idea what can be the problem.
This is my Android.mk and Application.mk files:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Location of SDK on my drive
OPENCVROOT := ${LOCAL_PATH}/../../OpenCV-android-sdk
OPENCV_CAMERA_MODULES := off
OPENCV_INSTALL_MODULES := on
OPENCV_LIB_TYPE := STATIC
TARGET_ARCH_ABI := armeabi-v7a
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk
# Load your local .cpp and .h files here.
LOCAL_SRC_FILES := readQr.cpp
LOCAL_LDLIBS := -lm -llog -ldl -lz
LOCAL_CPPFLAGS += -fexceptions -frtti -std=c++17
LOCAL_LDFLAGS += -ljnigraphics
LOCAL_C_INCLUDES += ${OPENCVROOT}/sdk/native/jni/include \
${OPENCVROOT}/sdk/native/jni/include/opencv2
LOCAL_EXPORT_C_INCLUDES += ${OPENCVROOT}/sdk/native/jni/include \
${OPENCVROOT}/sdk/native/jni/include/opencv2
LOCAL_MODULE := read_qr
include $(BUILD_EXECUTABLE)
APP_PLATFORM := android-21
Application.mk
APP_STL := c++_static
APP_CPPFLAGS += -fexceptions -frtti -std=c++11 -D__STDC_CONSTANT_MACROS
APP_ABI := armeabi-v7a
APP_PLATFORM := android-21
Can someone help me to understand what is the problem?
Resolved by changing the Android.mk
from:
include $(BUILD_EXECUTABLE)
to
include $(BUILD_STATIC_EXECUTABLE)
We need to execute ffmpeg in a command window in my delphi application.
We found the solution to protect the path with the function "ExtractShortPathName".
But on some computers we can't get the 8.3 path (HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation is 2) and we want to find another way to escape the spaces.
Here is the code :
sParameters := '"C:\Users\[...]\input.wav" -r 12.03 -f image2 -i "C:\Users\[...]\delphilm%d.png" -vf "scale=1024:704" -ab 96k -r 24 -b 2000k -pass 1 -vcodec libx264 -fpre "C:\[...]\libx264-normal.ffpreset" "C:\Users\[...]\export.mp4"';
sCommand := 'C:\Program Files\My application\utils\bin\ffmpeg.exe';
Handle := CreateProcess(nil, PChar('cmd.exe /C '+ProtectPath(sCommand)+' '+sParameters),nil, nil, True, 0, nil, nil, SI, PI);
With the ProtectPath function :
function ProtectPath(sCommand:Widestring):Widestring;
begin
Result := sCommand;
// get the 8.3 path
Result := ExtractShortPathName(sCommand);
// if 8.3 path is not accessible
if(Pos(' ', Result)>0)then begin
//Result := '"'+sCommand+'"'; --> do not work
//Result := StrReplace(sCommand, ' ','" "'); --> do not work
//Result := StrReplace(sCommand, ' ','^ '); --> do not work
//Result := StrReplace(sCommand, ' ','\ '); --> do not work
//Result := StrReplace(sCommand, ' ','\\ '); --> do not work
//Result := StrReplace(sCommand, ' ','/ '); --> do not work
//Result := StrReplace(sCommand, ' ','// '); --> do not work
end;
end;
Any ideas ?
You do not need to retrieve the 8.3 filename. All you have to do is wrap a long path with a single pair of quotation marks if it contains any space characters in it (like you are already doing with some of your FFMPEG parameters). Then, get rid of cmd.exe altogether and just call ffmpeg.exe directly instead.
sCommand := '"C:\Program Files\My application\utils\bin\ffmpeg.exe"';
sParameters := '"C:\Users\[...]\input.wav" -r 12.03 -f image2 -i "C:\Users\[...]\delphilm%d.png" -vf "scale=1024:704" -ab 96k -r 24 -b 2000k -pass 1 -vcodec libx264 -fpre "C:\[...]\libx264-normal.ffpreset" "C:\Users\[...]\export.mp4"';
Handle := CreateProcess(nil, PChar(sCommand + ' ' + sParameters), nil, nil, True, 0, nil, nil, SI, PI);
If you want to do the quoting dynamically, use (Ansi)QuotedStr() for that, eg:
function ProtectParam(sParam: String): String;
begin
if LastDelimiter(' "', sParam) <> 0 then
Result := QuotedStr(sParam)
else
Result := sParam;
end;
FFMPEG := 'C:\Program Files\My application\utils\bin\ffmpeg.exe';
InputFile := 'C:\Users\[...]\input.wav';
PngFile := 'C:\Users\[...]\delphilm%d.png';
PresetFile := 'C:\[...]\libx264-normal.ffpreset';
ExportFile := 'C:\Users\[...]\export.mp4';
sCommand := ProtectParam(FFMPEG) + ' ' + ProtectParam(InputFile) + ' -r 12.03 -f image2 -i ' + ProtectParam(PngFile) + ' -vf "scale=1024:704" -ab 96k -r 24 -b 2000k -pass 1 -vcodec libx264 -fpre ' + ProtectParam(PresetFile) + ' ' + ProtectParam(ExportFile);
Handle := CreateProcess(nil, PChar(sCommand), nil, nil, True, 0, nil, nil, SI, PI);
I don't see any real reason to use cmd.exe here. It's just adding an extra layer of complexity that burns you. You are asking cmd.exe to call CreateProcess to start ffmpeg, so why not do it directly?
That said, a cheap and cheerful way to side-step the problem is to make use of the working directory. Pass 'C:\Program Files\My application\utils\bin' for the working directory of the new process, and then PChar('cmd.exe /C ffmpeg.exe '+sParameters) is all you need.
I need to launch MS Window's OpenFiles.exe from a Delphi XE2 application to export currently opened files to a text file. The normal cmd.exe syntax is something like:
Openfiles.exe /query /s 127.0.0.1 /nh >c:\OpenFilesExport.txt
Using the following code returns a successful exit code but the export file is not generated:
var
exInfo: TShellExecuteInfo;
exitcode: DWORD;
begin
FillChar(exInfo, Sizeof(exInfo), 0);
with exInfo do
begin
cbSize := Sizeof(exInfo);
fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
lpVerb := 'open';
lpFile := Pchar('Openfiles.exe');
lpParameters := PChar('/query /s 127.0.0.1 /nh >c:\OpenFilesOutput.txt');
nShow := SW_SHOWNORMAL
end;
if ShellExecuteEx(#exInfo) then
begin
while GetExitCodeProcess(exInfo.hProcess, exitcode)
and (exitcode = STILL_ACTIVE) do
Application.ProcessMessages();
CloseHandle(exInfo.hProcess);
end
else
ShowMessage(SysErrorMessage(GetLastError));
I've also tried putting the cmd.exe syntax in a bat file and launching that from shellexecute and it DOES generate the file but there is no content. Running the same bat file from explorer generates the file as expected.
How can I launch Openfiles.exe successfully from ShellExecute?
Your problem is the redirect, >, which only makes sense if you have a command interpreter. And in your code you do not. You have two options:
Call ShellExecuteEx passing a command interpreter to do the work.
Use CreateProcess to execute the other process, but pass a handle to a file as the stdout handle for the new process.
For the command interpreter option you would have a command line like this:
cmd /c Openfiles.exe /query /s 127.0.0.1 /nh >c:\OpenFilesExport.txt
The code might be like so:
FillChar(exInfo, Sizeof(exInfo), 0);
with exInfo do
begin
cbSize := Sizeof(exInfo);
fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
lpFile := 'cmd.exe';
lpParameters := '/c Openfiles.exe /query /s 127.0.0.1 /nh >c:\OpenFilesExport.txt';
nShow := SW_SHOWNORMAL;
end;
For the CreateProcess option you'll need to create the file with a call to CreateFile, and pass that handle as stdout of the new process. You'll need to make sure that the file handle is inheritable. And finally you'll need to wait on the process so that you can close the file handle.
Regarding your current code, your wait is not very pleasant. It's a busy wait that needlessly consumes CPU. You should use a blocking wait on the process handle.
I'm trying to compile Mars for cuda 4.2.9 (cuda 5.0 eliminated a lot of header files used by Mars). Versions below 5.0 seem to utilize this monstrous makefile common.mk and I'm having a hard time configuring it to get the code to work. The object files compile just fine but I'm getting this error:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/bin/ld: cannot find -lcutil_x86_64
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/bin/ld: cannot find -lshrutil_x86_64
collect2: ld returned 1 exit status
make: *** [/home/ian/code/cuda-4.2.9/C/bin/linux/release/MatrixMul] Error 1
Why is this happening? How can I remedy it?
Here is the makefile for MatrixMul:
################################################################################
#
# Build script for project
#
################################################################################
# Add source files here
EXECUTABLE := MatrixMul
# Cuda source files (compiled with cudacc)
CUFILES := main.cu MarsLib.cu MarsScan.cu MarsSort.cu
# C/C++ source files (compiled with gcc / c++)
CCFILES := MarsUtils.cpp
################################################################################
# Rules and targets
include ../cuda-4.2.9/C/common/common.mk
The lines of common.mk that I edited:
# Basic directory setup for SDK
# (override directories only if they are not already defined)
SRCDIR ?=
ROOTDIR ?= /home/ian/code/cuda-4.2.9
ROOTBINDIR ?= $(ROOTDIR)/C/bin
BINDIR ?= $(ROOTBINDIR)/$(OSLOWER)
ROOTOBJDIR ?= obj
LIBDIR := $(ROOTDIR)/C/lib
COMMONDIR := $(ROOTDIR)/C/common
SHAREDDIR := $(ROOTDIR)/shared/
Original values:
# Basic directory setup for SDK
# (override directories only if they are not already defined)
SRCDIR ?=
ROOTDIR ?= ..
ROOTBINDIR ?= $(ROOTDIR)/../bin
BINDIR ?= $(ROOTBINDIR)/$(OSLOWER)
ROOTOBJDIR ?= obj
LIBDIR := $(ROOTDIR)/../lib
COMMONDIR := $(ROOTDIR)/../common
SHAREDDIR := $(ROOTDIR)/../shared/
And the whole common.mk:
################################################################################
#
# Common build script for CUDA source projects for Linux and Mac platforms
#
################################################################################
.SUFFIXES : .cu .cu_dbg.o .c_dbg.o .cpp_dbg.o .cu_rel.o .c_rel.o .cpp_rel.o .cubin .ptx
# Add new SM Versions here as devices with new Compute Capability are released
SM_VERSIONS := 10 11 12 13 20 21 30
CUDA_INSTALL_PATH ?= /home/ian/code/cuda-4.2.9/cuda/
ifdef cuda-install
CUDA_INSTALL_PATH := $(cuda-install)
endif
# detect OS
OSUPPER = $(shell uname -s 2>/dev/null | tr [:lower:] [:upper:])
OSLOWER = $(shell uname -s 2>/dev/null | tr [:upper:] [:lower:])
# 'linux' is output for Linux system, 'darwin' for OS X
DARWIN = $(strip $(findstring DARWIN, $(OSUPPER)))
ifneq ($(DARWIN),)
SNOWLEOPARD = $(strip $(findstring 10.6, $(shell egrep "<string>10\.6" /System/Library/CoreServices/SystemVersion.plist)))
LION = $(strip $(findstring 10.7, $(shell egrep "<string>10\.7" /System/Library/CoreServices/SystemVersion.plist)))
endif
# detect 32-bit or 64-bit platform
HP_64 = $(shell uname -m | grep 64)
OSARCH= $(shell uname -m)
# Basic directory setup for SDK
# (override directories only if they are not already defined)
SRCDIR ?=
ROOTDIR ?= /home/ian/code/cuda-4.2.9/cuda/C
ROOTBINDIR ?= $(ROOTDIR)/bin
BINDIR ?= $(ROOTBINDIR)/$(OSLOWER)
ROOTOBJDIR ?= obj
LIBDIR := $(ROOTDIR)/lib
COMMONDIR := $(ROOTDIR)/common
SHAREDDIR := $(ROOTDIR)/../shared/
# Compilers
NVCC := $(CUDA_INSTALL_PATH)/bin/nvcc
CXX := g++ -fPIC
CC := gcc -fPIC
LINK := g++ -fPIC
# Includes
INCLUDES += -I. -I$(CUDA_INSTALL_PATH)/include -I$(COMMONDIR)/inc -I$(SHAREDDIR)/inc
# Warning flags
CXXWARN_FLAGS := \
-W -Wall \
-Wimplicit \
-Wswitch \
-Wformat \
-Wchar-subscripts \
-Wparentheses \
-Wmultichar \
-Wtrigraphs \
-Wpointer-arith \
-Wcast-align \
-Wreturn-type \
-Wno-unused-function \
$(SPACE)
CWARN_FLAGS := $(CXXWARN_FLAGS) \
-Wstrict-prototypes \
-Wmissing-prototypes \
-Wmissing-declarations \
-Wnested-externs \
-Wmain \
# architecture flag for nvcc and gcc compilers build
CUBIN_ARCH_FLAG :=
CXX_ARCH_FLAGS :=
NVCCFLAGS :=
LIB_ARCH := $(OSARCH)
# Determining the necessary Cross-Compilation Flags
# 32-bit OS, but we target 64-bit cross compilation
ifeq ($(x86_64),1)
NVCCFLAGS += -m64
LIB_ARCH = x86_64
ifneq ($(DARWIN),)
CXX_ARCH_FLAGS += -arch x86_64
else
CXX_ARCH_FLAGS += -m64
endif
else
# 64-bit OS, and we target 32-bit cross compilation
ifeq ($(i386),1)
NVCCFLAGS += -m32
LIB_ARCH = i386
ifneq ($(DARWIN),)
CXX_ARCH_FLAGS += -arch i386
else
CXX_ARCH_FLAGS += -m32
endif
else
ifeq "$(strip $(HP_64))" ""
LIB_ARCH = i386
NVCCFLAGS += -m32
ifneq ($(DARWIN),)
CXX_ARCH_FLAGS += -arch i386
else
CXX_ARCH_FLAGS += -m32
endif
else
ifeq "$(strip $(HP_64))" ""
LIB_ARCH = i386
NVCCFLAGS += -m32
ifneq ($(DARWIN),)
CXX_ARCH_FLAGS += -arch i386
else
CXX_ARCH_FLAGS += -m32
endif
else
LIB_ARCH = x86_64
NVCCFLAGS += -m64
ifneq ($(DARWIN),)
CXX_ARCH_FLAGS += -arch x86_64
else
CXX_ARCH_FLAGS += -m64
endif
endif
endif
endif
# Compiler-specific flags (by default, we always use sm_10, sm_20, and sm_30), unless we use the SMVERSION template
GENCODE_SM10 := -gencode=arch=compute_10,code=\"sm_10,compute_10\"
GENCODE_SM20 := -gencode=arch=compute_20,code=\"sm_20,compute_20\"
GENCODE_SM30 := -gencode=arch=compute_30,code=\"sm_30,compute_30\"
CXXFLAGS += $(CXXWARN_FLAGS) $(CXX_ARCH_FLAGS)
CFLAGS += $(CWARN_FLAGS) $(CXX_ARCH_FLAGS)
LINKFLAGS +=
LINK += $(LINKFLAGS) $(CXX_ARCH_FLAGS)
# This option for Mac allows CUDA applications to work without requiring to set DYLD_LIBRARY_PATH
ifneq ($(DARWIN),)
LINK += -Xlinker -rpath $(CUDA_INSTALL_PATH)/lib
endif
# Common flags
COMMONFLAGS += $(INCLUDES) -DUNIX
# If we are enabling GPU based debugging, then we want to use -G, warning that this
# May have a significant impact on GPU device code, since optimizations are turned off
ifeq ($(gpudbg),1)
NVCCFLAGS += -G
dbg = $(gpudbg)
endif
# Debug/release configuration
ifeq ($(dbg),1)
COMMONFLAGS += -g
NVCCFLAGS += -D_DEBUG
CXXFLAGS += -D_DEBUG
CFLAGS += -D_DEBUG
BINSUBDIR := debug
LIBSUFFIX := D
else
COMMONFLAGS += -O2
BINSUBDIR := release
LIBSUFFIX :=
NVCCFLAGS += --compiler-options -fno-strict-aliasing
CXXFLAGS += -fno-strict-aliasing
CFLAGS += -fno-strict-aliasing
endif
# architecture flag for cubin build
CUBIN_ARCH_FLAG :=
# OpenGL is used or not (if it is used, then it is necessary to include GLEW)
ifeq ($(USEGLLIB),1)
ifneq ($(DARWIN),)
OPENGLLIB := -L/System/Library/Frameworks/OpenGL.framework/Libraries
OPENGLLIB += -lGL -lGLU $(COMMONDIR)/lib/$(OSLOWER)/libGLEW.a
else
# this case for linux platforms
OPENGLLIB := -lGL -lGLU -lX11 -lXi -lXmu
# check if x86_64 flag has been set, otherwise, check HP_64 is i386/x86_64
ifeq ($(x86_64),1)
OPENGLLIB += -lGLEW_x86_64 -L/usr/X11R6/lib64
else
ifeq ($(i386),)
ifeq "$(strip $(HP_64))" ""
OPENGLLIB += -lGLEW -L/usr/X11R6/lib
else
OPENGLLIB += -lGLEW_x86_64 -L/usr/X11R6/lib64
endif
endif
endif
# check if i386 flag has been set, otehrwise check HP_64 is i386/x86_64
ifeq ($(i386),1)
OPENGLLIB += -lGLEW -L/usr/X11R6/lib
else
ifeq ($(x86_64),)
ifeq "$(strip $(HP_64))" ""
OPENGLLIB += -lGLEW -L/usr/X11R6/lib
else
OPENGLLIB += -lGLEW_x86_64 -L/usr/X11R6/lib64
endif
endif
endif
endif
endif
ifeq ($(USEGLUT),1)
ifneq ($(DARWIN),)
OPENGLLIB += -framework GLUT
else
ifeq ($(x86_64),1)
OPENGLLIB += -lglut -L/usr/lib64
endif
ifeq ($(i386),1)
OPENGLLIB += -lglut -L/usr/lib
endif
ifeq ($(x86_64),)
ifeq ($(i386),)
OPENGLLIB += -lglut
endif
endif
endif
endif
ifeq ($(USEPARAMGL),1)
PARAMGLLIB := -lparamgl_$(LIB_ARCH)$(LIBSUFFIX)
endif
ifeq ($(USERENDERCHECKGL),1)
RENDERCHECKGLLIB := -lrendercheckgl_$(LIB_ARCH)$(LIBSUFFIX)
endif
ifeq ($(USENVCUVID), 1)
ifneq ($(DARWIN),)
NVCUVIDLIB := -L../../common/lib/darwin -lnvcuvid
endif
endif
# Libs
ifneq ($(DARWIN),)
LIB := -L$(CUDA_INSTALL_PATH)/lib -L$(LIBDIR) -L$(COMMONDIR)/lib/$(OSLOWER) -L$(SHAREDDIR)/lib $(NVCUVIDLIB)
else
ifeq "$(strip $(HP_64))" ""
ifeq ($(x86_64),1)
LIB := -L$(CUDA_INSTALL_PATH)/lib64 -L$(LIBDIR) -L$(COMMONDIR)/lib/$(OSLOWER) -L$(SHAREDDIR)/lib
else
LIB := -L$(CUDA_INSTALL_PATH)/lib -L$(LIBDIR) -L$(COMMONDIR)/lib/$(OSLOWER) -L$(SHAREDDIR)/lib
endif
else
ifeq ($(i386),1)
LIB := -L$(CUDA_INSTALL_PATH)/lib -L$(LIBDIR) -L$(COMMONDIR)/lib/$(OSLOWER) -L$(SHAREDDIR)/lib
else
LIB := -L$(CUDA_INSTALL_PATH)/lib64 -L$(LIBDIR) -L$(COMMONDIR)/lib/$(OSLOWER) -L$(SHAREDDIR)/lib
endif
endif
endif
# If dynamically linking to CUDA and CUDART, we exclude the libraries from the LIB
ifeq ($(USECUDADYNLIB),1)
LIB += ${OPENGLLIB} $(PARAMGLLIB) $(RENDERCHECKGLLIB) ${LIB} -ldl -rdynamic
else
# static linking, we will statically link against CUDA and CUDART
ifeq ($(USEDRVAPI),1)
LIB += -lcuda ${OPENGLLIB} $(PARAMGLLIB) $(RENDERCHECKGLLIB) ${LIB}
else
ifeq ($(emu),1)
LIB += -lcudartemu
else
LIB += -lcudart
endif
LIB += ${OPENGLLIB} $(PARAMGLLIB) $(RENDERCHECKGLLIB) ${LIB}
endif
endif
ifeq ($(USECUFFT),1)
ifeq ($(emu),1)
LIB += -lcufftemu
else
LIB += -lcufft
endif
endif
ifeq ($(USECUBLAS),1)
ifeq ($(emu),1)
LIB += -lcublasemu
else
LIB += -lcublas
endif
endif
ifeq ($(USECURAND),1)
LIB += -lcurand
endif
ifeq ($(USECUSPARSE),1)
LIB += -lcusparse
endif
# Lib/exe configuration
# Lib/exe configuration
# Lib/exe configuration
ifneq ($(STATIC_LIB),)
TARGETDIR := $(LIBDIR)
TARGET := $(subst .a,_$(LIB_ARCH)$(LIBSUFFIX).a,$(LIBDIR)/$(STATIC_LIB))
LINKLINE = ar rucv $(TARGET) $(OBJS)
else
ifneq ($(OMIT_CUTIL_LIB),1)
LIB += -lcutil_$(LIB_ARCH)$(LIBSUFFIX)
endif
ifneq ($(OMIT_SHRUTIL_LIB),1)
LIB += -lshrutil_$(LIB_ARCH)$(LIBSUFFIX)
endif
# Device emulation configuration
ifeq ($(emu), 1)
NVCCFLAGS += -deviceemu
CUDACCFLAGS +=
BINSUBDIR := emu$(BINSUBDIR)
# consistency, makes developing easier
CXXFLAGS += -D__DEVICE_EMULATION__
CFLAGS += -D__DEVICE_EMULATION__
endif
TARGETDIR := $(BINDIR)/$(BINSUBDIR)
TARGET := $(TARGETDIR)/$(EXECUTABLE)
LINKLINE = $(LINK) -o $(TARGET) $(OBJS) $(LIB)
endif
# check if verbose
ifeq ($(verbose), 1)
VERBOSE :=
else
VERBOSE := #
endif
################################################################################
# Check for input flags and set compiler flags appropriately
################################################################################
ifeq ($(fastmath), 1)
NVCCFLAGS += -use_fast_math
endif
ifeq ($(keep), 1)
NVCCFLAGS += -keep
NVCC_KEEP_CLEAN := *.i* *.cubin *.cu.c *.cudafe* *.fatbin.c *.ptx
endif
ifdef maxregisters
NVCCFLAGS += -maxrregcount $(maxregisters)
endif
ifeq ($(ptxas), 1)
NVCCFLAGS += --ptxas-options=-v
endif
# Add cudacc flags
NVCCFLAGS += $(CUDACCFLAGS)
# Add common flags
NVCCFLAGS += $(COMMONFLAGS)
CXXFLAGS += $(COMMONFLAGS)
CFLAGS += $(COMMONFLAGS)
ifeq ($(nvcc_warn_verbose),1)
NVCCFLAGS += $(addprefix --compiler-options ,$(CXXWARN_FLAGS))
NVCCFLAGS += --compiler-options -fno-strict-aliasing
endif
################################################################################
# Set up object files
################################################################################
OBJDIR := $(ROOTOBJDIR)/$(LIB_ARCH)/$(BINSUBDIR)
OBJS += $(patsubst %.cpp,$(OBJDIR)/%.cpp.o,$(notdir $(CCFILES)))
OBJS += $(patsubst %.c,$(OBJDIR)/%.c.o,$(notdir $(CFILES)))
OBJS += $(patsubst %.cu,$(OBJDIR)/%.cu.o,$(notdir $(CUFILES)))
################################################################################
# Set up cubin output files
################################################################################
CUBINDIR := $(SRCDIR)data
CUBINS += $(patsubst %.cu,$(CUBINDIR)/%.cubin,$(notdir $(CUBINFILES)))
################################################################################
# Set up PTX output files
################################################################################
PTXDIR := $(SRCDIR)data
PTXBINS += $(patsubst %.cu,$(PTXDIR)/%.ptx,$(notdir $(PTXFILES)))
################################################################################
# Rules
################################################################################
$(OBJDIR)/%.c.o : $(SRCDIR)%.c $(C_DEPS)
$(VERBOSE)$(CC) $(CFLAGS) -o $# -c $<
$(OBJDIR)/%.cpp.o : $(SRCDIR)%.cpp $(C_DEPS)
$(VERBOSE)$(CXX) $(CXXFLAGS) -o $# -c $<
# Default arch includes gencode for sm_10, sm_20, sm_30, and other archs from GENCODE_ARCH declared in the makefile
$(OBJDIR)/%.cu.o : $(SRCDIR)%.cu $(CU_DEPS)
$(VERBOSE)$(NVCC) $(GENCODE_SM10) $(GENCODE_ARCH) $(GENCODE_SM20) $(GENCODE_SM30) $(NVCCFLAGS) $(SMVERSIONFLAGS) -o $# -c $<
# Default arch includes gencode for sm_10, sm_20, sm_30, and other archs from GENCODE_ARCH declared in the makefile
$(CUBINDIR)/%.cubin : $(SRCDIR)%.cu cubindirectory
$(VERBOSE)$(NVCC) $(GENCODE_SM10) $(GENCODE_ARCH) $(GENCODE_SM20) $(GENCODE_SM30) $(CUBIN_ARCH_FLAG) $(NVCCFLAGS) $(SMVERSIONFLAGS) -o $# -cubin $<
$(PTXDIR)/%.ptx : $(SRCDIR)%.cu ptxdirectory
$(VERBOSE)$(NVCC) $(CUBIN_ARCH_FLAG) $(NVCCFLAGS) $(SMVERSIONFLAGS) -o $# -ptx $<
# The following definition is a template that gets instantiated for each SM
# version (sm_10, sm_13, etc.) stored in SMVERSIONS. It does 2 things:
# 1. It adds to OBJS a .cu_sm_XX.o for each .cu file it finds in CUFILES_sm_XX.
# 2. It generates a rule for building .cu_sm_XX.o files from the corresponding
# .cu file.
#
# The intended use for this is to allow Makefiles that use common.mk to compile
# files to different Compute Capability targets (aka SM arch version). To do
# so, in the Makefile, list files for each SM arch separately, like so:
# This will be used over the default rule abov
#
# CUFILES_sm_10 := mycudakernel_sm10.cu app.cu
# CUFILES_sm_12 := anothercudakernel_sm12.cu
#
define SMVERSION_template
#OBJS += $(patsubst %.cu,$(OBJDIR)/%.cu_$(1).o,$(notdir $(CUFILES_$(1))))
OBJS += $(patsubst %.cu,$(OBJDIR)/%.cu_$(1).o,$(notdir $(CUFILES_sm_$(1))))
$(OBJDIR)/%.cu_$(1).o : $(SRCDIR)%.cu $(CU_DEPS)
# $(VERBOSE)$(NVCC) -o $$# -c $$< $(NVCCFLAGS) $(1)
$(VERBOSE)$(NVCC) -gencode=arch=compute_$(1),code=\"sm_$(1),compute_$(1)\" $(GENCODE_SM20) $(GENCODE_SM30) -o $$# -c $$< $(NVCCFLAGS)
endef
# This line invokes the above template for each arch version stored in
# SM_VERSIONS. The call function invokes the template, and the eval
# function interprets it as make commands.
$(foreach smver,$(SM_VERSIONS),$(eval $(call SMVERSION_template,$(smver))))
$(TARGET): makedirectories $(OBJS) $(CUBINS) $(PTXBINS) Makefile
$(VERBOSE)$(LINKLINE)
cubindirectory:
$(VERBOSE)mkdir -p $(CUBINDIR)
ptxdirectory:
$(VERBOSE)mkdir -p $(PTXDIR)
makedirectories:
$(VERBOSE)mkdir -p $(LIBDIR)
$(VERBOSE)mkdir -p $(OBJDIR)
$(VERBOSE)mkdir -p $(TARGETDIR)
tidy :
$(VERBOSE)find . | egrep "#" | xargs rm -f
$(VERBOSE)find . | egrep "\~" | xargs rm -f
clean : tidy
$(VERBOSE)rm -f *.stub.c *.gpu *.cu.cpp *.i *.ii
$(VERBOSE)rm -f *.cubin *.ptx *.fatbin.c *.hash
$(VERBOSE)rm -f *.cudafe1.c *.cudafe2.c *.cudafe1.cpp *.cudafe2.cpp
$(VERBOSE)rm -f $(OBJS)
$(VERBOSE)rm -f $(CUBINS)
$(VERBOSE)rm -f $(PTXBINS)
$(VERBOSE)rm -f $(TARGET)
$(VERBOSE)rm -f $(NVCC_KEEP_CLEAN)
$(VERBOSE)rm -f $(ROOTBINDIR)/$(OSLOWER)/$(BINSUBDIR)/*.ppm
$(VERBOSE)rm -f $(ROOTBINDIR)/$(OSLOWER)/$(BINSUBDIR)/*.pgm
$(VERBOSE)rm -f $(ROOTBINDIR)/$(OSLOWER)/$(BINSUBDIR)/*.bin
$(VERBOSE)rm -f $(ROOTBINDIR)/$(OSLOWER)/$(BINSUBDIR)/*.bmp
$(VERBOSE)rm -f $(ROOTBINDIR)/$(OSLOWER)/$(BINSUBDIR)/*.txt
$(VERBOSE)rm -f $(CUBINDIR)/*.cubin $(PTXDIR)/*.ptx
$(VERBOSE)rm -rf $(ROOTOBJDIR)
$(VERBOSE)rm -rf $(LIBDIR)
$(VERBOSE)rm -rf $(OBJDIR)
$(VERBOSE)rm -rf $(TARGETDIR)
clobber : clean
$(VERBOSE)rm -rf $(COMMONDIR)/lib/*.a
$(VERBOSE)rm -rf $(SHAREDDIR)/lib/*.a
$(VERBOSE)rm -rf $(COMMONDIR)/obj
$(VERBOSE)rm -rf $(SHAREDDIR)/obj
Why is this happening?
libcutil_x86_64.lib and libshrutil_x86_64.lib are libraries that are built by the cuda samples (called CUDA SDK in cuda 4.2 and earlier) when a proper make operation has been done after the CUDA SDK is installed. The linker cannot find these libraries and so is throwing these errors.
How can I remedy it?
Make sure that the CUDA 4.2 SDK has been properly installed and that the necessary make operation has been done to build the samples and therefore the requisite libraries. If you're unsure how to install the CUDA SDK or make the sample codes, review the /home/ian/code/cuda-4.2.9/CUDA_SDK_Release_Notes.txt file (especially linux install instructions). You may also be interested in the GPU_COMPUTING_SDK_Description.rtf file in that directory and also the files in the .../doc/release subdirectory. If you have not properly built the samples, the libraries won't be available and you'll have no luck linking your own matrixMul-MARS project. Note that you can specify the directory path to install the CUDA SDK at. Let's assume that from here on that ... in a path represents your SDK install path (which might be /home/ian/code/cuda-4.2.9/NVIDIA_GPU_Computing_SDK or something similar.) If things are jumbled in what you already have, you may want to start clean and re-run the installer.
Create a new project directory for your matrixMul-MARS project, at the same level as the other C source project directories, i.e. .../C/src/myMARS or something similar.
Copy all the files from .../C/src/matrixMul directory into your new .../C/src/myMARS directory.
Make the necessary changes to the Makefile in your new project directory (only) corresponding to what you have shown here, such as including additional files to be built, etc. You should not have to make any changes to common.mk.
Now execute make in your new project directory.
I have source code of 2 different libraries, FooMain and FooSecondary. FooSecondary is used by FooMain, so, makefile must compile First FooSecondary, then compile FooMain, and then link FooSecondary to FooMain.
My Android.mk is:
LOCAL_PATH:= $(call my-dir)
# Foo Secondary lib:
# Clear vars
include $(CLEAR_VARS)
# Target Build
LOCAL_ARM_MODE := arm
# Library Name
LOCAL_MODULE := FooSecondary
# Set All SRC_FILES Together
SRC_FILES := $(wildcard $(LOCAL_PATH)/FooSecondary/src/*.c)
SRC_FILES := $(SRC_FILES:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES = $(SRC_FILES)
# Enable Log support
LOCAL_LDLIBS = -llog
# C Flags - Max optimization
LOCAL_CFLAGS := -O3 -mno-thumb
# C++ Flags - Max optimization
LOCAL_CPPFLAGS := -O3 -mno-thumb
# Compile as Shared Library
include $(BUILD_SHARED_LIBRARY)
# Foo Secondary lib:
# Clear vars
include $(CLEAR_VARS)
# Include OpenCV
include 3rdparty/OpenCV-2.4.3-rc-android-sdk/sdk/native/jni/OpenCV.mk
# Target Build
LOCAL_ARM_MODE := arm
# Library Name
LOCAL_MODULE := FooMain
# Set All SRC_FILES Together
SRC_FILES := $(wildcard $(LOCAL_PATH)/FooMain/src/*.cpp)
SRC_FILES := $(SRC_FILES:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES = $(SRC_FILES)
LOCAL_SHARED_LIBRARIES := libFooSecondary
LOCAL_LDLIBS := -L$(LOCAL_PATH)/../libs/armeabi
LOCAL_LDLIBS += -lz -lm -ldl -lGLESv2 -lEGL -llog -lFooSecondary
LOCAL_CFLAGS := -O2 -mno-thumb -Wno-write-strings
LOCAL_CPPFLAGS := -O2 -mno-thumb -Wno-write-strings
# Compile as Shared Library
include $(BUILD_SHARED_LIBRARY)
And my Application.mk is:
APP_CPPFLAGS := -frtti -fexceptions
APP_STL := gnustl_static
APP_ABI := armeabi-v7a
But, when I compile Android.mk using ndk-build I get the next Error:
Compile arm : libFooSecondary <= *.c
SharedLibrary : libFooSecondary.so
Install : libFooSecondary.so => libs/armeabi-v7a/libFooSecondary.so
SharedLibrary : libFooMain.so
/home/user/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lFooSecondary
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi-v7a/libFooMain.so] Error 1
Why libFooSecondary.so is not found if is correctly compiled and installed?
Additionaly, if LOCAL_MODULE name change, for example, first one is LOCAL_MODULE := zname and second one is LOCAL_MODULE := aname, compile first the second one, i don't know why.
Your Android.mk looks weird. Does it assign LOCAL_PATH somewhere? There is no need to assign LOCAL_CPPFLAGS to duplicate LOCAL_CFLAGS, because ndk-build puts both sets of flags on C++ command line.
To understand better how NDK interprets your Application.mk and Android.mk, you can run
ndk-build V=1
This will echo all executed commands, including compilation and link, with all their parameters that NDK build assigns.
Try compiling FooSecondary as a static library and include it in FooMain as:
LOCAL_STATIC_LIBRARIES := libFooSecondary
The ndk doesn't play nicely with multiple shared libraries unless they're being dlopen'd.