For all you C4DROID dev's, I have a question about the Makefile option. I have been toying around with it for some time now, and just can't seem to get it to function properly. I've tried implementing the tutorial from http://mrbook.org/tutorials/make/ as well as http://www.gnu.org/software/make/manual/make.html#Implicit-Rules . These sites have helped me at least get different error messages (which in some ways is helpful) but I'm just not sure what else I need to be doing. I'm not sure how much detail I should include about what I'm doing (first time posting), so here goes.
At the moment, I have the files (for test purposes only) main.cpp, hello.cpp, factorial.cpp, and functions.h . I created a Makefile with:
all:
g++ main.cpp hello.cpp factorial.cpp functions.h -o MyFile
I have also tried variations like:
all: testTwo
testTwo:
g++ main.cpp hello.cpp factorial.cpp functions.h -o MyFile
In the compilation settings, I have selected Makefile, I have not modified the "Commands Before Make" code (I don't even understand it), my Make command is
make -f Makefile
I have selected the Native Activity in Run Mode, and that's all that I can think of explaining. My error message I get on compilation is "Failed to copy file".
Any help with the process would be greatly appreciated and thank you in advance.
In the compile options screen, section 'Result binary filename': enter the name of the executable that your Makefile generates i.e. MyFile for your example.
I also tend to use 'Run mode: Terminal app' for simple console programs. NativeActivity is intended for Android NDK app development and hence is a bit more involved.
Related
All the git projects for the AOSP are cloned by the repo tool, which reads this xml: https://android.googlesource.com/platform/manifest/+/refs/heads/master/default.xml.
AOSP guide says the in order to build, we should run source build/envsetup.sh on the folder where repo cloned all repositories. So let's look at the platform/build on the default.xml from the manifest repository. We get
<project path="build/make" name="platform/build" groups="pdk" >
<copyfile src="core/root.mk" dest="Makefile" />
<linkfile src="CleanSpec.mk" dest="build/CleanSpec.mk" />
<linkfile src="buildspec.mk.default" dest="build/buildspec.mk.default" />
<linkfile src="core" dest="build/core" />
<linkfile src="envsetup.sh" dest="build/envsetup.sh" />
<linkfile src="target" dest="build/target" />
<linkfile src="tools" dest="build/tools" />
</project>
We confirm where envsetup.sh is located., it is in platform/build. It defines the function m which according to the AOSP guide, builds the entire AOSP project:
function _trigger_build()
(
local -r bc="$1"; shift
if T="$(gettop)"; then
_wrap_build "$T/build/soong/soong_ui.bash" --build-mode --${bc} --dir="$(pwd)" "$#"
else
echo "Couldn't locate the top of the tree. Try setting TOP."
fi
)
function m()
(
_trigger_build "all-modules" "$#"
)
Ok, so looks like build/soong/soong_ui.bash is the place called when we run the m function, so this script should build everything.
Here's soong_ui.bash. It sources source ${TOP}/build/soong/scripts/microfactory.bash and then calls soong_build_go soong_ui android/soong/cmd/soong_ui
Here's microfactory.bash, where we find function soong_build_go
soong_build_go
{
BUILDDIR=$(getoutdir) \
SRCDIR=${TOP} \
BLUEPRINTDIR=${TOP}/build/blueprint \
EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong -pkg-path github.com/golang/protobuf=${TOP}/external/golang-protobuf" \
build_go $#
}
We find build_go in microfactory.bash from build/blueprint:
Looks like all of this is for building the microfactory.go project. I think it has something to do with the soong build system.
I'm now lost. After building microfactory.go, what happens? Where does actual Android code gets built?
microfactory.sh says build_go does this: Bootstrap microfactory from source if necessary and use it to build the requested binary. The requested binary is android/soong/cmd/soong_ui
I'm trying to find android/soong/cmd/soong_ui but I don't know what/where it is, but I'd guess is the soong build system, not the AOSP project yet.
UPDATE:
on soong_ui.bash, I noticed it end with
cd ${TOP}
exec "$(getoutdir)/soong_ui" "$#"
Remember that this is called form envsetup.sh. Well, ${TOP}, I guess, is the place where repo clones everything. Looks like it's trying to execute soong_ui with the arguments from envsetup.sh which are --build-mode --${bc} --dir="$(pwd)" "$#", where this $# is "all-modules" "$#", I guess.
I assume song_ui is the soong executable. It should look for Android.bp on the ${TOP}, but I don't think there is one on the place where repo cloned everything.
You have already found out a lot, and you are right with the link from m to soong_ui.bash and then starting microfactory.
From my reading of the code, the purpose of soong_build_go is to build the package android/soong/cmd/soong_ui, with the binary name soong_ui. Like Yong said in the other answer, this creates the binary soong_ui under the directory $(getoutdir), and the source for that binary is located at build/soong/cmd/soong_ui/main.go.
As for your updated question about an Android.bp file, it is symlinked from build/soong/root.bp when repo sync is run, but as you can see, the file is empty.
Instead, in m it tells Soong to build all_modules, which eventually runs another tool called kati. From the description in https://github.com/google/kati, Kati processes GNU makefiles and turns them into Ninja build files.
At this point we can (mostly) assume regular Make semantics, even though the underlying build system is actually Kati and Ninja and Soong etc. Since the working directory is $TOP, the Makefile at the root directory, which is symlinked from build/make/core/root.mk is used. Which includes main.mk which then includes build/make/core/Makefile. Inside that makefile you can see how the different .img files are built (e.g. system.img).
Let's take make systemimage as an example:
The call sequence is:
prebuilts/build-tools/linux-x86/bin/makeparallel --ninja build/soong/soong_ui.bash --make-mode "systemimage".
And $(getoutdir)/soong_ui is build by "build_go soong_ui android/soong/cmd/soong_ui"
build/soong/cmd/soong_ui/main.go#main()
soong/ui/build/build.go#Build()
I'm trying to compile a kernel but can't figure out how its Makefile work : https://github.com/LineageOS/android_kernel_sony_msm8994/blob/cm-14.1/scripts/Makefile.build
As I have this error when building : Build of a custom Linux/Android/LineageOS kernel in C doesn't work , I'm for now trying to understand up until the line 44.
Why are there several Makefile with extensions like .build .clean etc rather than these actions being "targets" within the main Makefile?
How can I figure out what the very first $(obj) var refers to ?
Is the mathematical syntax := "equals by definition" instead of = specific to the developper? I do saw this on mathematics notes or symbolic languages such as Wolfram/Mathematica if I'm right, but never within a program.
Why does PHONY := is a variable and not a "type of action" as in the doc ? It should be written .PHONY: as on the very last line of the file. I didn't get this trick.
Why are there 2 underscores before __build the value of PHONY ?
By thanking you for your precisions
Because the person who wrote the makefile wanted to break those out into separate files. Maybe they're included in multiple other files, or they just wanted the top-level makefile to be more clean to read.
You can run make with the -p option and it will print all the values of all the variables in the makefile.
I don't quite understand the question: the := operator in a makefile is used for simply-expanded variable assignments. See the GNU make manual for more info.
That sets the variable PHONY to contain some contents. It is just a normal variable assignment, there's nothing fancy here. Presumably somewhere else in the makefile will appear a line: .PHONY: $(PHONY) and that will make all the targets in the PHONY variable phony.
Because the person who wrote the makefile wanted to use two underscores.
I want to convert pdf to pksmraw by using ghostscript9.04, the command is:
gs -q -dBATCH -dSAFER -dQUIET -dNOPAUSE -sPAPERSIZE=a4 -r300x300 -sDEVICE=pksmraw -sOutputFile=printjob.pksmraw printjob.pdf
But in android system, it's no output, and the error code is -15.
I think it's maybe Resources and libs is can't be found.
So in android system, how to set up the Resources and libs?
error code -15 is a rangecheck error. In order to find out more you are going to have to find out where stdout and stderr are going, and capture them.
We don't supply Ghostscript for Android systems, so I assume you built this yourself, in which case it should be reasonably straight-forward for you to figure out where the error messages are going.
Oh, the current version is 9.10, you might well want to upgrade too.
Library and resource files are ordinarily built into the executable using a rom file system, unless you specified COMPILE_INITS=0 at build time.
Try this example
gs \
-sDEVICE=pdfwrite \
-o foo.pdf \
/usr/local/share/ghostscript/8.71/lib/viewjpeg.ps \
-c \(my.jpg\) viewJPEG
reads my.jpg and produces foo.pdf. You will have to find where your installation installed the PostScript program viewjpeg.ps.
Same way do it for to convert pdf to pksmraw it will work for you.
I'm facing a bug in a makefile build system (Android built under Linux) - some files are removed by an 'rm' command, and I can see that command in the build log.
How can I find the exact line in the makefiles which calls the 'rm' ? Is there any automated method?
For GNU Make you can do the following trick:
__shell := $(SHELL)
SHELL = \
$(warning making '$#'$(if $^, from '$^')$(if $?, because of '$?'))$(__shell)
SHELL variable is expanded each time when Make invokes a sub-shell to execute a recipe. In these lines it is replaced so that on each expansion it will print a target, its prerequisites and prerequisites that are newer than the target. Also each debug message is prepended with the file and line number of the rule being executed.
The same technique is used in GMD to set breakpoints to certain targets.
Assuming your make is a Gnu make, you can also pass some debugging options, like --debug=b (basic debugging messages, very often enough) or --debug=all which is the same as -d
Some files may be removed because they are intermediate. Read also about secondary files and precious files in make
You may try make -d -w and then grep your file from huge amount of output lines.
I was wondering if there is any way to access the logcat logging data from native code ?
Also if someone knows what kind of shell can be accessed on the native linux system directly on the device itself (so NOT by starting a shell through adb on a client pc !!!) ?
Thanks in advance
You can either read the raw data fom /dev/log/main or you can run the built-in shell command logcat and pipe the result to a file descriptor as usual. The logcat command is usually preferably because then the printout is easier to filter and format.
As for the built-in shell, it is called toolbox and the source can be found in the Android open source project. The shell is rather similar to bash. Toolbox contains lots more functionality than just a shell. It is very similar to Busybox, but released under another license.
You can set it up using a log tag in your source file and then include the library as so:
#define LOG_TAG "some.unique.identifier" //I usually use the class name
#include <utils/Log.h>
Then in the Android.mk file you will need to add the liblog library dependency to your LOCAL_SHARED_LIBRARIES.
LOCAL_SHARED_LIBRARIES += liblog
Also, take note that logcat looks for the LOG_TAG definition to include as part of the tagging so it makes searching for your logs easier. Then you can log as such:
int my_int = 0;
ALOGI("some logs.... print my int: %d", my_int);
ALOGI is for info, you can also use ALOGE, ALOGD, ALOGV and ALOGW for error, debug, verbose and warning logging, respectively.
ALOG* is analogous to printf. I interchange them at times if I need to debug on different platforms, say Linux.