I am trying to compile bt from NPB. I am getting the attached errorCompilation Error . I have also attached the make file I am using.
What am I doing wrong in this case?
MakeFile:
SHELL=/bin/sh
BENCHMARK=bt
BENCHMARKU=BT
include ../config/make.def
OBJS = bt.o \
${COMMON}/c_print_results.o ${COMMON}/c_timers.o ${COMMON}/c_wtime.o
include ../sys/make.common
# npbparams.h is included by header.h
# The following rule should do the trick but many make programs (not gmake)
# will do the wrong thing and rebuild the world every time (because the
# mod time on header.h is not changed. One solution would be to
# touch header.h but this might cause confusion if someone has
# accidentally deleted it. Instead, make the dependency on npbparams.h
# explicit in all the lines below (even though dependence is indirect).
# header.h: npbparams.h
${PROGRAM}: config ${OBJS}
${CLINK} ${CLINKFLAGS} -o ${PROGRAM} ${OBJS} ${C_LIB}
.c.o:
${CCOMPILE} $<
bt.o: bt.c header.h npbparams.h
clean:
- rm -f *.o *~ mputil*
- rm -f npbparams.h core
Seems missing ../sys/setparams
Which should be an executable file, and takes bt A as input arguments.
It might be a depended tool should be built at first. I've tried a search on github, and could find some projects containing, ../sys/setparams.c, maybe, these are what you need.
Hope it helps you.
Related
I have a c++ makefile project. It works great for non-parallel building. It works 99% for parallel building... the only problem I have is that I can't get my final executable link-line to run last (it must be the last thing that happens).
I have some constraints: I don't want to have any PHONY dependencies on my link line because this causes it to re-link every time. I.e. once my target is built, when I re-build it should not be re-linked.
Here is (slightly contrived) minimal example. Please don't try to pick holes in it, its really here just to show the problem, its not real, but the problem I am showing is. You should be able to just run this and see the same issue that I am.
# Set the default goal to build.
.DEFAULT_GOAL = build
#pretend subdirs (these don't really exist but it does not matter so long as they always try to be built)
MAKE_SUB_DIRS = 1 2 3
#pretend shared objects that are created by the pretend makefile sub directories (above)
OUTPUTS = out1.so out2.so out3.so
# Top level build goal - depends on all of the subdir makes and the target.out
.PHONY: build
build: $(MAKE_SUB_DIRS) target.out
#echo build finished
# Takes 1 second to build each of these pretend sub make directories. PHONY so always runs
.PHONY: $(MAKE_SUB_DIRS)
$(MAKE_SUB_DIRS):
#if [ ! -f out$#.so ] ; then echo making $#... ; sleep 1 ; echo a > out$#.so ; fi
# The main target, pretending that it needs out1,2 and 3 to link
# Should only run when target.out does not exist
# No PHONY deps allowed here
target.out:
#echo linking $#...
#ls $(OUTPUTS) > /dev/null
#cat $(OUTPUTS) > target.out
# Clean for convinience
clean:
#rm -rf *.so target.out
Now, I don't really care about make working, what I want is make -j to work. Here is me trying to run it:
admin#osboxes:~/sandbox$ make clean
admin#osboxes:~/sandbox$
admin#osboxes:~/sandbox$ make -j - 1st attempt
making 1...
making 2...
linking target.out...
making 3...
ls: cannot access 'out1.so': No such file or directory
ls: cannot access 'out2.so': No such file or directory
ls: cannot access 'out3.so': No such file or directory
makefile:24: recipe for target 'target.out' failed
make: *** [target.out] Error 2
make: *** Waiting for unfinished jobs....
admin#osboxes:~/sandbox$
admin#osboxes:~/sandbox$ make -j - 2nd attempt
linking target.out...
build finished
admin#osboxes:~/sandbox$
admin#osboxes:~/sandbox$ make -j - 3rd attempt
build finished
admin#osboxes:~/sandbox$
So I highlighted my three attempts to run it.
Attempt 1: you can see all 4 dependencies of build are started at the same time (approx). Since each of the makeing x... take 1 second and the linking is nearly instant we see my error. However all the three "libraries" are build correctly.
Attempt 2: The libraries only get created if they don't already exists (that's bash code - pretending to do what a makefile might have done). In this case they are already created. So the Linking passes now since it just requires the libraries to exist.
Attempt 3: nothing happens because nothing needs to :)
So you can see all the steps are there, its simply a matter of ordering them. I would like the the make sub dirs 1, 2, 3 to build in any order in parallel and then only once they are all completed I want target.out to run (i.e. the linker).
I don't want to call it like this though: $(MAKE) target.out because in my real makefile I have lots of variables all setup...
I have tried looking at (from othe answers) .NOT_PARALLEL and using the dep order operator | (pipe), and I have tried order a load of rules to get target.out to be last.... but the -j option just ploughs through all of these and ruins my ordering :( ... there must be some simple way to do this?
EDIT: add an example of ways to pass variables to sub-makes. Optimized a bit by adding $(SUBDIRS) to the prerequisites of build instead of making them in its recipe.
I am not sure I fully understand your organization but one solution to deal with sub-directories is as follows. I assume, a bit like in your example, that building sub-directory foo produces foo.o in the top directory. I assume also that your top Makefile defines variables (VAR1, VAR2...) that you want to pass to the sub-makes when building your sub-directories.
VAR1 := some-value
VAR2 := some-other-value
...
SUBDIRS := foo bar baz
SUBOBJS := $(patsubst %,%.o,$(SUBDIRS))
.PHONY: build clean $(SUBDIRS)
build: $(SUBDIRS)
$(MAKE) top
$(SUBDIRS):
$(MAKE) -C $# VAR1=$(VAR1) VAR2=$(VAR2) ...
top: top.o $(SUBOBJS)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
top.o: top.cc
$(CXX) $(CXXFLAGS) -c $< -o $#
clean:
rm -f top top.o $(SUBOBJS)
for d in $(SUBDIRS); do $(MAKE) -C $$d clean; done
This is parallel safe and guarantees that the link will take place only after all sub-builds complete. Note that you can also export the variables you want to pass to sub-makes, instead of passing them on the command line:
VAR1 := some-value
VAR2 := some-other-value
...
export VAR1 VAR2 ...
Normally you would just add the lib files as prerequisites of target.out:
target.out: $(OUTPUTS)
#echo linking $#...
The thing is, this will relink target.out if any of the output lib files are newer. Normally this is what you want (if the lib has changed, you need to relink target), but you specifically say you do not.
GNU make provides an extension called "order only prerequisites", which you put after a |:
target.out: | $(OUTPUTS)
#echo linking $#...
now, target.out will only be relinked if it does not exist, but in that case, it will still wait until after $(OUTPUTS) have finished being built
If your $(OUTPUT) files are build by subsirectory makes, you may find you need a rule like:
.PHONY: $(OUTPUT)
$(OUTPUT):
$(MAKE) -C $$(dirname $#) $#
to invoke the recursive make, unless you have other rules that will invoke make in the subdirectories
Ok, so I have found "a" solution... but it goes a little bit against what I wanted and is therefore ugly (but not that that ugly):
The only way I can fathom to ensure order in parallel build (again from other answers I read) is like this:
rule: un ordered deps
rule:
#echo this will happen last
Here the three deps will be made (or maked?) in any order and then finally the echo line will be run.
However the thing that I want to do is a rule and specifically so, such that it checks if anything has changed or if the file does not exist - and then, and only then, runs the rule.
The only way I know of to run a rule from within the bode of another rule is to recursively call make on it. However I get the following issues just calling make recursively on the same makefile:
Variables are not passed in by default
Many of the same rules will be re-defined (not allowed or wanted)
So I came up with this:
makefile:
# Set the default goal to build.
.DEFAULT_GOAL = build
#pretend subdirs (these don't really exist but it does not matter so long as they always try to be built)
MAKE_SUB_DIRS = 1 2 3
#pretend shared objects that are created by the pretend makefile sub directories (above)
OUTPUTS = out1.so out2.so out3.so
# Top level build goal - depends on all of the subdir makes and the target.out
export OUTPUTS
.PHONY: build
build: $(MAKE_SUB_DIRS)
#$(MAKE) -f link.mk target.out --no-print-directory
#echo build finished
# Takes 1 second to build each of these pretend sub make directories. PHONY so always runs
.PHONY: $(MAKE_SUB_DIRS)
$(MAKE_SUB_DIRS):
#if [ ! -f out$#.so ] ; then echo making $#... ; sleep 1 ; echo a > out$#.so ; fi
# Clean for convinience
clean:
#rm -rf *.so target.out
link.mk:
# The main target, pretending that it needs out1,2 and 3 to link
# Should only run when target.out does not exist
# No PHONY deps allowed here
target.out:
#echo linking $#...
#ls $(OUTPUTS) > /dev/null
#cat $(OUTPUTS) > target.out
So here I put the linker rule into a separate makefile called link.mk, this avoids recursive make calling on the same file (and therefore with re-defined rules). But I have to export all the variables I need to pass through... which is ugly and adds a bit of a maintenance overhead if those variables change.
... but... it works :)
I will not mark this any time soon, because I am hopeful some genius will point out a neater/better way to do this...
I'm using GNU makefiles to build a C project. I want to keep all build artifacts on an isolated build tree in order to minimize clutter. The project looks like this:
$prefix/
include/$tree/program.h
source/$tree/program.c
build/
objects/$tree/program.o
dependencies/$tree/program.d
Where $prefix represents the directory of the project and $tree represents an arbitrary folder structure.
I wanted to match source files in the source/ directory to their object and dependency file counterparts in the build/ tree. So, I wrote the following rules:
# Remove the built-in rules
%.o : %.c
$(objects_directory)/%.o : $(source_directory)/%.c $(dependencies_directory)/%.d
$(compiler_command_line) $(compiler_option_output) $# $<
$(build_directory)/$(target) : $(objects)
$(compiler_command_line) $(compiler_option_output) $# $^
Make correctly figures out the compilation target and the object files needed to build it. However, make stops at this point with the error:
No rule to make target 'build/objects/project/program.o', needed by 'build/program.dll'.
So why is this happening, and how do I fix it?
I investigated the problem by running make --print-data-base, the output of which included:
# Not a target:
build/objects/project/program.o:
# Implicit rule search has been done.
# File does not exist.
# File has not been updated.
Which suggests that the prerequisite is not matching the implicit rule as intended. However, I verified that it does match when I tried to work my way backwards by writing:
object := build/objects/project/program.o
$(object:$(objects_directory)/%.o=$(source_directory)/%.c)
$(object:$(objects_directory)/%.o=%)
These lines result in source/project/program.c and project/program, which means the stem is being correctly computed.
I have studied the GNU make documentation and I don't remember reading anything that suggests that this kind of pattern matching can't happen in implicit rule definitions.
Here are the variable definitions:
include_directory := include
source_directory := source
build_directory := build
objects_directory := $(build_directory)/objects
dependencies_directory := $(build_directory)/dependencies
sources := $(wildcard $(source_directory)/**/*.c)
objects := $(sources:$(source_directory)/%.c=$(objects_directory)/%.o)
# Take the name of the project's directory
target := $(notdir $(CURDIR)).dll
compiler_dependency_file = $(patsubst $(source_directory)/%.c,$(dependencies_directory)/%.d,$<)
compiler_options = -I $(include_directory) -MMD -MF $(compiler_dependency_file)
CC = gcc
compiler_command_line = $(CC) $(compiler_options) $(CFLAGS)
compiler_option_output = -o
It turns out it wasn't the pattern matching. The root of the problem was in the dependency prerequisite of the implicit rule.
The dependency file isn't supposed to be a prerequisite in the first place; it should be one of the targets that gets generated along with the object file.
As I read once more ยง 4.14 Generating Prerequisites Automatically of the manual, the answer jumped out at me:
The purpose of the sed command is to translate (for example):
main.o : main.c defs.h
into:
main.o main.d : main.c defs.h
While my build system makes no use of sed, the fact that main.d was on the left-hand side of the example rule felt strange. In my code, it was on the right-hand side.
When I put my rule in the left-hand side, it worked and the problem was solved. The erroneous recipe was essentially treating one of its byproducts as a prerequisite.
In my project all .cpp files are stored in
Classes/
Classes/Something/
Classes/Something/Else
...
I want to compile all .cpp file separetly to Bin/ directory, replacing / with _, so that:
Classes/First.cpp -> Bin/Classes_First.o
Classes/Foo/Bar.cpp -> Bin/Classes_Foo_Bar.o
Now I wanted to create rules for compiling:
Bin/%.o: $(subst _,/,%.cpp)
$(COMPILER)g++ $(COMPILE_FLAGS) -c -o $# $^
I tried:
make Bin/Classes_Test.o
But compilation failed.
So I created debugging pattern:
%.cpp:
#echo CPP: $#
Now it printed:
CPP: Classes_Test.cpp
Why?!
So I changed my pattern to:
Bin/%.o: $(subst _,/,Test1_Test2.cpp)
and I saw:
CPP: Test1/Test2.cpp
I'm a little bit confused why subst does not work if I use wildcard as source...
This is an evaluation order issue.
When make parse the makefile it evaluates the $(subst) call but the argument to $(subst) at that point is the literal string %.cpp which has nothing to substitute in it and so does not do anything.
At target evaluation/execution time the % in the target pattern and prereq pattern are filled out but the $(subst) has long-since gone away.
To do this you will need to manually (in one way or another) map the output files to the input files. You can do that and keep the %.o pattern rule target for the actual recipe to run though (so you just need to generate a bunch of Bin/Test1_Test2.o: Test1/Test2.cpp lines).
Alternatively, I believe you can might be able to use secondary expansion to do this:
.SECONDEXPANSION:
Bin/%.o: $$(subst _,/,%.cpp)
CXXSRC = $(shell find source -iname "*.cpp")
CXXSRCFN = $(notdir $(CXXSRC))
CXXOBJ = $(CXXSRCFN:%.s=output/obj/%.cpp.o)
OUTPUT = output/kernel.elf
.PHONY: builduserspace clean all
all: $(OUTPUT)
#$(QEMU) -vga std -serial file:"output/serialout.log" -m 20 -hda output/disk.img -rtc base=localtime
$(OUTPUT): $(CXXOBJ)
# Linking object files...
#$(LD) $(LDFLAGS) -o output/temp.elf output/obj/Start.s.o $(shell find output/obj -name "*.o" ! -name "Start.s.o") -Lgcc
# Performing objcopy...
#$(OBJCOPY) -O elf32-i386 output/temp.elf output/kernel.elf
%.cpp.o: %.cpp
#echo $(notdir $<)
#$(CXX) $(CXXFLAGS) -o $(notdir $#) $<
That's the makefile. Here's the situation, imagine this directory structure:
output
|
|-- obj
source
|
|-- file1.cpp
|-- file2.cpp
|-- subdirectory
|
|-- file3.cpp
Say I run make in the root folder (where output and source are). The target output is output/kernel.elf.
Essentially, I want all the files in the folder 'source' to be compiled into object files and placed into the folder output/obj.
I managed to get the variables about right; CXXSRC is simply the list of all source files to be compiled; CXXOBJ is the list of outputs.
However, make: * No rule to make target output/obj/file.cpp.o', needed byoutput/kernel.elf'. Stop.
After some trial and error, I managed to narrow down the issue: If I modify the target to this:
output/obj/%.cpp.o: source/subdirectory/%.cpp
It works fine (ie. it errors on the other files in my tree, because not all files are in subdirectory)
Obviously this would defeat the purpose of the % wildcard operator, so how do I fix this problem?
Thanks.
First SO post, take it easy on me (:
The short answer is, you can't. In a pattern rule the pattern (%) must be identical (string-wise) between the target and the prerequisite. It can't mean "something sort of, but not exactly, the same".
I think it's a bit unpleasant to compile source files from multiple different directories and put the output into a single directory. Every single time I've seen that done it's become a big problem (because people sometimes use the same source file name and then you have a mess).
If you really want to do it there's no choice but to declare multiple rules with the different source directories. There are ways to do this in the makefile without writing them all by hand, but they're somewhat more advanced.
This will probably be a bot of a waffly question but ill try my best.
I have a simple c++ program that i need to build testing for. I have 2 Classes i use besides the one i actually am using, these are called WebServer and BusinessLogicLayer.
To test my own code i have made my own versions of these classes that feed dummy data to my class to test it functionality.
I need to know a way of somehow, via a makefile for instance, how to tell the source code to use the test classes over the normally used classes. The test classes are in a different "tester" c++ file, and the tester c++ file also has its own header file.
Regards
Paul
P.S. This is probably a badly worded question, but i dont know any better way to put my question.
You can define abstract base classes that declare the public interfaces for your components, then wire the objects together at runtime (in main() or something else fairly high up in the food chain). In testing, you simply wire up different objects.
To build debug and release versions of a program with source code in directories ${SRC_DIR_1} and ${SRC_DIR_2}:
CXX := g++
CPPFLAGS = ...
CXXFLAGS = ...
SRC_DIR_1 := ...
SRC_DIR_2 := ...
ifeq (${debug},1)
BIN_DIR := ./obj_debug
CXXFLAGS += -g
else
BIN_DIR := ./obj_release
CXXFLAGS += -DNDEBUG
endif
# Make sure that the directory exists.
TEMP := ${shell test -d ${BIN_DIR} || mkdir ${BIN_DIR}}
# Tell make to search each directory
VPATH := ${SRC_DIR_1}:${SRC_DIR_2}
# You can modify this to use a suffix other than .cc
${BIN_DIR}/%.o : %.cc
${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $#
# Build the requested version of the program.
ifeq (${debug},1)
default: program_name_debug
else
default: program_name
endif
tidy::
#${RM} -r ./obj_*
In the Project Configuration dialog, specify the target name as "program_name, program_name_debug". (Replace program_name with the name of your program.)
To build the program, invoke "make debug=X" with X replaced by either 0 or 1.
Reference
Why does your tester code have a header file of its own? Your test code should have the same interface as the code it emulates, and using the same header file prevents a lot of headaches.
Anyway, this will work:
real_program: WebServer.o BusinessLogicLayer.o
test_program: tester.o
real_program test_program: MyClass.o OtherThings.o
$(LINK) $^ -o $#