OpenCL header file difficulty - opencl

So I am trying to set up a way to easily develop OpenCL programs which turned out to be the hardest part of learning this language so far. I include CL/cl.h in my source files but I keep getting compiler errors that the headers don't exist. When I change the include to only be cl.h it works but every program I have seen so far uses CL/cl.h so I am assuming it is some sort of macro to allow either file. Any ideas how I can get around this or possible fixes?
This is my makefile
PROJ=ocl_intro
CC=mingw32-g++
CFLAGS=-std=c99 -Wall
LIB=-lOpenCL
ifdef INTELOCLSDKROOT
INC_DIRS="$(INTELOCLSDKROOT)include\CL"
LIB_DIRS="$(INTELOCLSDKROOT)lib\x86
endif
$(PROJ): $(PROJ).cpp
$(CC) $(CFLAGS) -o $# $^ -I$(INC_DIRS) -L$(LIB_DIRS) $(LIB)
.PHONY: clean
clean:
rm $(PROJ).exe

Change:
INC_DIRS="$(INTELOCLSDKROOT)include\CL"
To:
INC_DIRS="$(INTELOCLSDKROOT)include"
You are looking for "CL/cl.h", obviously it's not going to find a folder called "CL" inside "include\CL", since you're already giving the "CL" folder as a search path. As is now, you're essentially asking the compiler to find "\include\CL\CL\cl.h", clearly the compiler will fail since this file does not exist.
You are meant to simply provide the path to the "include" folder - conventions will do the rest.

Related

Disable parallel execution in make

I have a building process that creates a header file. In the second stage, several source files are generated from that header file. Then these source files are built into a binary. If anyone is interested these sources are generated with gSOAP utilities (wsdl2h, soapcpp2).
I have made Makefile.am, etc to build these sources, but there are problems when I want to use parallel execution.
Makefile.am would look something like this in a very simplified form
## generate header file
service.h : service.wsdl
wsdl2h -o $# service.wsdl
## list of generated source files
generated_files = source1.cpp source2.cpp source3.cpp
## generate source files
$(generated_files) : service.h
soapcpp2 $^
## build binary
binary: $(generated_files)
gcc -o $# $^
The rules say that service.h will be generated if service.wsdl changes. If service.h changes, soapcpp2 will generate source?.cpp files with one command execution.
Everything works fine until I try to build in parallel (for instance make -j4). The problematic line is the last one which generates many soruce files. If running in parrallel all these files are generated many times, while other make processes already try to compile them.
I followed instructions to disable parallel https://www.gnu.org/software/make/manual/html_node/Parallel-Disable.html, but with no success. If I try
.NOTPARALLEL: $(generated_files)
or
.NOTPARALLEL: service.h
The parallel execution just does not work any more. I also tried with .WAIT, and got no rule to make target .WAIT.
First, the .WAIT special target was introduced in GNU make 4.4. Since you are getting a no rule to make target error for it, it's clear you're using an older version which doesn't support it. It's usually a good idea to include the version of whatever tool you're using when asking for help.
The best thing to do is not disable parallelism but instead tell make that a single invocation of the recipe will generate all the files. If you have GNU make 4.3, then you can use a "grouped target" rule, like this:
## generate source files
$(generated_files) &: service.h
soapcpp2 $^
the &: here tells make that instead of building each target with a different invocation of the recipe, which is the default, a single invocation of the recipe builds all the targets.
If you don't have GNU make 4.3 then you'll need to play a trick to get the same behavior, something like this:
## generate source files
.sentinel : service.h
soapcpp2 $^
#touch $#
$(generated_files) : .sentinel ;
## build binary
binary: $(generated_files)
gcc -o $# $^
This has all the generated files depend on a single file .sentinel (you can name it whatever you want), which is the one make knows is generated by the recipe that also creates all the other source files. This isn't perfect but it will work for simple situations.

How would I create a Makefile that remotely updates itself?

I have a makefile that I've changed up a bit here to look more generalized
.PHONY:
bash hash.sh
all: .PHONY lab tests.zip
lab: .PHONY lab.cpp
g++ -o lab lab.cpp -g -Wall -std=c++11
tests.zip:
curl -L -O https://url/tests.zip
unzip tests.zip
tests: .PHONY lab tests.zip
bash scripts/test.bash lab.cpp
clean:
rm -rf scripts tests bitset-tests.zip
I am a TA for an entry level computer science course at my university, and I've created a makefile here for my students to use to compile and test their code seamlessly.
One thing I want to do though is to have the makefile update itself every time the remote repository has a new version of it. I know I could just have them update the file themselves, but my job is to make the students focus less on setting things up and more on just coding for now, since it's entry level. So for the purposes of this, I'm sticking with the idea I have.
Currently, I'm achieving this with a script hash.sh which fetches a hash of the makefile from the repo, and compares it to a hash of the makefile in the student's directory. If the hashes don't match, then the updated makefile is fetched and replaces the old one. This is done in the .PHONY recipe. I should also mention that I don't want to add a recipe that updates it like make update, because again I want the process to be seamless. You'd be surprised how many students wouldn't utilize that feature, so I want to build it into the ones they will use for sure.
Is there a better method for this, or am I doing something wrong with this one?
Thomas has the right idea, but you can't use .PHONY here because it would means the makefile is ALWAYS out of date; make knows this so it doesn't re-exec itself if its included makefile is marked .PHONY.
You need to create a way for make to know if the makefile was changed since the last time it was run locally. I recommend you do it like this:
<normal makefile here>
Makefile: FORCE
curl https://.../Makefile -o Makefile.tmp
cmp -s Makefile Makefile.tmp && rm -f Makefile.tmp || mv -f Makefile.tmp Makefile
FORCE:
What does this do? First it uses a FORCE target which is an old-school way to emulate a .PHONY target, which is always out of date, without actually using .PHONY (which as I mentioned above, is handled specially by GNU make in this situation).
Second it retrieves the Makefile but only updates the local makefile if it has changed. If it hasn't changed, it doesn't update the local makefile and so make won't re-exec itself.
The whole stuff with fetching a hash sounds overly complicated. If you're going to do a fetch anyway, why not unconditionally fetch the entire makefile? It saves a network round trip, which is probably the limiting factor; the actual data is probably just a few kB anyway.
If you're using curl, notice the --time-cond option, for example:
curl https://... --time-cond Makefile -o Makefile
This will only fetch and update the Makefile if it's newer than the mtime of the current file. It works by sending an If-Modified-Since HTTP header, so you'll need some cooperation from the server for this to work reliably.
If using GNU make, you can use another neat trick: Remake the makefile itself. If you have a rule whose target is Makefile, it will be executed before anything else happens, and make will re-read the updated Makefile before proceeding:
.PHONY: Makefile
Makefile:
curl https://... --time-cond Makefile -o Makefile
Note that this will lead to infinite loops if for whatever reason the --time-cond leads to an unconditional update, so it wouldn't hurt to guard against that:
.PHONY: Makefile
Makefile:
[[ ! -v MAKE_RESTARTS ]] && \
curl https://... --time-cond Makefile -o Makefile

automake/gnu make dealing with directories in patterned rules

When I create a patterned rule, or some other custom rule, I need to be able to deal with the target directory not existing. This is for when the project is being built in a directory other than the source directory itself.
For example:
%.out: %.in
gen_file.sh $< > $#
The problem is when somebody specifies a path in the dependency:
some_target: some/path/sample.out
This fails because the some/path directory doesn't exist.
Is there a standard way of getting this directory to be created?
NOTE: I'm trying to use mkdir now, but having issues with getting the directory name as opposed to the filename. Probably just an escaping issue. Update: Got this to work with #mkdir -p $(shell dirname $#) This isn't likely portable.
The way automake does this is by making anything that could depend on a non-existent directory depend on a target some/dir/.dirstamp. The following pattern rule should cover that:
%/.dirstamp:
mkdir -p $(#D)
touch $#
Note also the use of $(#D) to get the directory part of $#. That means you don't have to use $(shell dirname $#) (or the GNU Make built-in $(dir $#)). See the GNU Make manual for more.

Out of tree builds with makefiles and static pattern rules

I'm working on some bare-metal embedded code that runs on ARM, and thus has to deal with the whole ARM vs. THUMB mode distinction. The current build system uses static pattern rules to determine whether to compile files in ARM or THUMB mode.
$(ACOBJS) : %.o : %.c
#echo
$(CC) -c $(CFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $#
$(TCOBJS) : %.o : %.c
#echo
$(CC) -c $(CFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $#
Where ACOBJS is a list of output objects that should be in ARM mode and the same for TCOBJS and Thumb mode. These lists are created from the list of sources in the usual manner of
ACOBJS = $(ACSRC:.c=.o)
TCOBJS = $(TCSRC:.c=.o)
Currently this results in the object files from the build being strewn about the source tree, which I don't particularly desire. I've been trying to set this up for out of tree builds but haven't been able to get this to work. I don't necessarily need to get full out of tree builds working, but I would like to at least be able to use an output directory under which all the intermediate files end up going. What is the best strategy to achieve this under these constraints?
One option I'm considering is using either automake or the whole autotools toolchain to build a makefile. This would seem to support creating the type of makefile I want, but seems like overkill. It also seems like there would be an inherent impedance mismatch between autotools, which is designed for portable builds, and bare-metal embedded systems, where things like host tuple are dictated by the target micro.
This is a bit old but I was just trying to do the same thing this was the first google hit. I thought it was worth sharing another approach since neither answer is convenient if you're not using autotools and want to be able to build in any directory with a single command and later just blow away that directory.
Here's an example of a Makefile that refers to files relative to the directory containing the Makefile.
MAKEFILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
MFD := $(MAKEFILE_DIR)
CXX=g++
CXXFLAGS=-std=c++14 -Wall -Wextra -pedantic -c
test: test.o adjacency_pointers_graph.o
$(CXX) $^ -o $#
%.o: $(MFD)/%.cpp $(MFD)/adjacency_pointers_graph.h
$(CXX) $(CXXFLAGS) $< -o $#
Then to do an sort of source build:
mkdir build
cd build
make -f ../Makefile
Considering/assuming you don't care about portability and are using GNU make, you can use the VPATH feature:
Create the directory where you want to do your build.
Create a 'Makefile' in that directory with (approximately) the following contents:
path_to_source = ..
VPATH = $(path_to_source)
include $(path_to_source)/Makefile
Change the path_to_source variable to point to the root of your source tree.
Additionally you probably need to tweak your original Makefile to make sure that it supports the out of source build. For example, you can't reference to prerequisites from your build rules and instead must use $^ and $<. (See GNU make - Writing Recipes with Directory Search) You might also need to modify the vpath-makefile. For example: adding CFLAGS+=-I$(path_to_source) might be useful.
Also note that if a file is in both your source and build directory, make will use the file in your build directory.
On automake
If you use automake, you're pretty much using the entire autotools. automake cannot work without autoconf.
The Makefiles generated by automake support out-of-source builds and cross-compilation, so you should be able to create subdirectories arm/ and thumb/ and run ../configure --host=arm-host-prefix in arm/ and run ../configure --host=thumb-host-prefix in thumb/. (I don't know the actual host tuples that you'd use for each compiler.)
Using GNU make
Since you're using GNUMake, you could do something like this:
ACOBJS := $(addprefix arm/,$(ACSRC:.c=.o))
TCOBJS := $(addprefix thumb/,$(TCSRC:.c=.o))
Use something like this answer to ensure that the arm/ and thumb/ directories (and any subdirectories) exist.

recursive gmake question

I need to write a quick makefile for building all my projects. This is C++ code and I am using gmake.
Say I have a list of directories, I want to cd to each, issue gmake command and if it succeeds, go to the next one and so on.
I cooked this by looking at the gmake manual
.PHONY: all clean dirs $(DIRS)
dirs: $(DIRS)
$(DIRS): \n\t
$(MAKE) -C $#
It works for the "all" target - if I just type gmake, it does the right thing. But if I do gmake clean it does nothing.
I am learning gmake as I go, so I am certainly doing something silly here :)
Thanks for any help.
In order to recursively make something other than the first target (I'm guessing all is your first target), you need to give the sub-make an idea of what to build. You can do so with the MAKEFLAGS and MAKECMDGOALS variables.
For example:
$(DIRS):
$(MAKE) -C "$#" $(MAKEFLAGS) $(MAKECMDGOALS)
Your rule was not passing along the target names, e.g. clean, so the sub-make had no work to do (since all was already built).

Resources