programming
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
programming [2009/06/17 00:45] – memeruiz | programming [2021/02/01 05:55] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Programming ====== | ====== Programming ====== | ||
+ | |||
+ | [[bash]] | ||
+ | |||
===== C ===== | ===== C ===== | ||
* With GCC one can do inline functions (useful with microcontrollers). [[http:// | * With GCC one can do inline functions (useful with microcontrollers). [[http:// | ||
Line 16: | Line 19: | ||
* Variables are used with $() | * Variables are used with $() | ||
- | * " | + | * " |
* MAKEFILES is an environmental variable that tells make to include the makefiles listed there if they exist. Used in recursive invocations of make. | * MAKEFILES is an environmental variable that tells make to include the makefiles listed there if they exist. Used in recursive invocations of make. | ||
+ | * It seems that Double-colon rules (::) are always executed (updated) | ||
+ | * make -n target will print the commands to update target without executing them. make -s silences echoing. | ||
+ | * $? only files that have change from the list of prerequisites of a rule. | ||
+ | * $^ list of all the prerequisites of a rule. | ||
+ | * $@ target | ||
+ | * $< is only the first prerequisite. Useful when you have also header files as prerequisites but you don't want to put them on the compilation commands. | ||
+ | * A prerequisite can be of the form: -lname. It will look for a file called | ||
+ | * Wildcards only get automatically expanded in rules for the rest use: $(wildcard pattern...) | ||
+ | * Substitution: | ||
+ | * VPATH contains the search directories. vpath Directive is a search path for files under a pattern | ||
+ | |||
+ | vpath %.h ../headers | ||
+ | |||
+ | * CFLAGS variable is use during the c implicit rule compilation. | ||
+ | * make -C dir specifies the working directory. Activates -w for printing " | ||
+ | * See the phony section in the manual for multiple directory makefiles, and parallel processing | ||
+ | * Trick to generate several programs in the same directory: | ||
+ | |||
+ | all : prog1 prog2 prog3 | ||
+ | | ||
+ | ... rules for programs | ||
+ | |||
+ | * extradeps= takes the argument from make extradeps=foo | ||
+ | * $(objects): %.o: %.c Static Pattern rules. One can specify to which target is applies, you can't with implicit rules. It overwrites implicit rules. | ||
+ | * $(filter %.o, | ||
+ | * $* expands to what is in % (the stem) | ||
+ | * When a target appears in more than one rule the rules must be of the same type (: or ::) | ||
+ | * When a target appears in more that one :: rule, the rules executed are the ones where the target is older than the prerequisites. | ||
+ | * cc -MM main.c gives main.o : main.c defs.h | ||
+ | * For each source file name.c there is a makefile name.d which lists what files the object file name.o depends on. | ||
+ | |||
+ | * Here is the pattern rule to generate a file of prerequisites (i.e., a makefile) called name.d from a C source file called name.c: | ||
+ | |||
+ | %.d: %.c | ||
+ | @set -e; rm -f $@; \ | ||
+ | $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \ | ||
+ | sed ' | ||
+ | rm -f $@.$$$$ | ||
+ | |||
+ | * $(sources: | ||
+ | * @ disables echoing in the shell commands area. | ||
+ | * For command execution each line gets executed with a separated shell. Be careful with " | ||
+ | * Check "&&" | ||
+ | * make -j . Gives parallel processing. | ||
+ | * make -i . Ignores all errors. | ||
+ | * If a target fails the right thing to do is to erase the target file. Check [[http:// | ||
+ | * Recursive make: | ||
+ | |||
+ | | ||
+ | cd subdir && $(MAKE) | ||
+ | |||
+ | * Use $(MAKE) instead of make | ||
+ | * You can export variables to the sub-make with " | ||
+ | * Canned sequences of commands are like functions or macros but is really a variable. You can called from rule commands. syntax: | ||
+ | |||
+ | define name | ||
+ | cmd | ||
+ | cmd | ||
+ | ... | ||
+ | endef | ||
+ | |||
+ | * For avoiding that a target gets an implicit rule use: target: ; An empty command target | ||
+ | * = variables are called recursive variables. They do recursive expansion. | ||
+ | * := simply expanded variables. | ||
+ | * FOO ?= bar , this assignment only happens if FOO hasn't been assigned before. | ||
+ | * Substitution references: Is an abbreviation of patsubst | ||
+ | |||
+ | foo := a.o b.o c.o | ||
+ | bar := $(foo: | ||
+ | |||
+ | * Variables in the environment become make variables | ||
+ | * To add more text to an existing variable use += . += over a non existing variable acts as = . If the variable existed before it acts according to the type of variable. | ||
+ | * define directive is similar to " | ||
+ | * target specific variable assignments. | ||
+ | * pattern specific variable assignments. | ||
+ | * conditionals : | ||
+ | |||
+ | ifeq(variable, | ||
+ | statements | ||
+ | else | ||
+ | statements | ||
+ | endif | ||
+ | |||
+ | * conditionals: | ||
+ | * function call. $(function arguments) . Find functions [[http:// | ||
+ | * $(foreach var, | ||
+ | * $(call variable, | ||
+ | * make -p in a directory without Makefile to see all the implicit rules. | ||
+ | * n.o is made automatically from n.c with a command of the form `$(CC) -c $(CPPFLAGS) $(CFLAGS)' | ||
+ | * n.o is made automatically from n.s by running the assembler, as. The precise command is `$(AS) $(ASFLAGS)' | ||
+ | * n.s is made automatically from n.S by running the C preprocessor, | ||
+ | * n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise command used is `$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)' | ||
+ | * Variables used by implicit rules [[http:// | ||
+ | * pattern rules contain % in the target | ||
+ | * List of automatic variables [[http:// | ||
+ | * Canceling implicit rules. | ||
+ | * study the following commands. Seem to be useful: cat cmp cp diff echo egrep expr false grep install-info ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true | ||
+ | * Quick reference [[http:// | ||
+ | |||
+ | ===== Microcontrollers and GCC ===== | ||
+ | |||
+ | Programming and generating code for a system where Linux is already running usually involves just writing the source code for the program, some libraries and some Makefiles. One thing that is always happening, every time that some code is generated that can be useful to use in a system, is linking. During linking basically the code generated by the compiling process, called object code, from all the source files plus the code from library files gets " | ||
+ | The approach that I follow to deal with this was the following: | ||
+ | - Get an example of a project for a microcontroller that requires to set memory layouts by hand, I got an example for the stm32 Arm microcontrollers. | ||
+ | - Read the complete GCC users manual. This is important to know what is going on during the whole compilation process. | ||
+ | - Read the complete Makefile users manual. This is big but very important. Now I understand much more variations of Makefiles. | ||
+ | - Read the complete manual for ld the linker. This is where you will find the information for writing linker scripts. | ||
+ | You may wander why you don't have to do this in your linux i386 PC computer, this is because there is already a default ld script for your system and it gets used automatically. So you don't notice. But if you dare you can try to write your own ld script for your i386 and try to get your program running with it. | ||
programming.txt · Last modified: 2021/02/01 05:55 by 127.0.0.1