C programming - picking up the machine name, username at compile time - c

Are there a set of defines that are created at compile time, that I can use to populate a printk statement with information about where and who last build a kernel driver? I know that there are predefined C macros, and I was hoping to find something in there that is dynamically set as the compile is kicked off, but there doesn't appear to be.
This would be specific to GCC as well. Thanks in advance.

To expand on my comment; you could just use the shell function of make, in case you use make.
It could look something like this in the makefile:
USER=$(shell whoami)
HOST=$(shell hostname)
CXX=gcc
CXX_DEFINES=-D__BUILD_USER=\"$(USER)\" -D__BUILD_HOST=\"$(HOST)\"
CXX_FLAGS=-c -Wall -Wextra $(CXX_DEFINES)
CXX_LFLAGS=
SOURCES=main.c
OBJECTS=$(SOURCES:.c=.o)
EXEC=hostusertest
all: $(SOURCES) $(EXEC)
clean:
rm $(OBJECTS)
rm $(EXEC)
$(EXEC): $(OBJECTS)
$(CXX) -o $# $(OBJECTS) $(CXX_LFLAGS)
%.o: %.c
$(CXX) $(CXX_FLAGS) $<
Basically just use the standard shell commands to gather the information and create a variable in the makefile that keeps that info after using the shell function $(shell ...) to get it.
Then just set it via -D NAME=VALUE but don't forget to add escaped qoutation marks.

Related

'linker input file unused because linking not done' error when running make

I'm compiling C programs I made for a project.
Goals
Compiling get_next_line.c and get_next_line_utils.c.
Structure
I have 3 files, get_next_line.c, get_next_line_utils.c and get_next_line.h in my folder (excluding Makefile). Nothing more, nothing less.
Code
NAME = get_next_line
SRCS = get_next_line.c get_next_line_utils.c
OBJS = $(SRCS:.c=.o)
CC = gcc
CFLAGS = -Wall -Wextra -Werror
LIB_CRT = ar rcs
all: $(NAME)
$(NAME) : $(OBJS)
#$(LIB_CRT) $(NAME) $(OBJS)
%.o: %.c $(INCLUDE)
#$(CC) -c $(CFLAGS) -o $# $<
clean:
#rm -f $(OBJS) a.out
fclean: clean
#rm -f $(NAME)
re : fclean all
Error Message
linker input file unused because linking not done. I get this error several times.
I keep on running on this error when I run make. I followed another Makefile I had for another project, to no avail. I also read this article and that one too but they aren't relevant to my issue.
Any input appreciated.
Your makefile appears to be aimed at building a program named "get_next_line", but this is not altogether clear because what you are actually building is a static archive file with that (unconventional for an archive) name. That's what the ar utility does. With the gcc toolchain and many others, one would normally use the same front end (gcc in this case) for both compiling and linking. That is,
$(NAME) : $(OBJS)
$(CC) -o $(NAME) $(OBJS)
... or, a bit DRYer ...
$(NAME) : $(OBJS)
$(CC) -o $# $^
It is not clear why you are getting the specific message you report. It looks like a message from the linker, ld, but I see no reason in the makefile presented to think that the linker would ever run. As such, I am inclined to suppose that the message is associated with something altogether different. Possibly you are running make in a different working directory, and therefore using a different makefile. Or perhaps it is associated with some other command than make itself. Or maybe you have an influential variable set in your environment that alters the meaning of your makefile. Maybe you get that message when you try to run the archive as if it were a program (though that's not what I would expect to happen in that case).

gmake (Gnu) to make (Cygwin) - verification of my implementation [only 3 statements]

I need to convert a makefile built for gmake into a makefile that could be executed via cygwin "make" command.
The GMAKE code is below:
OBJ := ${SOURCES:%.c=%.o}
%.o: %.c
$(CC) -c -o $# $< $(CFLAGS) $(DEFINES)
$(LIBNAME).lib: $(OBJ)
$(AR) rcs $# $(OBJ)
clean:
del $(OBJ)
del *.out
I've used the statements below in the Cygwin makefile. Could you please confirm, if it replicates the gmake statements above or am I missing something. Any inputs would be helpful.
Cygwin "make":
OBJ := ${SOURCES:%.c=%.o}
%.obj: %.c
$(CC) -c -o `cygpath -w $#` `cygpath -w $<` $(CFLAGS) $(DEFINES)
.DEFAULT_GOAL := ${LIBNAME}.lib
${LIBNAME}.lib: $(OBJS)
$(SILENCE)echo -e "Archive: ${LIBNAME}.lib\n"
$(SILENCE)$(AR) $(ARFLAGS) `cygpath -w $#` ${OBJS}}
clean:
rm $(OBJ)
rm *.out
Thanks much in advance.
As pointed out by #matzeri, cygwin make is gnu make.
That's why I use it.
The first makefile looks fine to me.
If all your files use relative paths, everything should be fine.
Even the Microsoft compiler can build subdir/file.cpp and stick the object into objdir/file.o (cl subdir/file.cpp -o objdir/file.o).
Hint: Strive manfully to use forward slashes in your filenames. Always.
The only difficulty you might have is with absolute paths,
as typically appear in include paths say.
/usr/local/include only makes sense to cygwin programs.
cl.exe would like this translated to C:/cygwin64/usr/local/include.
Don't use backslashes unless the command really really requires it.
One issue then is that bash interprets backslashes,
so you will have to quote the filename in some way to prevent this.
objdir/1.o: /usr/local/src/1.cpp
some-odd-compiler "$$(cygpath -wa $<)" -o "$$(cygpath -w $#)"
Quoting not required if you use forward slashes (cygpath -ma).
Why prefer $(…) over `…`? Because then the double quotes nest.
Useful if the path in question expands to something with a space in it ("$$(cygpath -wa "$<")")

Why does my Makefile do nothing?

#
# MakeFile assignment 2
# Variables
CC=gcc
LINK=gcc
CFLAGS=-c -Wall -I.
OBJECT_FILES = cmpsc311-f13-assign2.o a2support.o
#Suffix rules
.SUFFIXES: .c .o
.c.o:
$(CC) -c $(CFLAGS) -o $# $<
#Productions
cmpsc311-f13-assign2 : $(OBJECT_FILES)
$(LINK) $(OBJECT_FILES) -o $#
#Dependencies
cmpsc311-f13-assign2.o : cmpsc311-f13-assign2.c a2support.h
a2support.o : a2support.c a2support.h
clean:
rm cmpsc311-f13-assign2.o
rm a2support.o
Every time I use the command make Makefile it does nothing, is there something wrong with my makefile or is it another issue?
Running the following command also dose nothing:
gcc -o cmpsc311-f13-assign2 cmpsc311-f13-assign2.c a2support.c a2support.h -I.
Every time I use the command make Makefile it does nothing
make Makefile tries to create Makefile. Since you don't have any rule to create it, there's nothing to do.
Usually make is invoked with no arguments; it uses Makefile by default, and tries to make the first target defined (in your case, cmpsc311-f13-assign2).
You can use the -f option to specify a different makefile to use:
make -f foo.mk
or you can use an argument to specify what to build:
make clean
or both:
make -f foo.mk clean
Apart from the answer mentioned above you also need to add a TAB character at line 14.
$(CC) -c $(CFLAGS) -o $# $<

Make recursive all C files

I really can't get into makefiles. In previous projects, I hardcoded all compile tasks in the Makefile:
all: compile_a compile_b compile_c
compile_a:
${CC} ${CFLAGS} ${A_SRC} -o ${A_OUT}
and so on.
But as the latest project has more files than every project before, I want to write better make tasks and of course LESS characters as make is not really friendly to my eyes (it makes them suffer)! :-P
What I want:
One task to rule them all (just make projectname or make all, you know?)
One task for every C file to compile (I read something about this %.o: %.c syntax, but didn't really get it)
One task for linking (how to get all .o files and link them without hardcoding each?)
One task for cleaning (oh, i can do this!)
The project structure is:
bin (binary goes here!)
src
some
directories
are
here
I don't know if I need a directory for object files, I put them in ./bin, I think that's good enough, isn't it?
Maybe I just need someone who can explain it with easy words!
EDIT:
As someone pointed out, there's no real question, so here it goes:
how to recursively compile all C files to bin/(filename).o
how to link all .o files in 'bin/' without knowing their names
maybe this helps.
Try this:
CC = gcc
CFLAGS = -c -Wall -g -Os
LD = $(CC)
LDFLAGS = -lfoo
TARGET = MyProject
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) -o $# $^ $(LDFLAGS)
# You don't even need to be explicit here,
# compiling C files is handled automagically by Make.
%.o: %.c
$(CC) $(CFLAGS) $^ -o $#
clean:
rm $(TARGET) $(OBJECTS)
I frequently use the wildcard function in combination with the foreach function for something like you want to achieve.
If your sources are in src/ and you want to put the binaries into bin/ the basic construction of my Makefile would look like follows:
SOURCES=$(shell find src -type f -iname '*.c')
OBJECTS=$(foreach x, $(basename $(SOURCES)), $(x).o)
TARGET=bin/MyProject
$(TARGET): $(OBJECTS)
$(CC) $^ -o $#
clean:
rm -f $(TARGET) $(OBJECTS)
I usually take advantage of make's built in implicit rules and predefined variables (Make manual, Chap 10).
without going into specifics of makefiles, use the * to your advantage.
i.e.
compileAll: gcc -c *.c
linkAll: gcc *.o -o output.exe

How do I make a simple makefile for gcc on Linux?

I have three files: program.c, program.h and headers.h.
program.c includes program.h and headers.h.
I need to compile this on Linux using gcc compiler. I'm not sure how to do this. Netbeans created one for me, but it's empty.
Interesting, I didn't know make would default to using the C compiler given rules regarding source files.
Anyway, a simple solution that demonstrates simple Makefile concepts would be:
HEADERS = program.h headers.h
default: program
program.o: program.c $(HEADERS)
gcc -c program.c -o program.o
program: program.o
gcc program.o -o program
clean:
-rm -f program.o
-rm -f program
(bear in mind that make requires tab instead of space indentation, so be sure to fix that when copying)
However, to support more C files, you'd have to make new rules for each of them. Thus, to improve:
HEADERS = program.h headers.h
OBJECTS = program.o
default: program
%.o: %.c $(HEADERS)
gcc -c $< -o $#
program: $(OBJECTS)
gcc $(OBJECTS) -o $#
clean:
-rm -f $(OBJECTS)
-rm -f program
I tried to make this as simple as possible by omitting variables like $(CC) and $(CFLAGS) that are usually seen in makefiles. If you're interested in figuring that out, I hope I've given you a good start on that.
Here's the Makefile I like to use for C source. Feel free to use it:
TARGET = prog
LIBS = -lm
CC = gcc
CFLAGS = -g -Wall
.PHONY: default all clean
default: $(TARGET)
all: default
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
HEADERS = $(wildcard *.h)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $#
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -Wall $(LIBS) -o $#
clean:
-rm -f *.o
-rm -f $(TARGET)
It uses the wildcard and patsubst features of the make utility to automatically include .c and .h files in the current directory, meaning when you add new code files to your directory, you won't have to update the Makefile. However, if you want to change the name of the generated executable, libraries, or compiler flags, you can just modify the variables.
In either case, don't use autoconf, please. I'm begging you! :)
For example this simple Makefile should be sufficient:
CC=gcc
CFLAGS=-Wall
all: program
program: program.o
program.o: program.c program.h headers.h
clean:
rm -f program program.o
run: program
./program
Note there must be <tab> on the next line after clean and run, not spaces.
UPDATE Comments below applied
all: program
program.o: program.h headers.h
is enough. the rest is implicit
The simplest make file can be
all : test
test : test.o
gcc -o test test.o
test.o : test.c
gcc -c test.c
clean :
rm test *.o
Depending on the number of headers and your development habits, you may want to investigate gccmakedep. This program examines your current directory and adds to the end of the makefile the header dependencies for each .c/cpp file. This is overkill when you have 2 headers and one program file. However, if you have 5+ little test programs and you are editing one of 10 headers, you can then trust make to rebuild exactly those programs which were changed by your modifications.

Resources