How to compile a custom folder structure with ndk-build? - linker

I have the next folder structure:
On $My_Eclipse_Project
jni/Android.mk
jni/Application.mk
jni/main.cpp
lib/
On $My_Library_Project
src/
include/
Android.mk
$My_Eclipse_Project/jni/main.cpp is a basic makefile whom call the source to compile, following the instructions from $My_Library_Project/Android.mk
# NOTE:
$(warning Compiling Android.mk from sample_cameraview_activity)
# This path
LOCAL_PATH := $(call my-dir)
$(warning Local path: $(LOCAL_PATH))
# GNU var
include $(CLEAR_VARS)
# Include extra library
include $(mylibrary_INCLUDE)/../Android.mk
# Add openCV
# Add in .bashrc enviroment var
include $(OPENCV_SHARE_MK)/OpenCV.mk
LOCAL_ARM_NEON := true
# Local libraries
LOCAL_LDLIBS += -llog -lGLESv1_CM
# Name library
LOCAL_MODULE := camView
# Local SRC
LOCAL_SRC_FILES := main.cpp
# Shared library
include $(BUILD_SHARED_LIBRARY)
The problem is, $My_Library_Project>Android.mk don't detect the folder structure what is waiting, because my source is on src folder, don't at jni folder. I get:
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
How could i compile the code at $My_Library_Project from $My_Eclipse_Project, and copy the library generated on $My_Eclipse_Project>lib/armeabi, to be used by main.cpp?
Thanks in advance.

2 Options. You can define $NDK_PROJECT_PATH = /your_ndk_path, Makefile auto detect the path and use it to compile, or add a enviroment var with name $NDK_PROJECT_PATH and value /your_ndk_path.

Related

OpenWrt Makefile include package.mk error

I'm such a beginner on OpenWrt and Makefiles, trying to demonstrate "Helloworld" example of creating a package but at the package feed update step, from command ./scripts/feeds update mypackages I get this error
Updating feed 'mypackages' from '/home/onur/Desktop/OpenWRT/openwrt/mypackages' ...
Create index file './feeds/mypackages.index'
/home/onur/Desktop/OpenWRT/openwrt/feeds/mypackages.tmp/info/.files-packageinfo.mk:1: *** target pattern contains no '%'. Stop.
I have src-link mypackages /home/onur/Desktop/OpenWRT/openwrt/mypackages in my feeds.conf, "helloworld" C program compiled on /openwrt/helloworld directory and below is my Makefile:
include $(TOPDIR)/rules.mk
# Name, version and release number
# The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR)
PKG_NAME:=helloworld
PKG_VERSION:=1.0
PKG_RELEASE:=1
# Source settings (i.e. where to find the source codes)
# This is a custom variable, used below
SOURCE_DIR:=/home/onur/Desktop/OpenWRT/openwrt/helloworld
include $(INCLUDE_DIR)/package.mk
# Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig')
define Package/helloworld
SECTION:=examples
CATEGORY:=Examples
TITLE:=Hello, World!
endef
# Package description; a more verbose description on what our package does
define Package/helloworld/description
A simple "Hello, world!" -application.
endef
# Package preparation instructions; create the build directory and copy the source code.
# The last command is necessary to ensure our preparation instructions remain compatible with the patching system.
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR)
$(Build/Patch)
endef
# Package build instructions; invoke the target-specific compiler to first compile the source file, and then to link the file into the final executable
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CXX="$(TARGET_CROSS)g++"
endef
# Package install instructions; create a directory inside the package to hold our executable, and then copy the executable we built previously into the folder
define Package/helloworld/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin
endef
# This command is always the last, it uses the definitions and variables we give above in order to get the job done
$(eval $(call BuildPackage,helloworld))
I know I may have mistake on cross-compile part but I don't think that's the issue that I'm having right now.
When I try to make this Makefile, I get that error.
Makefile:13: /package.mk: No such file or directory
make: *** No rule to make target '/package.mk'. Stop.
I can't find any problem like this anywhere. Why it can't even find "package.mk" file.
My directory structure is like, Top directory is Desktop/OpenWrt/openwrt and this Makefile is in Desktop/OpenWrt/openwrt/mypackage folder. I'm on Ubuntu 20.04
I found solution to my question on OpenWrt Forum. Here is the link of thread

C code Makefile,how to include path?

I am trying to compile bottledwater
~/bottledwater-pg$ make
make -C ext all
make[1]: Entering directory '/home/jholmes/bottledwater-pg/ext'
Package avro-c was not found in the pkg-config search path.
Perhaps you should add the directory containing `avro-c.pc'
to the PKG_CONFIG_PATH environment variable
No package 'avro-c' found
Avro-c is here
/home/jholmes/avro-c-1.8.2
Makefile
MODULE_big = bottledwater
EXTENSION = bottledwater
AVRO_CFLAGS = $(shell pkg-config --cflags avro-c)
AVRO_LDFLAGS = $(shell pkg-config --libs avro-c)
PG_CPPFLAGS += $(AVRO_CFLAGS) -std=c99
SHLIB_LINK += $(AVRO_LDFLAGS)
OBJS = io_util.o error_policy.o logdecoder.o oid2avro.o schema_cache.o protocol.o protocol_server.o snapshot.o
DATA = bottledwater--0.1.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
How does shell expand PG_CONFIG?
What should I do to enable main code to detect avro-c folder?
I have compiled avro-c, on Ubunutu 16.04.
My avrolib path
/home/jholmes/avro-c-1.8.2/build/avrolib
~/avro-c-1.8.2/build/avrolib$ ls
bin include lib
There is no avro-c.pc inside.
Bin content
/avro-c-1.8.2/build/avrolib/bin$ ls
avroappend avrocat avromod avropipe
Since you have installed the library in a non-standard location, you need to tell pkg-config about that non-standard location. The easiest way to do that, is to set the PKG_CONFIG_PATH environment variable. You can do that when running make:
PKG_CONFIG_PATH="/home/jholmes/avro-c-1.8.2/lib/pkgconfig" make
This assumes that /home/jholmes/avro-c-1.8.2/lib/pkgconfig is where the .pc file resides.
Anyway, overall, I would instead recommend installing libraries in /usr/local instead. This should result in everything just working without manual intervention. /usr/local is a location used specifically for this purpose.

Problems with includes when migrating to experimental gradle Android Studio 2.0+

My problem goes beyond of what the title says so will give a background before the question. I've been experimenting issues since I updated from Android Studio 1.5 to 2.0 (now using 2.1.1 Stable, tried beta version as well)
Background
When I updated my Android Studio and opened c files in NDK y started receiving the following message:
This message appears even though I have already synced the project.
The compiler was working fine, as I could ignore modify things in c and it would still compile. Then I tried to add a new include of a file created by me which contains some settings and methods, the same file is included in other files working well. However, this time the compiler throws me the following error:
error: undefined reference to 'my_method'
Spent quite a while debugging but was unsuccessful, so decided to migrate to experimental gradle where this problem does not happen.
Here is what I'm using now:
- gradle-experimental:0.7.0
- wraper: gradle-2.10-all.zip
My gradle file is this:
apply plugin: 'com.android.model.application'
import org.apache.tools.ant.taskdefs.condition.Os
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig.with {
applicationId "com.domain.myapp"
minSdkVersion.apiLevel 15
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
}
}
}
task runSwig(type: Exec, description: 'Run swig config') {
workingDir 'src/main'
commandLine 'cmd', '/c', 'swig.bat'
}
ndk {
moduleName "MyNativeModule"
//toolchain "clang"
}
sources.main {
jni {
source {
srcDir 'src/main/libs' //set .so files location to libs
srcDirs = [] //disable automatic ndk-build call
}
}
}
buildTypes {
debug {
debuggable true
ndk.with {
debuggable = true
}
versionNameSuffix "1.0"
}
}
}
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'org.litepal.android:core:1.2.1'
}
Now, when I run clean it finishes successfully, but..
Now the problem:
*I'm using a libusb library
When I try to build, I get the following errors:
-Error:(20, 20) config.h: No such file or directory
-Error:(33, 30) libkern/OSAtomic.h: No such file or directory
-Error:(29, 25) dev/usb/usb.h: No such file or directory
... many others like these
In the case of config.h in the library it's included like this:
#include <config.h>
so since I have that file in a parent directory in the library, I managed to make it work this way:
#include "../config.h>
On the other hand for the other files, I don't have the directories nor the files in the library so I cannot reference them. Besides, I see these files belong to MacOS when I google them.
With standard gradle this is not a problem as it compiles like a charm!
My questions are:
Why is this happening? is there some compilation flag I'm missing to ignore these files?
How can I fix this issue, what would be the best approach?
What I've already tried:
Update NDK from 11 to 12
Switch from stable Android Studio to Beta channel and back
Tried different gradle versions stable and experimental
As I'm getting familiar with NDK and C my question might be to obvios, any help will be much appreciated!
Update
I'm building libusb library as I made some changes to it. (with stable gradle this works fine except for the problem I described above, before the update I have been using this setup for a few months, everything working as expected)
My directory structure is as follows:
-jni
-jni/myUSB/libusb
Here are my Android.mk files so you see how I'm building them:
jni:
LOCAL_PATH := $(call my-dir)
ROOT_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)
LOCAL_PATH := $(ROOT_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := myModuleName
LOCAL_CFLAGS := -O2 -ffast-math
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \
jiw.cpp \
mainFile.c \
otherFile.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/
LOCAL_SHARED_LIBRARIES := myUSB
include $(BUILD_SHARED_LIBRARY)
myUSB:
LOCAL_PATH := $(call my-dir)
ROOTUSB_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)
LOCAL_PATH := $(ROOTUSB_PATH)
include $(CLEAR_VARS)
LOCAL_MODULE := myUSB
LOCAL_CFLAGS := -O2 -ffast-math
LOCAL_LDLIBS := -llog -pthread
LOCAL_SRC_FILES := \
myUsbMainFile.c \
myUsbInterface.c \
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/
LOCAL_SHARED_LIBRARIES := android-usb
include $(BUILD_SHARED_LIBRARY)
libusb:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := android-usb
LOCAL_CFLAGS := -O2 -ffast-math
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := \
core.c \
descriptor.c \
io.c \
sync.c \
os/linux_usbfs.c \
os/threads_posix.c \
os/android_java.c
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/ \
$(LOCAL_PATH)/os
include $(BUILD_SHARED_LIBRARY)
I can't see, where you connect libusb to your project. So, you probably have to link it manually. Here is an example, how to link libraries statically/dynamically in build.gradle.

the way to put my own package and compile openwrt

I wrote my own openwrt package for my script and the compilation stage I put it in the package file as this path openwrt / feeds / package / is that the path is correct or not?
or if I have is for the compilation error:
make[1]: *** No rule to make target `package/test/compile'. Stop.
make: *** [package/test/compile] Error 2
THis my Makefile:
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=test
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
DEPENDS:= +nmap +python
include $(INCLUDE_DIR)/package.mk
define Package/test
SECTION:=secure
CATEGORY:=Monitoring
TITLE:=test
define Package/test/description
test tis is my first package
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/test/install
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/test $(1)/bin/
endef
$(eval $(call BuildPackage,test))
I need help please.
thanks.
You don't really have to put your source code anywhere in the /openwrt/ folder. It can be placed, let's say, in /Documents/[name] folder. However it is important that you put your OpenWRT-specific Makefile in the /openwrt/ tree. I am not sure if putting your Makefile in /openwrt/feeds/package is correct but I put my Makefiles in /openwrt/package/[name] folder which works fine. Your source code will be automatically copied by the toolchain to the same folder anyway.
Note: if you place your source code somewhere on your system (for example, in the Documents folder) you have to specify the path to it in your Makefile as follows: PKG_SOURCE_URL:=file://$(TOPDIR)/../Documents/[name]
Your make[1] errors are basically telling you that the toolchain could not find the Makefile. Try putting Makefile in /openwrt/package/[name].

How to write `make` file for separate source and build directory for large program with mixed Fortran F77 and F90 code

I have about 39 Fortran F90 source files and 35 Fortran 77 Lapack related files. I am using include statement in my main program to connect all these files.
I have created a batch file make.bat with command ifort "MDL HydroD.F90" which compiles my code and generates the mdlhydrod.exe file. In the process the Fortran compiler creates many .mod and .obj build files which makes it difficult to manage. I would like to put my source files under a directory Source and lapack library files in a directory lapack and build files in a directory Debug.
Could anyone help me modify my make.bat file so that ifort looks at Source directory and build in Debug directory.
Thank you for help.
Currently using make.bat has only one line of command:
File Name: make.bat
ifort "MDL HydroD.F90"
Working on a make file to be used with nmake (incomplete):
File Name: make.mak:
#Make File for MDL HydroD
# Compiler options
FC := ifort
VPATH := src
BINDIR := bin
$(BINDIR):
mkdir -p $(BINDIR)
clean:
#rm -rf $(BINDIR)
Because you are using a strange way of working with source files, which you showed in your other question, it will be very difficult to change this.
For recapitulation, you include everything in a single source file using the include statement. This looks pretty unfortunate to me and I commented on that there. If you have one source file, you are forced to build it with one command, there is no place for any fine control. This is not the issue of a bash or bat script vs. Makefile.
You can probably still keep some files included in some groups that are logically similar, if you need no finer control on that, but I see not much reason for that.
Remove the includes or at least the relevant ones. Then you can just do
ifort Source/the_source_file1 -c Output/name_of_obj1 -module the_directory_for_modules -I the_directory_for_modules -other_flags
for every file. And then in the end:
ifort Output/name_of_obj1 Output/name_of_obj2 Output/name_of_obj3 .... -o the_result
In Scons (which I would use) it would be like this (tested on couple of dummy files). The file Sconstruct:
import os
env = Environment(tools=['default','ifort'])
env.Append(ENV = {'PATH' : os.environ['PATH']})
try:
env.Append(ENV = {'LIBRARY_PATH' : os.environ['LIBRARY_PATH']})
except:
pass
env.Append(F90FLAGS='-g -fast') #whatever flags you need
env.Append(FORTRANFLAGS='-g -fast') #whatever flags you need
outdir = "Output/"
srcdir = "Sources/"
lapackdir = "lapack/"
objs = []
for file in os.listdir(srcdir):
objs += env.Object(target=outdir+os.path.splitext(file)[0], source=srcdir+file)
for file in os.listdir(lapackdir):
objs += env.Object(target=outdir+os.path.splitext(file)[0], source=lapackdir+file)
env.Append(FORTRANMODDIR = outdir)
objs = filter(lambda o: str(o)[-4:] != '.mod', objs)
prg = env.Program(target="bin/result.exe", source= objs)
Default(prg)

Resources