Petalinux - Multiple Source File application - c

I'm pretty new to the 2020.2 version of Petalinux and I'm trying to create a simple application inside my project using the C template.
After creating the helloworld-app using the command:
petalinux-create -t apps --template c --name helloworld-app
After enabling the default application and building it successfully,I tried to add some functionality by creating a new directory under helloworld-app/files called Ethernet, containing 2 files Etherent.c and Ethernet.h
Finally, I added the Ethernet.o object to the list inside the auto-generated Makefile for the module, I also added a VPATH for simplicity.
Unfortunately the build fails, in fact bitbake tells me that no rule for the object Ethernet.o is specified.
How can I modify the makefile in order for this simple code to compile?
I can edit the .bb file? I would like not to, since in that way i would have to specify every src file...
Thank you for the support!
Ethernet.c:
#include "Ethernet.h"
//some C code
helloworld-app.c:
#include <stdio.h>
#include "Ethernet/Ethernet.h"
//some C code
Makefile:
APP = helloworld-app
VPATH=Ethernet
# Add any other object files to this list below
APP_OBJS = helloworld-app.o Ethernet.o
all: build
build: $(APP)
$(APP): $(APP_OBJS)
$(CC) -o $# $(APP_OBJS) $(LDFLAGS) $(LDLIBS)
clean:
rm -f $(APP) *.o
Below I included the output of the petalinux-build -c helloworld-app command:

A simple solution, but really cumbersome if the number of files increases, is to simply add the path to the source files to the variable SRC_URI inside the .bb file. I will leave this question without an accepted answer, waiting for a more sustainable solution.
Thanks to everyone!

Related

How does Redis Makefile include header file prerequisites

I was teaching myself GNU Make and thought a look at the Redis Makefile would teach me a thing or two about the tool.
The rule that compiles the source file to the object file is here:
%.o: %.c .make-prerequisites
$(REDIS_CC) -c $<
Notice that the suffix rule just mentions the C source file (with %.c) as a prerequisite.
But if I add a echo in the middle and run make:
%.o: %.c .make-prerequisites
echo $^
$(REDIS_CC) -c $<
Then the first few lines of the output from make is like below:
cd src && make all
make[1]: Entering directory `/home/cltpadmin/code/redis/src'
echo adlist.c .make-prerequisites adlist.h zmalloc.h
adlist.c .make-prerequisites adlist.h zmalloc.h
CC adlist.o
How did make know that adlist.c depends on adlist.h and zmalloc.h?
The prerequisites in question come from line one of the Makefile.dep included makefile (included on line 134).
The dep target on line 136 generates that file.
This was a fairly common (though entirely avoidable) step for using the compiler to generate the necessary header file includes. This static method also has issues with conditional header includes I believe.
To clarify, the "avoidable" part of this is that it need not be a separate step and a static dependency file at all. See Advanced Auto-Dependency Generation for details about this idea.

Makefile with multiple submodules

I have following program structure:
main.c
Makefile
Submodule
--{somefiles}
--Makefile
Submodule is creating library submodule.a. It has many source files and it need some libraries.
All I want to know that
Makefile in submodule knows how to make submodule.a
Makefile in submodule sets variable SUBMODULE_LDFLAGS and SUBMODULE_LDLIBS
How can I write Makefile in root project directory that:
it would create submodule.a using Makefile in submodule
it would add SUBMODULE_LDFLAGS and SUBMODULE_LDLIBS to its own variable?
AT the end I want the following command in main Makefile works correctly:
TARGET = MyProgram
OBJS = $(TARGET).o submodule/submodule.a
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $# $(LDLIBS)
Now it creates MyProgram.o and cannot create MyProgram, because Makefile doesn't know how to make submodule/submodule.a.
I can add lines:
submodule/submodule.a:
make -C submodule
but it won't help me with missing libraries.
There is no direct way for the sub-Make to pass variables to the parent process. There are (at least) two indirect ways.
You could have the sub-Make write a file containing the variable values, which the parent Make could then read.
You could copy the part of submodule/Makefile that constructs those variables, and put it into Makefile. Better still, you could isolate that code in a separate file that both makefiles would then include.
EDIT:
One disadvantage of recursive Make is that it interrupts much of Make's dependency handling. In this case, there's no clean way to have the sub-make run when and only when one of the library's sources is changed.
You can put the list of submodule sources -- or the code that constructs the list -- in a separate file which both makefiles will include. Then those files can be among the prerequisites of $(TARGET).
Or, you could make submodule/submodule.a a PHONY target. In that case, Make will rebuild the binary every time, but otherwise it'll work perfectly.

multiple small programs in one code::blocks project

I am new to Code::Blocks. For my studies I am programming several small programms in C (just to try things out).
I tried to put them all in one project, because they belong to the same topic, but that doesn't work because each of them has a main function.
Any ideas how I can put those files together somehow, but not depending on each other?
Suppose your source files are called
prog1.c
prog2.c
mylib.c
mylib.h
where prog1.c and prog2.c each contain a main() function and mylib.c (with the corresponding header file mylib.h) contains some library functions that should be linked to each program. In your Code::Blocks project you need to create multiple targets now. From the menu choose 'File/New/Build target...' and name them 'prog1' and 'prog2'. Now add all of your source files to the project (in case you haven't done so already).
Now right-click on prog1.c and select "Properties..." from the context menu. In the dialog box choose the 'Build' tab and make sure that under "Belongs to target" only "prog1" is checked. Do the same with prog2.c and the target "prog2". For "mylib.c" make sure that both "prog1" and "prog2" are checked.
Now you can easily choose in the UI which build target to build and run. Note that if you add another target, say "prog3", then you have to go to the build properties of prog1.c and prog2.c again and uncheck "prog3".
A C program should contain only one main function.. Divide all your separate programs as Functions and put them in a single C program or you can even put it in multiple files and compile them..
You can use a switch case for calling different functions..
Remove the main function from all the programs and convert them into functions..
Call them where ever required.. This will help you..
let's say that your project contains 3 c files and each c file is a separate program and it contains its own main function:
program1.c
program2.c
program3.c
So you can write a Makefile (its name in your computer should be "Makfile"). It will build the program you want separately
This is how your makefile looks:
all: program1 program2 program3
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $^
program1: program1.o
$(CC) $(LDFLAGS) -o $# $^
program2: program2.o
$(CC) $(LDFLAGS) -o $# $^
program3: program3.o
$(CC) $(LDFLAGS) -o $# $^
clean:
rm -f *.o program1 program2 program3
with the above Makefile you can build each program separetly
example
$ make program1
will build only program1
or you can buil all programs with
$make all
It seems to me as if you are starting to build some nice utility functions. So follow the advice offered by raghu-srikanth-reddyce and create separate functions for each little program. However I would add that it would be better to create yourself a simple C library to keep them all in which you can link to at any time. Most professional programmers keep such libraries.
A simple makefile will enable you to build a final binary that you can link to.
Good luck with your programming ;)
If you want to compile in one file, you dont need a Project File then.
Just make a New File, then write all the code in a single file. Also use Function and Procedure if you need it.
This is quite late but since I was once here with the same question, and I believe most students had/ have/ will have this same question, let me elaborate where you have been played at.
In Educational Courses and in Real World, a project is (in general) some problem you work on, find a solution, then make a report (+ documentation) on it.
In Programming IDE, a project is the problem's solution itself. Hence, while you may have multiple individual problems within one project in any Python IDE, Any standard C/C++ IDE project must have only one 'main()' to rule them all (unless you know how to create makefiles).
What the AP tried to do is to put several different problem's solutions fit within one solution's space - not a possible thing to do in Code::Blocks. Even if all the problems may share the same topic (say, Graph Theory), they are individual problem (Dijkstra vs Floyd) themselves.

Updating source files to different folder using makefile in Linux

I have a Linux GNU C project that requires building output for two different hardware devices, using a common C source code base, but different makefiles. Presently I have two makefiles in the same folder, one for each device, and when I make a change to the code, I have to first do "make clean" to make the first model, then "make clean" to make the second model. This is because they use different compilers and processors. Even if a code file didn't change, I have to recompile it for the other device.
What I would like to do is use a different folder for the second model, so it stores a separate copy of *.d and *.o files. I would not have to "make clean", only recompile the changed sources. I have looked at makefile syntax, and being new to Linux, can only scratch my head at the cryptic nature of this stuff.
One method I'm considering would update the .c & .h files from model_1 folder into model_2 folder. Can someone provide me with a simple makefile that will copy only newer *.c and *.h files from one folder to another?
Alternatively, there must be a way to have a common source folder, and separate output folders, so duplicated source files are not required. Any help to achieve that is appreciated. I can provide the makefiles if you want to look at them.
You want to generated files (object and dependencies) put into a separate folder for each build type as it compiles. Here's what I had do that may work for you:
$(PRODUCT1_OBJDIR)/%.o $(PRODUCT1_OBJDIR)/%.d: %.cpp
#mkdir -p $(#D)
$(CXX) $(PRODUCT1_DEPSFLAGS) $(CXXFLAGS) $(INCLUDE_DIR) $< -o $(PRODUCT1_OBJDIR)/$*.o
$(PRODUCT2_OBJDIR)/%.o $(PRODUCT2_OBJDIR)/%.d: %.cpp
#mkdir -p $(#D)
$(CXX) $(PRODUCT2_DEPSFLAGS) $(CXXFLAGS) $(INCLUDE_DIR) $< -o $(PRODUCT2_OBJDIR)/$*.o
$PRODUCT1_OBJDIR and $PRODUCT2_OBJDIR are variables names for the directory where you wish to have the generated files stored. This will check for changes to dependencies and recompile if needed.
If you still have problems, get back with feedback, will try and sort you out.
You could compile your source files to object files in different directories ("folder" is not really the appropriate word on Unix). You just have to set appropriate make rules. And you might use other builders like omake, scons, ...
You could use remake to debug your GNU Makefile-s. You could have inside a rule like
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(COMPILE.c) -c $^ -o $#
And you could set (earlier in your Makefile) variables with e.g.
OBJDIR:=obj-$(shell uname -m)
or something better
I do suggest to read GNU make's manual; it has an introduction to makefiles.
This can be easily achieved with makepp's repository mechanism. If you call makepp -R../src ARCH=whatever then it will symbolically link all parts of ../src under the current directory and compile here.
You can even create a file .makepprc and put in any options specific to this architecture, so you'll never get confused which command to call where.
If your different architectures have identically produced files (like generated sources), you can even build in ../src and the other architecture will pick up everything that doesn't depend on your current compile options.
There is much more to makepp. Besides doing almost all that GNU make can, there are lots more useful things, and you can even extend your makefiles with some Perl programming.

make: Nothing to be done for `all'

I am going through an eg pgm to create a make file.
http://mrbook.org/tutorials/make/
My folder eg_make_creation contains the following files,
desktop:~/eg_make_creation$ ls
factorial.c functions.h hello hello.c main.c Makefile
Makefile
# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=gcc
# Hwy!, I am comment no.2. I want to say that CFLAGS will be the
#options I'll pass to the compiler
CFLAGS=-c -Wall
all:hello
hello:main.o factorial.o hello.o
$(CC) main.o factorial.o hello.o -o hello
main.o:main.c
$(CC) $(CFLAGS) main.c
factorial.o:factorial.c
$(CC) $(CFLAGS) factorial.c
hello.o:hello.c
$(CC) $(CFLAGS) hello.c
clean:
rm -rf *o hello
error:
desktop:~/eg_make_creation$ make all
make: Nothing to be done for `all'.
Please help me understand to compile this program.
Sometimes "Nothing to be done for all" error can be caused by spaces before command in makefile rule instead of tab. Please ensure that you use tabs instead of spaces inside of your rules.
all:
<\t>$(CC) $(CFLAGS) ...
instead of
all:
$(CC) $(CFLAGS) ...
Please see the GNU make manual for the rule syntax description: https://www.gnu.org/software/make/manual/make.html#Rule-Syntax
Remove the hello file from your folder and try again.
The all target depends on the hello target. The hello target first tries to find the corresponding file in the filesystem. If it finds it and it is up to date with the dependent files—there is nothing to do.
When you just give make, it makes the first rule in your makefile, i.e "all". You have specified that "all" depends on "hello", which depends on main.o, factorial.o and hello.o. So 'make' tries to see if those files are present.
If they are present, 'make' sees if their dependencies, e.g. main.o has a dependency main.c, have changed. If they have changed, make rebuilds them, else skips the rule. Similarly it recursively goes on building the files that have changed and finally runs the top most command, "all" in your case to give you a executable, 'hello' in your case.
If they are not present, make blindly builds everything under the rule.
Coming to your problem, it isn't an error but 'make' is saying that every dependency in your makefile is up to date and it doesn't need to make anything!
Make is behaving correctly. hello already exists and is not older than the .c files, and therefore there is no more work to be done. There are four scenarios in which make will need to (re)build:
If you modify one of your .c files, then it will be newer than hello, and then it will have to rebuild when you run make.
If you delete hello, then it will obviously have to rebuild it
You can force make to rebuild everything with the -B option. make -B all
make clean all will delete hello and require a rebuild. (I suggest you look at #Mat's comment about rm -f *.o hello
I think you missed a tab in 9th line.
The line following all:hello must be a blank tab. Make sure that you have a blank tab in 9th line. It will make the interpreter understand that you want to use default recipe for makefile.
That is not an error; the make command in unix works based on the timestamps. I.e let's say if you have made certain changes to factorial.cpp and compile using make then make shows
the information that only the cc -o factorial.cpp command is executed. Next time if you execute the same command i.e make without making any changes to any file with .cpp extension the compiler says that the output file is up to date. The compiler gives this information until we make certain changes to any file.cpp.
The advantage of the makefile is that it reduces the recompiling time by compiling the only files that are modified and by using the object (.o) files of the unmodified files directly.
Using the comment from Paul R, I found that
make clean
followed by
make
or
make all
fixed my problem.
I arrived at this peculiar, hard-to-debug error through a different route. My trouble ended up being that I was using a pattern rule in a build step when the target and the dependency were located in distinct directories. Something like this:
foo/apple.o: bar/apple.c $(FOODEPS)
%.o: %.c
$(CC) $< -o $#
I had several dependencies set up this way, and was trying to use one pattern recipe for them all. Clearly, a single substitution for "%" isn't going to work here. I made explicit rules for each dependency, and I found myself back among the puppies and unicorns!
foo/apple.o: bar/apple.c $(FOODEPS)
$(CC) $< -o $#
Hope this helps someone!
I was trying to install libuv on Ubuntu and i also got the error make: Nothing to be done for 'all'. As i see it, using make gives two ways to solve the problem, one for check and one for install. But i found a workaround
still use the sudo make check command - it helps to read all the error messages before deciding on further actions. Basically, i've introduced a regression that makes the update workaround inefficient. This error comes from make however, the workaround from install fixes this, just try to run sudo make install and see what happens.
The make command will be a local optimization at the expense of the overall result of check/install - c'est ma façon de parler.
I believe i have narrowed down the problem considerably: in the first case after check i have "FAIL: test/run-tests" and in the second after install i get "specify the full pathname of the library, or use the '-LLIBDIR'" This argument to check/install can be a list object to store information about completed installations.
So install reports partial success when nothing actually happened.
Try running the commands from root:
cd your_program
sh autogen.sh
./configure
make
make check
make install
And then he writes that the installation was successful:
Libraries have been installed in:
/usr/local/lib
In your case, I strongly feel the only and simple problem you had is that you only preprocessed your app. You did so by having the flag -c under CFLAGS.

Resources