gengetopt and Automake - c

I'm trying to include the generation of the cmdline.c file (from gengetopt's defaults) in my Makefile.am file.
The file currently reads like these:
bin_PROGRAMS = myprog
myprog_SOURCES = main.c cmdline.c
myprog_DEPENDENCIES = gen_cmdline $(myprog_SOURCES) # somewhere I read that setting DEPENDENCIES inhibits automake from calculating those
gen_cmdline:
gengetopt < myprog.ggo
However, if I modify just myprog.ggo, the cmdline.c and all its dependents won't get recompiled. What am I missing here?

Is gen_cmdline a .PHONY target? If gengetopt creates a file named cmdline.c, then your Makefile.am should probably look like:
bin_PROGRAMS = myprog
myprog_SOURCES = main.c cmdline.c
BUILT_SOURCES = cmdline.c
cmdline.c: myprog.ggo
gengetopt < $(srcdir)/myprog.ggo

Related

Makefile with two .c files and no header

Trying to write a makefile with two .c files and no header. However, it seems examples online have shown the makefile with a header.
So i tried to write a header file and it would tell me a function is redefined somewhere else. my header consisted of declarations of functions in both my .c files.
#ifndef HEADER_H
#define HEADER_H
void calc(void parameters);
int main(int argc, char* argv[]);
struct compArray
{
int start;
int end;
int thr;
int m;
int r;
};
#endif
I'm positive that's not how you write a header but ideally I'd like to have my makefile without a header. Below is my Makefile:
all: thr_atomic.o thr_reduce.o
gcc -o make thr_atomic.o thr_reduce.o -lm -pthread
thr_atomic.o: thr_atomic.c
gcc -c thr_atomic.c
thr_reduce.o: thr_reduce.c
gcc -c thr_reduce.c
Is it possible to create a makefile without a header? My two .c files are independent of each other. If so how do I go about doing that? And if not, what would I put in my header.h to tell the computer that my variables are not being redefined and are independent from each other?
You can use the following Makefile:
all: thr_atomic thr_reduce
thr_atomic: thr_atomic.c
gcc thr_atomic.c -lm -pthread
thr_reduce: thr_reduce.c
gcc thr_reduce.c -lm -pthread <newline>
However, since it seems the two programs are totally independent, I would rather make two separate makefiles.
From what I can understand from your question, you don't need a header file in order to compile C code using a Makefile. Makefiles don't have anything to do with source code. All a Makefile does is run a command(s) if the file(s) you've specified have been updated.
# Makefile
outfile: infile1 infile2
command1
command2
# ^ commands MUST begin with a tab
If you run make outfile, this is what happens:
If outfile does not exist, then make runs command1, and then runs command2.
If outfile exists, but infile1 and infile2 have not been updated since then, make will do nothing.
If outfile exists and infile1 or infile2 have been updated since outfile was last modified, then make will run command1 and then run command2.
That's the basics of make and Makefiles. The files (outfile, infile1, infile2 etc.) and the commands (command1, command2) can be anything you like. There can also be any number of them present.
When it comes to compiling code, make is pretty useful because you can use it to recompile a binary file (also called an executable file) if the source files are changed, which is exactly what you want.
For example, this makefile creates a binary file (executable file) from two source files (and no header files):
# Makefile
# executable file is called "prog"
prog: a.o b.o
gcc -o prog a.o b.o
# ^^^^^^^
# tell gcc to name the output file "prog"
# compile the first source file "a.c" to produce the object file "a.o"
a.o: a.c
gcc -c a.c
# compile the second source file "b.c" to produce the object file "b.o"
b.o: b.c
gcc -c b.c
If you do have header files, then you would need to change the compilation lines to this:
# Makefile
# ...
# compile a.c, which has an associated header file a.h
a.o: a.c a.h
# ^^^ add the header file here
gcc -c a.c
If you are not clear about what header files are, then look them up somewhere or ask another question about them.

include_HEADERS and no rule for target needed by 'all-am'

I am trying to compile a library with autotools. The library compiles fine with the following Makefile.am in its source directory library/src
lib_LTLIBRARIES = libgtkchart.la
libgtkchart_la_CFLAGS = $(CFLAGS) -fPIC -Wall $(gtk_CFLAGS)
libgtkchart_la_LIBADD = $(gtk_LIBS) $(glib_LIBS)
libgtkchart_la_LDFLAGS = -fPIC -shared -version-info 1:0:0
libgtkchart_la_SOURCES = gtkchart.c gtkaxis.c gtkbarchart.c gtkchartdata.c gtkchart.h gtkaxis.h gtkbarchart.h gtkbarchartdata.h
but if I add the following line to that file:
include_HEADERS = gtkaxis.h gtkbarchart.h gtkbarchartdata.h gtkchart.h
I get the following error:
make[2]: *** No rule to make target 'gtkbarchartdata.h', needed by 'all-am'. Stop.
My main MAkefile.am in library/ is
SUBDIRS = src
ACLOCAL_AMFLAGS= -I m4
and my configure.ac is
AC_CONFIG_MACRO_DIRS([m4])
AC_INIT([library], [1.0], [me])
AM_PROG_AR
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([
Makefile
src/Makefile
])
LT_INIT
AC_OUTPUT
I can't figure out why the need for a target for that header file.
When you assign header files to the include_HEADERS, automake must
be able to locate the header.
For example, if you have the following directory structure:
src
Makefile.am
GTKBarCharDataDirectory
SomeOtherDirectory
gtkaxis.h
gtkbarchart.h
gtkchart.h
And gtkbarchartdata.h is located in the GTKBarCharDataDirectory directory, then you need to change your include_Headers to be:
include_HEADERS = gtkaxis.h gtkbarchart.h GTKBarCharDataDirectory/gtkbarchartdata.h gtkchart.h
make must know the relative path of the header file, when using the include_Headers variable. This is due to the fact that the HEADER family of variables works differently than the SOURCES family of variables.
automake won't fail if you list a non-existent/not-found header file
in the libgtkchart_la_SOURCES variable, since Header files listed in
a _SOURCES definition will be included in the distribution but
otherwise ignored.
Check here and here for a reference

How to write `make` file for separate source and build directory for large program with mixed Fortran F77 and F90 code

I have about 39 Fortran F90 source files and 35 Fortran 77 Lapack related files. I am using include statement in my main program to connect all these files.
I have created a batch file make.bat with command ifort "MDL HydroD.F90" which compiles my code and generates the mdlhydrod.exe file. In the process the Fortran compiler creates many .mod and .obj build files which makes it difficult to manage. I would like to put my source files under a directory Source and lapack library files in a directory lapack and build files in a directory Debug.
Could anyone help me modify my make.bat file so that ifort looks at Source directory and build in Debug directory.
Thank you for help.
Currently using make.bat has only one line of command:
File Name: make.bat
ifort "MDL HydroD.F90"
Working on a make file to be used with nmake (incomplete):
File Name: make.mak:
#Make File for MDL HydroD
# Compiler options
FC := ifort
VPATH := src
BINDIR := bin
$(BINDIR):
mkdir -p $(BINDIR)
clean:
#rm -rf $(BINDIR)
Because you are using a strange way of working with source files, which you showed in your other question, it will be very difficult to change this.
For recapitulation, you include everything in a single source file using the include statement. This looks pretty unfortunate to me and I commented on that there. If you have one source file, you are forced to build it with one command, there is no place for any fine control. This is not the issue of a bash or bat script vs. Makefile.
You can probably still keep some files included in some groups that are logically similar, if you need no finer control on that, but I see not much reason for that.
Remove the includes or at least the relevant ones. Then you can just do
ifort Source/the_source_file1 -c Output/name_of_obj1 -module the_directory_for_modules -I the_directory_for_modules -other_flags
for every file. And then in the end:
ifort Output/name_of_obj1 Output/name_of_obj2 Output/name_of_obj3 .... -o the_result
In Scons (which I would use) it would be like this (tested on couple of dummy files). The file Sconstruct:
import os
env = Environment(tools=['default','ifort'])
env.Append(ENV = {'PATH' : os.environ['PATH']})
try:
env.Append(ENV = {'LIBRARY_PATH' : os.environ['LIBRARY_PATH']})
except:
pass
env.Append(F90FLAGS='-g -fast') #whatever flags you need
env.Append(FORTRANFLAGS='-g -fast') #whatever flags you need
outdir = "Output/"
srcdir = "Sources/"
lapackdir = "lapack/"
objs = []
for file in os.listdir(srcdir):
objs += env.Object(target=outdir+os.path.splitext(file)[0], source=srcdir+file)
for file in os.listdir(lapackdir):
objs += env.Object(target=outdir+os.path.splitext(file)[0], source=lapackdir+file)
env.Append(FORTRANMODDIR = outdir)
objs = filter(lambda o: str(o)[-4:] != '.mod', objs)
prg = env.Program(target="bin/result.exe", source= objs)
Default(prg)

Including static library and header Makefile questions (C)

My file stacking is as follows
dir1/
mylib.a
myheader.h
file.c
executable
dir2/
dependentfile.c // depends on functions in myheader.h implemented in mylib.a
I would like to link my static library file in my Makefile WITHOUT using its name, but just indicating its path. What I have is as follows:
Makefile for dir2/
CC = gcc
CFLAGS = -g -Wall $(INCLUDES)
INCLUDES = -I../dir1
LDFLAGS = -g -L../dir1
exec: dependentfile.o
dependentfile.o: dependentfile.c
Running 'make' just gives me a bunch of implicit declaration errors, and undefined references because it's not looking in the paths I have specified with -L and -I. My dependentfile.c also has the line
#include "myheader.h"
which it can't find.
How should I modify the makefile in order to make this work? I have tried multiple things, even specifying the lib file with -l and writing the complete path to no avail.
Any help is appreciated!
#
EDIT: Figured it out!
Turns out I was forgetting LDLIBS. So for everyone else, the makefile ended up looking like:
CC = gcc
CFLAGS = -g -Wall $(INCLUDES)
INCLUDES = -I../dir1
LDFLAGS = -g -L../dir1
LDLIBS = -lmylib (my actual file was named libmylib.a, forgo the "lib")
exec: dependentfile.o
dependentfile.o: dependentfile.c
I think you should use
#include "myheader.h"
Your header file name should be quoted.

How to link two .c files in this advanced makefile?

I wanna use some functions which are defined in libvmi/driver/xen.c file, in process-list.c file,but I don't know where in Makefile I should link this two ".c" files.
I know how to do this in a simple Makefile but I couldn't find something like that in this Makefile to add linking part of libvmi/driver/xen.c and process-list.c.
This Makefile belongs to a project with several Makefiles.
Thanks for any help!
## Source directory
SUBDIRS =
INCLUDES = -I$(top_srcdir)
AM_LDFLAGS = -L$(top_srcdir)/libvmi/.libs/
LDADD = -lvmi -lm $(LIBS)
c_sources = process-list.c \
libvmi/driver/xen.c
bin_PROGRAMS = module-list process-list map-symbol map-addr dump-memory
module_list_SOURCES = module-list.c
process_list_SOURCES = $(c_sources)
map_symbol_SOURCES = map-symbol.c
map_addr_SOURCES = map-addr.c
dump_memory_SOURCES = dump-memory.c
You shouldn't need to link two .c files, you need to compile them and then link the .o files. If your project makefile is generated, perhaps this happens automatically, if not you would mainly need to add the new .c files to the build.

Resources