| Both sides previous revisionPrevious revisionNext revision | Previous revision |
| learn:programming_c_00prep [2026/08/11 10:29] – [Practical makefile] azman | learn:programming_c_00prep [2026/08/11 10:51] (current) – azman |
|---|
| ====== C Programming: Preparations ====== | ====== C Programming: Preparations ====== |
| |
| Obviously we need a text editor (some may want to call it code editor, to be more spcific) to write code, a C compiler to compile the code and a linker to create the executable. What is most commonly used would probably be an Integrated Development Environment (IDE) which combines all of them into a single environment which is mainly the editor - the compiler and linker are just menu items or buttons somewhere within. | Obviously, a text editor (some may want to call it code editor, to be more spcific) to write code, a C compiler to compile the code and a linker to create the executable. What is most commonly used would probably be an Integrated Development Environment (IDE) which combines all of them into a single environment which is mainly the editor - the compiler and linker are just menu items or buttons somewhere within. |
| |
| //**Note**: It is advisable to manage your source file in proper folder/path hierarchy. One thing about naming files and paths is NEVER use a whitespace character (' ') in them, no matter what Windows says about them not being a problem (Apparently, even Windows have ditched 'My Documents').// | //**Note**: It is advisable to manage source files in proper folder/path hierarchy. One thing about naming files and paths is NEVER use a whitespace character (' ') in them, no matter what Windows says about them not being a problem (Apparently, even Windows have ditched 'My Documents').// |
| |
| ===== Code Editing ===== | ===== Code Editing ===== |
| |
| The source file is just a text file - so, it is actually possible to use any text editor. On Windows platform, ''notepad'' or even the console-based ''edit'' (relic from DOS era) can be used to write code. The downside of using these editors are they lack syntax-highlighting which is very useful to start learning programming by helping you spot keyword/structure-related syntax errors early on. There are a lot of free code editors (text editor specifically for programming purpose that provides syntax highlighting) - a recommended editor is [[https://www.geany.org/|Geany]]. | The source file is just a text file - so, it is actually possible to use any text editor. On Windows platform, ''notepad'' or even the console-based ''edit'' (relic from DOS era) can be used to write code. The downside of using these editors are they lack syntax-highlighting which is very useful to start learning programming by making it easier to spot keyword/structure-related syntax errors early on. There are a lot of free code editors (text editor specifically for programming purpose that provides syntax highlighting) - a recommended editor is [[https://www.geany.org/|Geany]]. |
| |
| On Linux, IDEs are also available but many veteran programmers simply use Linux text editors which naturally supports syntax highlighting. Among the popular editors are ''Emacs'' and ''Vim''. On popular distributions like Ubuntu, the supplied GUI-based editor (GNOME editor a.k.a. ''gedit'', which is available on all distributions that use GNOME desktop) should be sufficient. On KDE desktop, ''kwrite'' or ''kate'' does the job pretty well. | On Linux, IDEs are also available but many veteran programmers simply use Linux text editors which naturally supports syntax highlighting. Among the popular editors are ''Emacs'' and ''Vim''. On popular distributions like Ubuntu, the supplied GUI-based editor (GNOME editor a.k.a. ''gedit'', which is available on all distributions that use GNOME desktop) should be sufficient. On KDE desktop, ''kwrite'' or ''kate'' does the job pretty well. |
| ===== Managing a Project ===== | ===== Managing a Project ===== |
| |
| If you are using a full-fledged IDE, you will find everything but the kitchen sink available (sometimes a sink can also be found :-D). One of the things that ''make'' an IDE seems to work better is having a project management flow, i.e. keeping tracks of source files required to build the project, which compiler to use, etc. For an old school developer, using a ''makefile'' (requires ''make'' tool) makes more sense. This is what I am going to introduce here. | If using a full-fledged IDE, it is common to find everything but the kitchen sink available (sometimes a sink can also be found :-D). One of the things that ''make'' an IDE seems to work better is having a project management flow, i.e. keeping tracks of source files required to build the project, which compiler to use, etc. For an old school developer, using a ''makefile'' (requires ''make'' tool) makes more sense. This is what going to be introduced here. |
| |
| Like other configuration files in Unix/Linux systems, writing a ''makefile'' (which is also a simple text file) is relatively easy. Any strings following the '#' character are treated as comments. A simple example of a ''makefile'' that can be used to compile a C program from a single 'single.c' source file is shown below. | Like other configuration files in Unix/Linux systems, writing a ''makefile'' (which is also a simple text file) is relatively easy. Any strings following the '#' character are treated as comments. A simple example of a ''makefile'' that can be used to compile a C program from a single 'single.c' source file is shown below. |
| </file> | </file> |
| |
| I will explain the syntax after the next example. Take note that there should be a single hard tab before the gcc command. The given example however is not very convenient because I have to change a lot of things (three words at least in the example) if I decided to change file or project name. The example below gives us a more generic ''makefile''. | The syntax will be explained after the next example. Take note that there should be a single hard tab before the gcc command. The example given above, however, is not very convenient because a lot of things have to be changed (three words at least in the example) if there is a change to file or project name. The example below gives a more generic ''makefile''. |
| |
| <file make makefile> | <file make makefile> |
| </file> | </file> |
| |
| The two common things that we do in a makefile is to define build rules and to define variables. The lines that contains a '=' is usually a variable definition. Any environment variable is imported into our ''make'' environment. A rule is defined by specifying a target that is done by specifying a label (or target object name) followed by a ':' character. In our example, the target is $(PROJECT) - which is a variable and expands to ''single''. Anything that comes after ':' will be considered as a prerequisite. If a target is older than any of its prerequisites, it will be rebuilt by ''make'' tool. The build process is defined by the lines following the target (there can be more than 1 line). Notice that the MUST BE a hard tab character at the beginning of a process line. | The two common things done in a makefile is to define build rules and to define variables. The lines that contains a '=' is usually a variable definition. Any environment variable is imported into ''make'' environment. A rule is defined by specifying a target that is done by specifying a label (or target object name) followed by a ':' character. In the given example, the target is $(PROJECT) - which is a variable and expands to ''single''. Anything that comes after ':' will be considered as a prerequisite. If a target is older than any of its prerequisites, it will be rebuilt by ''make'' tool. The build process is defined by the lines following the target (there can be more than 1 line). Notice that the MUST BE a hard tab character at the beginning of a process line. |
| |
| Imagine now that you have a hundred source files. Using the above rule, changing one source file will cause all the other source files to be recompiled again. This is not very efficient. Thus, if you remember you introductory lecture for computer programming, an executable is built by combining object files and linking them to the respective libraries. Object files (*.o or *.obj) can be built independently. So, to have that, we alter our ''makefile'' to accommodate this. | Imagine now that there are a hundred source files assigned to 'SOURCE'. Using the above rule, changing one source file will cause all the other source files to be recompiled again. This is not very efficient. It is actually useful to know that an executable is built by combining object files and linking them to the respective libraries. Object files (*.o or *.obj) can be built independently. So, to have that, the ''makefile'' needs some additional line(s) to accommodate this. |
| |
| <file make makefile> | <file make makefile> |
| </file> | </file> |
| |
| There are a few new things here. Special variables like $@, $+ and $< are now used. To know what they mean, you may refer to the note at the end of this section. The prerequisites are now object files that needs to be built as well. In order to build these, ''make'' will refer to the second rule ''%.o: %.c'' - which says that any object files (*.o) needs to be built depends on a source C file (*.c) that will be built using gcc with a ''-c'' parameter (compile only). | There are a few new things here. Special variables like $@, $+ and $< are now used. To know what they mean, refer to the note at the end of this section. The prerequisites are now object files that needs to be built as well. In order to build these, ''make'' will refer to the second rule ''%.o: %.c'' - which says that any object files (*.o) needs to be built depends on a source C file (*.c) that will be built using gcc with a ''-c'' parameter (compile only). |
| |
| One thing you should know is ''make'' will use the first matching rule that it finds. So, if you have some object files that depends on both source (*.c) and header (*.h) files, you need to create the rule (''%.o: %.c %.h'') //before// the rule given above. | One important thing to know is ''make'' will use the first matching rule that it finds. So, if you have some object files that depends on both source (*.c) and header (*.h) files, you need to create the rule (''%.o: %.c %.h'') //before// the rule given above. |
| |
| The given information so far about makefiles should be sufficient for basic projects. You will learn, in time, of more advanced ways to specify rules that will show you how the ''make'' tool can be a very powerful build management tool. | The given information so far about makefiles should be sufficient for basic projects. You will learn, in time, of more advanced ways to specify rules that will show you how the ''make'' tool can be a very powerful build management tool. |