User Tools

Site Tools


guides:software:make:start

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
guides:software:make:start [2020/07/20 15:20] – [Building Multiple Targets] wikiadminguides:software:make:start [2022/08/02 11:59] (current) – external edit 127.0.0.1
Line 3: Line 3:
  
 Make is a build automation tool that is designed to automatically construct executable programs from source code. Make is a build automation tool that is designed to automatically construct executable programs from source code.
 +
 +Make simplifies the build process for projects at all levels.
  
 ===== Simple Use ===== ===== Simple Use =====
Line 261: Line 263:
 </code> </code>
  
-Secondly, the default target has been changed.  Instead of listing a single target, or even multiple targets, the variable //OBJS// is specified.  Make will replace this variable with the values stored in the variable.  The variable is specified as //${OBJS}// in this case.  +Secondly, the default target has been changed.  Instead of listing a single target, or even multiple targets, the variable //OBJS// is specified.  Make will replace this variable with the values stored in the variable.  The variable is specified as //${OBJS}// in this case.    Don't worry about the syntax, just copy it.  As you learn more about //shell programming// this syntax will be easier to understand.
  
 <code make> <code make>
Line 289: Line 291:
  
 ===== Makefiles for Multiple File Compilation ===== ===== Makefiles for Multiple File Compilation =====
 +
 +One of the most powerful uses of make is to compile multiple files into a single executable.
 +
 +==== Example ====
 +
 +For this example the code is decomposed into the following files:
 +
 +  * //stringTools.h// defines a method for converting a string to lowercase
 +    * <code c++>
 +#ifndef STRING_TOOLS
 +#define STRING_TOOLS
 +
 +void  LowerCase(std::string & word);
 +
 +#endif
 +</code>
 +  * //stringTools.cpp// implements the code in stringTools.h
 +    * <code c++>
 +include <iostream>
 +#include <cstdlib> // gives access to tolower
 +#include "stringTools.h"
 +
 +using namespace std;
 +
 +void  LowerCase(string & word){
 +    for(auto &x : word) {
 +       x = static_cast<char> (tolower(static_cast<int> (x)));
 +    }
 +
 +    return;
 +}
 +</code>
 +
 +  * //greeting.h//
 +    * <code c++>
 +#ifndef GREETING
 +#define GREETING
 +
 +std::string GreetingString(std::string language);
 +
 +#endif
 +</code>
 +  * //greeting.cpp//
 +    * <code c++>
 +
 +#include <iostream>
 +
 +#include "greeting.h"
 +#include "stringTools.h"
 +
 +using namespace std;
 +
 +string GreetingString(string language){
 +    string greeting = "Hello World";
 +
 +    LowerCase(language);
 +
 +    if (language == "pig") {
 +       greeting = "Ellohay Orldway";
 +    } else if (language == "ubbi") {
 +       greeting = "Hubellubo Wuborublubdub";
 +    }
 +
 +    return greeting;
 +}
 +</code>
 +  * //hello.cpp//
 +    * <code c++>
 +#include <iostream>
 +
 +#include "greeting.h"
 +
 +using namespace std;
 +
 +int main() {
 +    string languages[] = {"PIG", "piG","UBBI", ""};
 +
 +    for (auto lang: languages) {
 +        cout << " The greeting in \"" << lang << "\"" << endl;
 +        cout << GreetingString(lang) << "!" << endl;
 +    }
 +
 +    return 0;
 +}
 +</code>
 +  * //Makefile//
 +    * <code make>
 +CXXFLAGS = -g -O3 -Wpedantic -Wall -Wextra -Wmisleading-indentation -Wunused -Wu
 +ninitialized -Wshadow -Wconversion -std=c++14
 +
 +OBJS =  hello
 +
 +all: ${OBJS}
 +
 +hello: greeting.o stringTools.o
 +
 +greeting.o: greeting.h stringTools.h
 +
 +stringTools.o: stringTools.h
 +
 +clean:
 +        rm -f ${OBJS} *.o
 +</code>
 +
 +To build this code, you are required to compile stringTools.cpp into stringTools.o, greeting.cpp into greeting.o and finally build hello from hello.cpp, stringTools.o and greeting.o.
 +
 +This could be accomplished by hand by executing the following
 +<code>
 +g++ -c greeting.cpp
 +g++ -c stringTools.cpp
 +g++ -o hello hello.cpp stringTools.o greeting.o
 +</code>
 +
 +Of course, if you have command line flags, this becomes much more complex.  In addition, you need to remember to recompile ALL of the proper files when any of the files change, this includes the header files.  Using make simplifies this process.
 +
 +Using the above //Makefile// the code can be built with one command 
 +
 +<code> 
 +$ make
 +g++ -g -O3 -Wpedantic -Wall -Wextra -Wmisleading-indentation -Wunused -Wuninitialized -Wshadow -Wconversion -std=c++14   -c -o greeting.o greeting.cpp
 +g++ -g -O3 -Wpedantic -Wall -Wextra -Wmisleading-indentation -Wunused -Wuninitialized -Wshadow -Wconversion -std=c++14   -c -o stringTools.o stringTools.cpp
 +g++ -g -O3 -Wpedantic -Wall -Wextra -Wmisleading-indentation -Wunused -Wuninitialized -Wshadow -Wconversion -std=c++14    hello.cpp greeting.o stringTools.o   -o hello
 +$ ls
 +Makefile      greeting.h  hello*     stringTools.cpp  stringTools.o
 +greeting.cpp  greeting.o  hello.cpp  stringTools.h
 +</code>
 +
 +Note that all components are compiled and the final executable is produced.  If any of the component files change, make will recompile only the parts necessary to rebuild the entire project.  For example, if greeting.cpp were change, that file, along with hello.cpp would need to be recomipled, but stringTools.o would not need to be rebuilt.
 +
 +<code>
 +$ touch greeting.cpp
 +$ make
 +g++ -g -O3 -Wpedantic -Wall -Wextra -Wmisleading-indentation -Wunused -Wuninitialized -Wshadow -Wconversion -std=c++14   -c -o greeting.o greeting.cpp
 +g++ -g -O3 -Wpedantic -Wall -Wextra -Wmisleading-indentation -Wunused -Wuninitialized -Wshadow -Wconversion -std=c++14    hello.cpp greeting.o stringTools.o   -o hello
 +</code>
 +
 +==== The Makefile ====
 +
 +In order to build this project using make, you need to inform make of the dependencies built into the project.  In this case, to build hello, we need to have both //greeting.o// and //stringTools.o// because the code in hello calls code in both of these files.  The following line in the makefile performs this task
 +
 +<code make>
 +hello:  greeting.o stringTools.o
 +</code>
 +
 +You do not need to tell make that //hello// depends on //hello.cpp//, that is built into the system.
 +
 +You also do not need to tell make that //hello// depends on //greeting.h// or //stringTools.h// This is accomplished by the next set of instructions in the makefile.
 +
 +<code make>
 +stringTools.o: stringTools.h
 +</code> 
 +
 +This line tells make that //stringTools.o// depends on //stringTools.h// Make does not have default rules for header files, so this line is necessary.  The result of this line is if stringTools.h changes, stringTools.o will need to be rebuilt.   If this happens, make is able to deduce that //hello// will need to be rebuilt as well.  This is good since //hello.cpp// includes //stringTools.h//.
 +
 +<code make>
 +greeting.o: greeting.h stringTools.h
 +</code>
 +
 +This line tells make that //greeting.o// depends on both //greeting.h// and //stringTools.h// Again //greeting.o// also depends on //greeting.cpp//, but make has this rule built in.  
  
guides/software/make/start.1595258432.txt.gz · Last modified: 2022/08/02 11:59 (external edit)