Writing an LLVM Pass - failing - compilation

I'm working though http://llvm.org/docs/WritingAnLLVMPass.html, trying to write a very simple pass. (Assume I'm using 'Joe' rather than 'hello', because there is already a 'hello' in the relevant directory)
I create the directory 'joe' where I should , I create the suggested cpp file in 'joe' (although I note that none of the nearby directory's have any cpp files in them) and I name it 'joe.cpp' because I don't believe I've been told differently...
I reach the part of the documentation where it says 'compile the file with a simple "gmake" command in the local directory' but I get the error
make: *** No rule to make target
/Users/joXXXXX/llvm/llvm/lib/Transforms/joe/Makefile',
needed byMakefile'. Stop.
which is utterly confusing. I note the similarity to this case, but in that case running ../config and then a make in the root directory solved in the problem. In my task this takes 20 minutes and then nothing has changed... could anyone tell me what is meant to have happened or give me a trace of what success looks like?
Edit - Local Makefile looks like this:
# Makefile for hello pass
#
# # Path to top level of LLVM hierarchy
LEVEL = ../../..
#
# # Name of the library to build
LIBRARYNAME = joe
#
# # Make the shared library become a loadable module so the tools can
# # dlopen/dlsym on the resulting library.
# LOADABLE_MODULE = 1
BUILD_ARCHIVE = 1
# # Include the makefile implementation stuff
include $(LEVEL)/Makefile.common

I faced the same problem and resolved this by re-reading the tutorial:
First, configure and build LLVM. This needs to be done directly inside the LLVM source tree rather than in a separate objects directory.
It means that you should not create a "build" folder as recommended in LLVM get started. Assume you downloaded the llvm source in $LLVM, here is list that I made it works:
create a new folder, let says MyHello, in $LLVM/lib/Transforms/ and necessary files for a pass as in the tutorial.
$cd $LLVM
$./configure
$make
$cd lib/Transforms/MyHello
$make

So it turns out that when the helpfile says 'lib/Transforms/Hello' it means 'somestuff/llvm/lib/Transforms/Hello' not '/somestuff/build/lib/Transforms/Hello'. In hindsight this is not as opaque as it could be, but I'd like to leave this answer to help other people who might have missed this in the doc...

Related

Attempting to compile through MacOS Terminal: "No such file or directory"

I'm trying to compile this project from DTU. This project requires that PETSc be installed.
I have installed PETSc to /Users/hornymoose/petsc-3.13.3/
I have extracted the zip from GitHub to /Users/hornymoose/dtu
The DTU project's makefile has the following lines:
include ${PETSC_DIR}/lib/petsc/conf/variables
include ${PETSC_DIR}/lib/petsc/conf/rules
include ${PETSC_DIR}/lib/petsc/conf/test
In these lines, {PETSC_DIR} is to be substituted with the user's PETSc installation directory. Thus, I changed these lines to:
include $/Users/hornymoose/petsc-3.13.3/lib/petsc/conf/variables
include $/Users/hornymoose/petsc-3.13.3/lib/petsc/conf/rules
include $/Users/hornymoose/petsc-3.13.3/lib/petsc/conf/test
To compile the code, I write make topopt in Terminal. Doing so yields:
makefile:13: Users/hornymoose/petsc-3.13.3/lib/petsc/conf/variables: No such file or directory
makefile:14: Users/hornymoose/petsc-3.13.3/lib/petsc/conf/rules: No such file or directory
makefile:15: Users/hornymoose/petsc-3.13.3/lib/petsc/conf/test: No such file or directory
make: *** No rule to make target `Users/jhutopopt/petsc-3.13.3/lib/petsc/conf/test'. Stop.
I have gone back and manually checked that Users/hornymoose/petsc-3.13.3/lib/petsc/conf/variables, ...rules, and ...test definitely exist and do not have errors.
Why am I receiving this error? Am I indicating the directory incorrectly in my makefile? Is the syntax in the makefile incorrect?
I'm sure there is a simple solution, I'm just very new to working with Terminal in MacOS. Thank you in advance!
There is a $ in the paths:
include $/Users/hornymoose/petsc-3.13.3/lib/petsc/conf/variables
^
This causes the / to be treated as a variable, and expanded to nothing because was never set. Run make with option --warn-undefined-variables to get a warning on that sort of thing. Perhaps already obvious at this point, but the correct line would be:
include /Users/hornymoose/petsc-3.13.3/lib/petsc/conf/variables
Rather than manually substituting the PETSC_DIR in the makefile you can provide it through an environment variable (assuming PETSc makefiles aren't bad):
export PETSC_DIR=/Users/hornymoose/petsc-3.13.3
make topopt
...or:
PETSC_DIR=/Users/hornymoose/petsc-3.13.3 make topopt
...or pass its value to the make invocation:
make topopt PETSC_DIR=/Users/hornymoose/petsc-3.13.3

Is there a way to make a makefile autodownload another makefile?

i know it is possible to execute standard rules on a makefile by simply including them like
hi:; echo hello
include hi
but there is some way, by doing this, to fetch an external input like a ftp server or, lets say, the aws s3 to fetch a "newborn" makefile and then include it to the project? in runtime?
like
include https://s3.bucket.domain.com/newmk.mk
As mentioned there's no way to include a URL. However, you can do something almost as good with GNU make's auto-re-make feature.
To do this, include a local file you download and create a rule that knows how to download it:
include newmk.mk
newmk.mk:
wget https://s3.bucket.domain.com/newmk.mk -O $#
In this situation, if (and only if) newmk.mk doesn't exist, then the recipe will be invoked, the file will be downloaded, then make will re-exec itself to read that file.
The make utility has no built-in download support (not even GNU's make which sometimes seems to have the kitchen sink thrown in), but because it can run arbitrary commands, you can fake it up
The simplest case is a fragment like
your_primary_target: newmk.mk
#...
WGET=wget
WGET_FLAGS=-q
newmk.mk:
$(WGET) $(WGET_FLAGS) https://s3.bucket.domain.com/newmk.mk
#...
which will attempt to download the file only if no such file exists.
The main difficulty here is that your users may need to edit the makefile to specify the command-line downloader they have (perhaps curl instead of wget), or it set any flags their network environment requires.
To make the download unconditional use a unbuildable, non-existent target
WGET=wget
WGET_FLAGS=-1
newmk.mk: ALWAYS
$(WGET) $(WGET_FLAGS) https://s3.bucket.domain.com/newmk.mk
# Here "ALWAYS" is *not* the name of a file existing in the file-system
ALWAYS:
(or there are games you can play with .PHONY in GNU-make).

How to get make to fail if generation of a required include passes but the file is not actually created

I have a makefile that is erroneously generating a required makefile include file. The included file does not initially exist, but there is a rule to make it. The rule runs successfully, but because of a bug, the required include file is not created where expected (and thus make is unable to include it). However, instead of make failing (due to the fact that the file still can't be included), make completes successfully.
The following is my makefile1.mak file.
include myfile.mak
default:
#echo hi
myfile.mak:
#echo hello
When I execute 'make -f makefile1.mak', I get:
makefile1.mak:1: myfile.mak: No such file or directory
hello
hi
Of course, I finally figured out that my code to generate myfile.mak was not generating it correctly, but the actual makefiles that I'm using are 100s of lines long, so we didn't notice that the include wasn't happening for quite a while (it was a very subtle build issue that was introduced).
So, my question is - is there any way to get make to fail on the above example?
Add a line to the rule:
myfile.mak:
do various things to build myfile.mak
test -f $#

how to run make for a local subdirectory

I am trying to port an existing code into a larger project. The larger project has a main Makefile with Makefiles in each sub-directory. I am sure the path below tells you all about how it is setup. I want to port my code to
/WORKING_DIRECTORY/Drivers/Char/example
And here is the content:
sansari#ubuntu:~/WORKING_DIRECTORY/drivers/char/examples$ ls
hello1.c Makefile
My question is 1- Should modify this local Makefile or the main one? I am setting up to modify this one, but I am not sure.
2- My other question is if I modify this local file, can I just run make from here and validate my configuration instead of running make for the entire project? I know that make only updates the files that are changed; however I feel better when I clean the build environment before each make. I have run into situations, which this alone fixed my issue.
Just as background, I did try to include the make file of my target project, the one I am trying to import here with -f command. What I did was: make -f Makefile -f ../mytarget/core/Makefile
But I ran into some issues with make not doing some of the normal things it does in the primary project. For instance, there was an include statement with a relative path to a header file, which make gave me an error about not seeing it. So now I am abandoning that strategy for the time being.
#Ahmad Masoud - Hey man, thanks. Here is the Makefile. Hey man, the link is exactly what I needed. I think it will address my other questions also. You see, I cross compiled this code, and when I flashed my phone, I get the following for
uname -r: 1|root#hltespr:/lib/modules # uname -r
uname -r
3.4.0-g7e6fbf7-dirty
And I have been wondering what "dirty" means and where it comes from. If you know please tell me. The link you sent, states that perhaps make would insert the Linux kernel version there? I ask this since, modprobe does not work when I try to load my module. Instead insmod works, and I can validate that my module is in. My main issue now is that I don't know how to execute the file to make sure it runs. I only know how to run the file using modprobe, and I can not use it. It gives me the following error:
1|root#hltespr:/ # modprobe /lib/modules/hello1.ko
modprobe /lib/modules/hello1.ko
modprobe: can't change directory to '3.4.0-g7e6fbf7-dirty': No such file or directory
Update as of 06/20/15 -I put in include /home/sansari/mytree2/tbt/makefile in my module's make file. I get the following error: makefile:3: *** missing separator. Stop.
#Ahmad - This is an update as of 062415. Thanks for the info. My goal is to get make to look into this external directory, collect all the source files and build them for me. What would you suggest? I am stuck because as it stands, I know make looks into my examples directory, but no other changes I make to that local make file in the examples directory shows up in make. For instance I tried adding ($warning ....) and #echo messages, but even they do not show up.
Update on 070215- Thanks for the previous comments and support. I feel I really should reopen this thread since I did not explain the goal in detail, and now I feel I can describe it better, and hopefully the resolution will help other. I issue the command:
TARGET=msm8974 PLATFORM=msm8974 make drivers/char/examples
But I get a message stating: Nothing to be done, while I have added a number of tasks to do. Below is my make file, and I'll elaborate on what I have added right after:
lib_tbt := ../../../m/shahin/tbt
lib_daemon := ../../../m/shahin/daemon
lib_lib := ../../../m/shahin/lib
lib_tasks := ../../../m/shahin/tasks
lib_tbt_driver := ../../../m/shahin/tbt_driver
lib_tbt_make := ../../../m/shahin/tbt/make
lib_tbt_msm_common := ../../../m/shahin/tbt/platform/msm8974/common
lib_tbt_msm8974 := ../../../m/shahin/tbt/platform/msm8974
lib_asm_generic = ../../../m/shahin/tbt/platform/msm8974/include/asm-generic
$(warning This is what is in lib_asm_generic $(lib_asm_generic))
#include $(lib_tbt_make)/macros.mk
.PHONY: all $(lib_tbt)
$(lib_tbt) $(lib_daemon) $(lib_lib) $(lib_tasks) $(lib_tbt_driver) $(lib_tbt_make) $(lib_tbt_msm_common) $(lib_tbt_msm8974) $(lib_asmgeneric) :
$(MAKE) --directory=$#
$(lib_*): $(MAKE) --directory=$#
obj-$(CONFIG_EXAMPLES) += hello1.o
_
Initially I only had the obj-$(CONFIG_EXAMPLES) += hello1.ostatement in my make file. I then proceeded to add the directory variables at the top of my makefile and added the $(lib_*): $(MAKE) --directory=$# directing make to compile what is in the directory. I believe that is what it does. Please let me know if I am mistaken. And although this same make file proceeds to create object files when I put it a different directory within my project, it won't do so when it is in a device driver directory. And I do not understand why. The other directory is the /external directory and it is at the top of the tree. But that should not matter right. What I have done was to first make sure I can compile a hello program in my device driver directory called /examples. I now want to add more source code to this section. I believe the correct term is module? I also want to know if I should copy of the source files to the /examples directory or referencing them via the path is ok. That is should I move the source code directory under /examples directory or not?
It is a LOT simpler than that if you are using a kernel that uses Kbuild.
Highly recommend reading
http://www.tldp.org/LDP/lkmpg/2.6/html/x181.html
Situation A - Your source is a sub-tree of the kernel source
You would NOT modify the top-level Makefile, just ensure that ~/WORKING_DIRECTORY/drivers/char/examples/Makefile and ~/WORKING_DIRECTORY/drivers/char/examples/KBuild are set up correctly/normally. THEN at the top-level of the kernel build directory (assuming you have a separate build directory) you would type:
foo#bar:~/build-dir$ make drivers/char/examples
The kernel top-level makefile then builds just that sub-tree. You can try it out on any part of the kernel, for example:
foo#bar:~/build-dir$ make fs
NOTE: build-dir can be the same as the kernel source directory
Situation B - You are building an external module
Then use the normal module KBuild / Makefile process.
P.S.
If you post your makefile / Kbuild then I may be able to help with the actual build processing.

OCaml makefile dependency problem

I am using OCaml Makefile for a project I am working on and I have the folowing modules
DynamicTree.ml
Huffman_Dynamic.ml which uses DynamicTree
Huffman_Static.ml
main.ml which uses both Huffman_Static and Huffman_Dynamic.
This is my make file :
# put here the names of your source files (in the right order)
SOURCES = huffman_static.ml dynamictree.ml huffman_dynamic.ml main.ml
# the name of the resulting executable
RESULT = huffman
# generate type information (.annot files)
ANNOTATE = yes
# make target (see manual) : byte-code, debug-code, native-code
all: native-code
include OCamlMakefile
When I try to make the project, I get an Unbound value DynamicTree.create_anchor_leaf that results from ocamlopt -c -dtypes huffman_dynamic.ml generated by Makefile.
The Ocaml Makefile wepage states that it generates automatically dependencies, am I missing something here?
Thank you.
Is the capitalization of your name correct ? In your post you use both DynamicTree.ml and dynamictree.ml.
Are you sure the issue comes from the Makefile ? Is there really a create_anchor_leaf function exported by DynamicTree.ml ? No .mli hiding it ?

Resources