*.ads file not found when compiling Ada with a makefile - makefile

I am trying to compile an ada program but I am having the following error: test.adb:4:06: file "motormachinestate.ads" not found. Of course, the problem is that the Makefile is wrong. I have been searching how to fix it but I have been unable.
The program files are the following:
MotorMachineState.ads: This file contains a package declaration. It contains procedures etc. that are used by the program-
MotorMachineState.adb: This file contains the above one's implementation. it is a package body.
test.adb: This is the program's entry point. It uses the MotorMachineState to perform some operations.
Makefile: The makefile I am using to compile.
Below there is a description of the mentioned files:
MotorMachineState.ads
package MotorMachineState is
protected Motor is
[...]
end Motor;
end MotorMachineState;
MotorMachineState.adb
with Ada.Text_IO;
with Ada.Real_Time;
with Ada.Integer_Text_IO;
use Ada.Text_IO;
use Ada.Real_Time;
use Ada.Integer_Text_IO;
package body MotorMachineState is
protected body Motor is
[...]
end Motor;
end MotorMachineState;
test.adb
with Ada.Text_IO;
with Ada.Real_Time;
with Ada.Integer_Text_IO;
with MotorMachineState;
use Ada.Text_IO;
use Ada.Real_Time;
use Ada.Integer_Text_IO;
use MotorMachineState;
procedure test is
begin
Put_Line("This is a test");
Motor.setPower(20);
[...]
end test;
Makefile
ADA::
gnatmake -c test.adb MotorMachineState.adb
gnatbind test.ali MotorMachineState.ali
gnatlink test.ali MotorMachineState.ali
clean::
rm *.o *.ali main

GNAT expects source file names to be all lower-case.
To build an Ada program (where all relevant source files are in the current directory) with GNAT, you simply run:
gnatmake main_source_file.adb
The gnatmake command knows all it need to know about dependencies of pure-Ada programs.

Files in Ada should be always with lower case. So the problem's solution is to rename the files MotorMachineState.ad* to motormachinestate.ad*.
In addition, the gnatbind and gnatlink should handle only one *.ali file, so the Makefile looks like this:
ADA::
gnatmake -c test.adb motormachinestate.adb
gnatbind test.ali
gnatlink test.ali
clean::
rm *.o *.ali test
EDIT
As #SimonWright says, actually there is no need to add the motormacinestate.adb
to the gnatmake command. So, the Makefile could be like this:
ADA::
gnatmake -c test.adb
gnatbind test.ali
gnatlink test.ali
clean::
rm *.o *.ali test

Related

How to build a programs that's output will be used in a Make variable name

I want to create a Makefile which will build a program which when run's output will be used as a value for a variable in the same Makefile.
Consider the program:
print_name.c:
#include <stdio.h>
int main() {
printf("foo\n");
return 0;
}
I'd like to use the standard output of this program to then determine a directory name to be stored in a variable used in the makefile and used for other rules, so far I've tried:
all: $(MY_DIRECTORY_NAME)/my_program
print_name: print_name.c | print_name
gcc $^ -o $#
MY_DIRECTORY_NAME:=$(shell ./print_name)
$(MY_DIRECTORY_NAME)/my_program: my_program.c
mkdir -p $(MY_DIRECTORY_NAME)
gcc $^ -o $#
However when I run:
make all
I get:
make: *** No rule to make target '/my_program', needed by 'all'. Stop
Whereas I'd like:
mkdir -p foo
gcc my_program.c -o foo/my_program
So basically, I want to compile print_name before the assignment to MY_DIRECTORY_NAME, and then that variable in then used in the following rules. Is this possible, and if not are there any workarounds for this?
The basic problem is that you need to build (and run) print_name before you can parse the rules that use it -- but all rules are read and parsed before anything is built. So you need to run make twice -- first to build print_name and second to build everything that depends on it. Something like
all: print_name
$(MAKE) `./print_name`/my_program
should do the trick

Bash : use variable in variable (nested loop)

I have a makefile and I want to compile each of my vhdl files in the correct library. And there is my code :
$(DEBUG)for core_lib in $(CORE_LIB_LIST); \
do for core_lib_src_vhd in $($$core_lib.VHDL_SRC_FILES_LIST); \
do $(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work $$core_lib $(BLOCK_PATH)/cores/$$core_lib_src_vhd; \
done; \
done;
But $($$core_lib.VHDL_SRC_FILES_LIST) is unrecognized.
I guess that in $($$core_lib.VHDL_SRC_FILES_LIST) core_lib is a shell variable and you want make to expand it first, and then expand the make variable which name is ${core_lib}.VHDL_SRC_FILES_LIST. This is not how make works. You cannot expect make to expand shell variables.
Instead you should rely on make variables only. Assuming:
make variable CORE_LIB_LIST is the list of libraries,
for each library LIB there is a make variable LIB.VHDL_SRC_FILES_LIST listing the source files,
the source files are in $(BLOCK_PATH)/cores/,
you could try this:
.PHONY: compile-all-libs
# $(1): library
define COMPLIB_rule
.PHONY: compile-$(1)
compile-$(1):
$$(DEBUG)$$(COMPILER_VHDL) $$(CC_VHDL_OPTIONS) $$(COVER_OPTIONS) -work $(1) $$(addprefix $$(BLOCK_PATH)/cores/,$$($(1).VHDL_SRC_FILES_LIST))
compile-all-libs: compile-$(1)
endef
$(foreach LIB,$(CORE_LIB_LIST),$(eval $(call COMPLIB_rule,$(LIB))))
Explanation: the define COMPLIB_rule ... endef is just another way to define a make variable named COMPLIB_rule. The $(foreach ... construct must be put flat in the Makefile (not in a recipe). It iterates over the words in the definition of make variable CORE_LIB_LIST. For each word LIB, it replaces $(1) by LIB in the definition of COMPLIB_rule (it also replaces every $$ by a single $) and it instantiates the result as a regular make rule. If the make variable CORE_LIB_LIST evaluates as a b, for instance, the result will be the same as:
.PHONY: compile-a
compile-a:
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work a $(addprefix $(BLOCK_PATH)/cores/,$(a.VHDL_SRC_FILES_LIST))
compile-all-libs: compile-a
.PHONY: compile-b
compile-b:
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work b $(addprefix $(BLOCK_PATH)/cores/,$(b.VHDL_SRC_FILES_LIST))
compile-all-libs: compile-b
So, if you type make compile-all-libs, make will try to build compile-a and compile-b, the two pre-requisites of compile-all-libs. In order to build compile-a it will execute the recipe:
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work a $(addprefix $(BLOCK_PATH)/cores/,$(a.VHDL_SRC_FILES_LIST))
which will compile in library a all source files listed in make variable a.VHDL_SRC_FILES_LIST and found in directory $(BLOCK_PATH)/cores. Same with compile-b.
But of course, it would be much better if you were recompiling only what's needed (that is, source files that changed since the last time they were compiled). This can be done with empty tag files that keep track of the last time a source file was compiled:
.PHONY: compile-all-libs
# $(1): library
# $(2): source file basename
define COMPLIB_rule
$$(BLOCK_PATH)/cores/$(1).$(2).tag: $$(BLOCK_PATH)/cores/$(2)
$$(DEBUG)$$(COMPILER_VHDL) $$(CC_VHDL_OPTIONS) $$(COVER_OPTIONS) -work $(1) $$< && \
touch $$#
compile-all-libs: $$(BLOCK_PATH)/cores/$(1).$(2).tag
endef
$(foreach LIB,$(CORE_LIB_LIST),$(foreach FILE,$($(LIB).VHDL_SRC_FILES_LIST),$(eval $(call COMPLIB_rule,$(LIB),$(FILE)))))
clean:
$(DEBUG)rm -f $(BLOCK_PATH)/cores/*.tag
Explanation: there, the foreach-foreach-eval-call iterates over library/source file pairs. For each LIB-FILE pair, it replaces $(1) by LIB and $(2) by FILE in the definition of COMPLIB_rule (it also replaces every $$ by a single $) and it instantiates the result as a regular make rule. All this declares all LIB.FILE.tag files as pre-requisites of target compile-all-libs and declares the rule to build the tag by compiling FILE in LIB and touching the tag file. This is just like if, for each source FILE of library LIB, you added this to your Makefile:
$(BLOCK_PATH)/cores/LIB.FILE.tag: $(BLOCK_PATH)/cores/FILE
$(DEBUG)$(COMPILER_VHDL) $(CC_VHDL_OPTIONS) $(COVER_OPTIONS) -work LIB $< && \
touch $#
compile-all-libs: $(BLOCK_PATH)/cores/LIB.FILE.tag
Just type make compile-all-libs and see: make will build all tag files, that is, compile each source file in its own library and touch the tag file. As the VHDL source file is a pre-requisite of the tag file, it is only if the VHDL source file is more recent than the tag file that the recipe will be executed. This is the same as the .o / .c dependency for C programs. The only difference is that we do not use the compilation result itself (.o) because we do not really know what it is with Modelsim. Instead, we create a tag file, just for this purpose. Side effect: it would be exactly the same with a different VHDL compiler/simulator.
This would even give you the possibility to declare dependencies between your source files: if $(BLOCK_PATH)/cores/foo.vhd must be compiled in library FOO_LIB before $(BLOCK_PATH)/cores/bar.vhd can be compiled in library BAR_LIB, you could add:
$(BLOCK_PATH)/cores/BAR_LIB.bar.vhd.tag: $(BLOCK_PATH)/cores/FOO_LIB.foo.vhd.tag
to your Makefile. And there are also many possible improvements like, for instance, per-library goals...

How to force compiler to compile same source file every time used in different shared libraries in cmake? [duplicate]

I have a project directory structure of:
Root
Source
Common
MyFolder
++ My 3 source files and header
When I am building my project it generates 3 to 4 shared libraries. Lib1 compiled using c++98 and others using c++11. Flags are added in CmakeList.txt which is at root.
I need my 3 source files to be compiled for Lib1 and for other Libs as as well. but here what happens is compiler is first compiling my source file for lib using c++11 and then it is trying to use same .o file for Lib1 as well. So for .o file which is generated using c++11 is throwing exception when same is used for c++98 compiled library.
So how do write this in CmakeList.txt such that compiler rather than trying to use same .o file will compile source file again for Lib1(c++98 compiled library)
Is there any flag I can specify so that it won't take precompiled .o file and will compile it again ?
Here flags are not being overridden for different shared libraries but actually same object file by make file is being used for different flags
This is sort of counter to how makefiles and cmake usually work.
Most users consider it really important that make performs an incremental build.
The usual way with makefiles is to do make clean which is supposed to remove any binaries and object files that were created.
However, sometimes I write cmake scripts that use globbing over the source directory to assemble the project. (That means, it says "just grab all *.cpp files in the /src folder and make an executable from them".) A makefile cannot check what files in a directory, so the make build will be broken after I add a new file, and make clean won't fix it -- the whole makefile will need to be regenerated by cmake.
Usually what I do is, I write a simple bash script, named rebuild.sh or something,
#!/bin/bash
rm -rf build
mkdir build
cd build
cmake ..
make -j3
./tests
And I put that in the root of my repository, and add /build to my .gitignore. I call that when I want to do a full rebuild -- it nukes the build directory, so its foolproof. When I want an incremental rebuild, I just type make again in the /build directory.
The rebuild.sh script can also serve a double purpose if you use travis-ci for continuous integration.
Most build system assume the compiled objects remain the same within the same pass. To avoid shooting your foot I would suggest telling the build system they were actually different objects, while still compiled from same source files.
I'm not familiar with cmake but this is how you do with make:
For example you have a a.cpp which you want to compile 2 times for different compiler options:
#include <stdio.h>
int main(int argc, char* argv[]) {
printf ("Hello %d\n", TOKEN);
return 0;
}
And the Makefile would looks like:
SRC := $(wildcard *.cpp)
OBJ_1 := $(patsubst %.cpp,%_1.o,$(SRC))
OBJ_2 := $(patsubst %.cpp,%_2.o,$(SRC))
all: pass1 pass2
pass1: $(OBJ_1)
gcc -o $# $(OBJ_1) -lstdc++
pass2: $(OBJ_2)
gcc -o $# $(OBJ_2) -lstdc++
%_1.o: %.cpp
gcc -DTOKEN=1 -c $< -o $#
%_2.o: %.cpp
gcc -DTOKEN=2 -c $< -o $#
clean:
rm -f $(OBJ_1) $(OBJ_2)
What I do here is generate two different list of object from the same source files, which you can even do the same for dependency(-MMD -MP flags).

make command with math library

I need to just run the make command for makefile. But when I run this make command I get the error that "undefined reference to `log'" because I know this fact that it doesn't include math Library and we have to include at runtime. I know that if I run this using gcc comiler then i can write -lm at the end, it will include math library. My problem is I need to run it using make command that is- make lu.
In this if I write make lu -lm it is not linking math library. Please help
Using this link How to use LDFLAGS in makefile
I updated my make file but still same problem persists. Please Help.
SHELL=/bin/sh
BENCHMARK=ep
BENCHMARKU=EP
include ../config/make.def
OBJS = ep.o ${COMMON}/c_print_results.o ${COMMON}/c_${RAND}.o \
${COMMON}/c_timers.o ${COMMON}/c_wtime.o
include ../sys/make.common
LDLIBS=-lm
LDFLAGS=-lm
${PROGRAM}: config ${OBJS}
${CLINK} ${CLINKFLAGS} -o ${PROGRAM} $(LDFLAGS) $(LOADLIBES) ${OBJS} ${C_LIB}
ep.o: ep.c npbparams.h
${CCOMPILE} ep.c
clean:
- rm -f *.o *~
- rm -f npbparams.h core
Why does your makefile refer to all sorts of variables that don't exist, like LOADLIBES, C_LIB? Why do you set variables that you never use, like LDLIBS?
The reason it doesn't work is that you're putting the library reference in the LDFLAGS variable, which comes early in your link command before any of your object files. So when the linker goes to link in the math library it thinks that it's not needed because nothing is using it yet.
You have to put libraries at the end of the link line.
Since you already have the C_LIB variable at the end which you are not using, if you add:
C_LIB = -lm
then it should work.

how to gcc compile with #define in multiple files

I have a project with multiple files.. I want to compile it using gcc from command line.
the directory looks like this
lib/
Comp/ contains .cpp files
Decomp/ contains .cpp files
Globals.cpp
include/
Comp/ contains .h files
Decomp/ contains .h files
Globals.h
some of these .h files are not paired with .cpp files
to compile this i use something like this :
g++ lib/Comp/* lib/Decomp/* lib/Globals.cpp -std=c++0x -o TEST
the problem is,I have to add some #defines for each .h file and i have to do it through command line. how to do this ??
also if i had to compile each file on its own and then link them. what would be the appropriate order for doing this ?
The dirtiest ugliest way is that you want to use something like:
g++ -Iinclude lib/Comp/*.cpp lib/Decomp/*.cpp lib/Globals.cpp -o test
Your .cpp files should #include <Comp/foo.h> or whatever
The correct way to manage this is to use a makefile to build each object file and then link them together:
Makefile
Create a a file called Makefile and put the following in it:
CXX=g++
CPPFLAGS=-Iinclude -DFOO -DBAR=1 -DSOME_STRING=\"My Name\"
CXXFLAGS=-O2 -g
SOURCES=lib/Comp/file1.cpp \
lib/Comp/file2.cpp \
lib/Comp/file3.cpp \
lib/Decomp/file1.cpp \
lib/Decomp/file2.cpp \
...
OBJ=$(SOURCES:%.cpp=%.o)
default: test
test: $(OBJ)
<tab> $(CXX) -o $# $(OBJ)
%.o: %.cpp
<tab> $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
NOTES
Replace file1.cpp etc. with the actual filenames in your project. DO NOT include headers in SOURCES only your .cpp or .cc files
If you are using sub-paths like #include <Comp/foo.h> or #include "Comp/foo.h" in your source files then you only need to use -Iinclude in CPPFLAGS but if you are doing something like "foo.h" and foo.h is actually in include/Comp/ then add -Iinclude/Comp and -Iinclude/Decomp to the CPPFLAGS
Where it says <tab> make sure you use the TAB key to insert a tab (don't type the word '')
Before using this Makefile blindly . Know that it will NOT work as is you have to correct the entries. It is offered as a starting point... Read up on writing Makefiles ... http://frank.mtsu.edu/~csdept/FacilitiesAndResources/make.htm has a good introduction
Defines can be provided on the compiler command line using -DVAR=VALUE (on Windows, presumably /DVAR=VALUE). Note that you can not provide different defines for different headers as in:
compiler -DX=one first.h -DX=two second.h third.cc -o third.o
In such a case, my compiler spews warning and uses the last value of X for all source code.
Anyway, in general you should not list header files on the compilation line; prefer to include them from the implementation files (.cc/.cpp or whatever) that need them.
Be careful too - if you're changing defines to modify class definitions, inline function implementation etc. you can end up with technically and/or practically undefined behaviour.
In terms of how best to decide which objects to create and link - you probably want one object per .cc/.cpp file. You can link those objects then specify them on the command line when compiling the file containing main().

Resources