I am writing an LLVM pass, just following http://llvm.org/docs/WritingAnLLVMPass.html#basic-code-required.
I have finished the Makefile, the source code, however, when I came to do the make:
Now that it’s all together, compile the file with a simple “gmake” command in the local directory and you should get a new file “Debug+Asserts/lib/Hello.so” under the top level directory of the LLVM source tree (not in the local directory).
It reported
../../../Makefile.common:61: ../../../Makefile.config: No such file or directory
../../../Makefile.common:69: /Makefile.rules: No such file or directory
make: *** No rule to make target '/Makefile.rules'. Stop.
I didn't change the any configuration files in the root directory. There is no Makefile.config in my root directory, but there is a file called Makefile.config.in. Makefile.common appears in the root directory.
I hate to be the one to tell you, but I think you'll need to get your basics straight before diving into compiler development:
http://llvm.org/docs/WritingAnLLVMPass.html has a lot of documentation that you should definitely read, including information on the Manager:
The PassManager class takes a list of passes, ensures their prerequisites are set up correctly, and then schedules passes to run efficiently. All of the LLVM tools that run passes use the PassManager for execution of these passes.
A makefile is a mechanism of defining how a piece of software is built by compiler, linker, installation scripts etc. How that will look like depends completely on how you plan to implement your software. In your case, you should definitely orientate yourself on existing passes. In fact, http://llvm.org/docs/WritingAnLLVMPass.html#setting-up-the-build-environment has a rather detailed explanation on how to set up the makefile, including a template, which is really simple
# Makefile for hello pass
# Path to top level of LLVM hierarchy
LEVEL = ../../..
# Name of the library to build
LIBRARYNAME = Hello
# Make the shared library become a loadable module so the tools can
# dlopen/dlsym on the resulting library.
LOADABLE_MODULE = 1
# Include the makefile implementation stuff
include $(LEVEL)/Makefile.common
If you don't understand that, you'll have to read a bit of existing Makefiles or make documentation.
All in all, I think writing LLVM passes might not be the thing I'd get started with if not being used to these kind of standard tools, but I recommend just diving into the LLVM source code tree to get a feeling. Practice makes a master!
Related
I'm writing a large OCaml project. I wrote a file foo.ml, which works perfectly. In a subdirectory of foo.ml's directory, there is a file bar.ml.
bar.ml references code in foo.ml, so its opening line is:
open Foo
This gives me an error at compile time:
Unbound module Foo.
What can I do to fix this without changing the location of foo.ml?
The easy path is to use one of OCaml build system like ocamlbuild or oasis. Another option would be jbuilder but jbuilder is quite opiniated about file organization and does not allow for the kind of subdirectory structure that you are asking for.
The more explicit path comes with a warning: OCaml build process is complicated with many moving parts that can be hard to deal with.
After this customary warning, when looking for modules, OCaml compiler first looks for module in the current compilation environment, then looks for compiled interface ".cmi" files in the directories specified by the "-I" option flags (plus the current directory and the standard library directory).
Thus in order to compile your bar.ml file, you will need to add the parent directory in the list of included directories with the -I .. option.
After all this, you will discover that during the linking phase, all object files (i.e. .cmo or .cmx) need to be listed in a topological order compatible with the dependency graph of your project.
Consequently, let me repeat my advice: use a proper build system.
I would like to edit an existing software to add a new source file (Source.cpp).
But, I can't manage the compilation process (it seems to be automake and it looks very complicated).
The software (iperf 2: https://sourceforge.net/projects/iperf2/files/?source=navbar) is compiled using a classical ./configure make then make install.
If I just add the file to the corresponding source and include directory, I got this error message:
Settings.cpp:(.text+0x969) : undefined reference to ...
It looks like the makefile isn't able to produce the output file associated with my new source file (Source.cpp). So, I probably need to indicate it manually somewhere.
I searched a bit in the project files and it seemed that the file to edit was: "Makefile.am".
I added my source to the variable iperf_SOURCES in that file but it didn't workded.
Could you help me to find the file where I need to indicate my new source file (it seems a pretty standard compilation scheme but I never used automake softwares and this one seems very complicated).
Thank you in advance
This project is built with the autotools, as you already figured out.
The makefiles are built by automake. It takes its input in files that usually have a am file name extension.
The iperf program is built by the makefile generated from src/Makefile.am. This is indicated by:
bin_PROGRAMS = iperf
All (actually this is a simplification, but which holds in this case) source files of a to be built binary are in the corresponding name_SOURCES variable, thus in this case iperf_SOURCES. Just add your source file to the end of that list, like so (keeping their formatting):
iperf_SOURCES = \
Client.cpp \
# lines omitted
tcp_window_size.c \
my_new_file.c
Now, to reflect this change in any future generated src/Makefile you need to run automake. This will modify src/Makefile.in, which is a template that is used by config.sub at the end of configure to generate the actual makefile.
Running automake can happen in various ways:
If you already have makefiles that were generated after an configure these should take care of rebuilding themselves. This seems to fail sometimes though!
You could run automake (in the top level directory) by hand. I've never done this, as there is the better solution to...
Run autoreconf --install (possibly add --force to the arguments) in the top level directory. This will regenerate the entire build system, calling all needed programs such as autoheader, autoconf and of course automake. This is my favorite solution.
The later two options require calling configure again, IMO ideally doing an out of source built:
# in top level dir
mkdir build
cd build
../configure # arguments
make # should now also compile and link your new source file
I have a project consisting of a set of makefiles that CANNOT be run with make --jobs=N because the dependencies are not specified tightly enough for make to correctly execute the recipes in correct order (ie I get race conditions).
I am currently using Huddle, by Electric-Cloud.com, and it does exactly what I need: it parses the makefile and then executes the jobs in parallel and accounts for the unspecified dependencies.
Question: is there a free or free-er thing that does this?
Yes I know I could re-write the makefiles but project management says "no way".
UPDATE #1
I understand that I'll have to do some work to get functionality similar to Electric-Cloud's functionality.
I know that Electric-Cloud parses the makefile(s) to find the dependencies so wouldn't the same thing be accomplished using makedepend?
I'm thinking:
Run makedepend on existing makefiles
Feed in the output using include <makedepend.output>
make all --jobs=64
UPDATE 2
Turns out makedepend is specific to C/C++: it merely runs the pre-processor on source files and parses any #include statements; not what I need.
I need what this guy is asking for:
Build a makefile dependency / inheritance tree
UPDATE 3
The makefile "dependency graph generator" actually already exists
http://plindenbaum.blogspot.com/2012/11/visualizing-dependencies-of-makefile.html?m=1
but that's not going to help me.
Many of my recipes create directories which are used by other targets' recipes, effectively making them implicit prerequisites.
The graph dependency tool at above URL works by parsing the build log's statements but those statements don't indicate the implicit dependencies.
Even if I try to run my makefile with --dry-run, the build fails because some of the recipes that aren't executed - cause it's a dry run - create directories that other invocations of make need simply to 'pretend execute' a recipe.
UPDATE 4
Electric-Cloud has made Huddle - 4 local cores, non-clustered - free for anyone forever.
Furthermore, they output an .xml file that lists each job's dependencies so I can use it to fix my makefiles compatible so they're compatible with the --jobs option.
I am currently using Huddle, by Electric-Cloud.com, and it does exactly what I need: it parses the makefile and then executes the jobs in parallel and accounts for the unspecified dependencies.
I actually don't know about these tools, but can't you provide them with a super makefile under your control, that clarifies the inner dependencies of the various targets?
You probably just have to add some indirection level for these (imported?) projects directory structure and another Makefile.
Context
I am working on a klee (http://klee.llvm.org) fork and want to clean up our repository to separate our stuff from the "canonical" klee code. Anyway, I'm having trouble understanding/extending the build system.
Problem
The directory structure in /lib/ looks like this
Basic/
Core/
Support/
Expr/
Solver/
Module/
Mine/
Mine was just added by me, so far we threw everything in Core and I am moving it to Mine. How do I tell the build system to do this properly?
My attempt
Being unable to figure this out on my own, I edited /lib/Makefile:
LEVEL=..
PARALLEL_DIRS=Basic Support Expr Solver Module Core Mine
include $(LEVEL)/Makefile.common
and copied the /lib/Core/Makefile to /lib/Mine/Makefile while changing LIBRARYNAME=kleeCore to LIBRARYNAME=kleeMine.
Caveat
I have a feeling that this is not the proper way to do it, and I should rather modify some configure script or something. Also it does not link (it compiles, though).
A colleague just told me how to get it to link, which is by modifying /tools/klee/Makefile
USEDLIBS = kleeCore.a kleeModule.a kleaverSolver.a kleaverExpr.a kleeSupport.a kleeBasic.a kleeMine.a
I'm taking some C++ classes and have send the teacher 9 exercises, each exercise is a simple directory with the name 'ex$' where $ is the number. Each directory has a single source file named 'ex$.cpp. I want to create a makefile that will allow me to type:
make ex$
And it will build a executable that corresponds to the compiled source file inside 'ex$' directory. The catch is that I want to do that without creating a target for each exercise(Some kind of 'generic target'). I also need to have an 'all' target that will go into each directory starting with 'ex' and build the executable there. How can I do that?
If all your C++ targets can be built with essentially the same command, you can do this fairly easily. Read this. Look for $#, in particular. Since this is part of an education, I'll leave the rest vague.
Can I also suggest looking at CMake which will make better makefiles for you to use IMO. Initial high learning curve for major long term gain. :)