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

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 "$<")")

Related

Makefile link issue

I can't figure out how link static libraries in Makefiles. I use ubuntu 20.04 LTS. I even tried to use direct path to these libraries, and the issue remains unchanged. Here's my Makefile code.
LIB = libgeoms.a
SRC = mlx_pxl_put.c \
std_arc.c \
std_crcl.c \
std_line.c \
std_poly.c \
std_rect.c \
CC = clang
WARNS = -Wall -Wextra -Werror
OBJ = $(SRC:.c=.o)
SRCP = /usr/local/wealdboar/src/
INCLUDEP = /usr/local/wealdboar/include/
LIBP = /usr/local/wealdboar/lib/
HEADER = geoms.h
LX11P = /usr/lib/x86_64-linux-gnu/libX11.a
LXEXTP = /usr/lib/x86_64-linux-gnu/libXext.a
LMLX = /usr/local/lib/libmlx.a
$(LIB): $(OBJ)
#echo "Every funtion is compile proved ..."
#ar rcs $(LIB) $(OBJ)
#echo "All functions added to static lib ..."
$(OBJ): %.o :%.c
#echo "check $< to be right"
#$(CC) $(WARNS) -c $(LX11P) $(LMLX) $(LXEXTP) $< -o $#
all: $(LIB)
clean:
#echo "removing all binaries ..."
#rm -rf $(OBJ)
fclean: clean
#echo "removing static library ..."
#rm -rf $(LIB)
re: fclean all
install: re clean
#echo "coping $(LIB) to $(LIBP)"
#sudo cp $(LIB) $(LIBP)
#echo "coping sources to $(SRCP)"
#sudo cp $(SRC) $(SRCP)
#echo "coping header to $(INCLUDEP)"
#sudo cp $(HEADER) $(INCLUDEP)
Issue image
You haven't specified the -l or -L flags to tell clang to link against choosen libraries.
First please don't paste image links in StackOverflow. They aren't searchable, they aren't quotable, and many people are not willing to click a on links to other sites. Please cut and paste the actual messages.
Second, when working with makefiles you should not use the # option which hides the most important information about the commands being run. It's much harder to debug a makefile when the command lines are not visible. If you really want to hide the actual commands you should either add in the # after everything is already working and not before, or else use tricks like this to allow for a debug mode.
Finally your error is as I suggested in my comment above. You are trying to add static libraries to a compile command (a command that compiles source files into object files). Libraries can only be added into link commands (commands that convert object files and libraries into executables).
You are not actually creating an executable anywhere in your makefile that I can see, so there's nowhere that you can add libraries here. But, you need to remove them from the compile rule:
$(OBJ): %.o :%.c
#echo "check $< to be right"
#$(CC) $(WARNS) -c $< -o $#

'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).

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

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.

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

Resources