Escaping spaces in LIBS path Makefile - c

I'm trying to include Eclipse Mosquitto library sample mosquitto example from here
I'm trying to use a Makefile to build and compile the code.
I'm facing an issue where the compiler/linker/whatsoever cannot find the mosquitto library located at C:\Program Files\Mosquitto\devel.
Here's the error:
mqtt-hostlink> make
gcc -Wall -o main main.c -LC:\\Program ,_,Files\\Mosquitto\\devel\mosquitto.lib
gcc: error: ,_,Files\Mosquitto\devel\mosquitto.lib: No such file or directory
make: *** [Makefile:11: make] Error 1
Here's my Makefile:
CC = gcc
null :=
SPACE := $(null) $(null)
LIBS = -LC:\\Program$(SPACE),_,Files\\Mosquitto\\devel\mosquitto.lib
%.o: %.c
$(CC) -c -o $# $<
make: main.c
$(CC) -Wall -o main $^ $(LIBS)
.PHONY: clean
The "space" method I referred from : How to escape spaces inside a Makefile

You can just use the short name for tar directory. List the directories with /X option as below
C:\>dir /X p*
Directory of C:\
09/06/2021 02:24 PM <DIR> PROGRA~1 Program Files
09/06/2021 01:29 PM <DIR> PROGRA~2 Program Files (x86)
0 File(s) 0 bytes
Then just use PROGRA~1 instead of Program Files

There's some confusion here. That post is about how to escape spaces from make functions. You are not trying to invoke any make functions here, you are just trying to use a variable in a command line. There's no need to escape anything from make.
What you need to do is escape the spaces from the shell, not from make. You can do that easily, just using quotes. No need for fancy make operations. I recommend you also use forward-slashes, not backslashes. Almost all Windows programs accept both forward and backslashes. Only cmd.exe built-ins don't.
LIBS = "-LC:/Program Files/Mosquitto/devel/mosquitto.lib"

Related

ming32-make.exe incorrect parsing of -I and -L flags

I'm on a Windows machine and use MinGW, attempting to compile a hello world program that uses a shared library. After an absurd amount of attempts, I found out the following:
Manually compiling it with gcc and providing -I and -L flags for the required directories works fine.
Using the msys make.exe file provided under the MinGW/msys/1.0/bin installation directory properly executes a Makefile with no problems
Using the mingw32-make.exe provided under MinGW/bin doesn't work properly when trying to build using the same Makefile. From my understanding, it doesn't parse the -I and -L flags at all. It works fine if I add the dependencies (both includes and libs) under their respective MinGW directories.
These past few days while I was trying and familiarizing myself with these tools (I'm comfortable with C's syntax but know about nothing past that) I read many guides and no one seemed to have this issue (from the few that actually attempted this on a Windows machine without using an IDE). Did I miss something? Is my MinGW installation known to have this issue?
Note that at first I was attempting to compile the project using the 64-bit version of the library but failed. I'm guessing this means that I have a 32-bit MinGW installation.
Knowing that some will ask to see the Makefile:
CC = gcc
MY_LIB = -L/e/C_Projects/Libraries/MySharedLib/lib -lMyLibName
MY_INCLUDE = -I/e/C_Projects/Libraries/MySharedLib/include
CFLAGS = -Wall -c $(MY_INCLUDE)
LDFLAGS = -lmingw32 -mwindows $(MY_LIB)
EXE = Test.exe
all: $(EXE)
$(EXE): main.o
$(CC) $< $(LDFLAGS) -o $#
main.o: main.c
$(CC) $(CFLAGS) $< -o $#
clean:
del *.o && del $(EXE)
The error produced by mingw32-make.exe is the following
main.c:1:22: fatal error: MyLib.h: No such file or directory
#include <MyLib.h>
^
compilation terminated.
Makefile:19: recipe for target 'main.o' failed
mingw32-make: *** [main.o] Error 1

C actualize files through makefile all at once

I am working on project, where i use couple of .c and .h files.
I created Makefile where i actualize executable program based on changes in all of these files.
Problem is, when i use make, program is compiled, but when i execute program, it runs without any change. I need to save ( working in vim so :w ) all included files, even when i changed only one.
If i don't save all these files, program is compiled, but executes the same thing as it did before change.
Could someone explain me why is that ?
Makefile code :
CC=gcc
CFLAGS=-WALL
execFile: execFile.o functions.h newDataTypes.h
Thank you.
The reason you are not getting execFile updated is because you're NOT updating it. Or at least you don't seem to be in this particular case.
There are many ways to get about doing this. However since you are using gcc and I assume you're using gnu make the following is probably the best solution you can execute1.
Given the files:
-rw-r--r-- 1 user sudo 73 Nov 4 22:54 exeFile.c
-rw-r--r-- 1 user sudo 74 Nov 4 22:54 exeFile.h
-rw-r--r-- 1 user sudo 90 Nov 4 22:55 hello_world.c
-rw-r--r-- 1 user sudo 888 Nov 4 23:03 Makefile
cat exeFile.c
#include <stdio.h>
#include "exeFile.h"
int main()
{
hello_world();
}
exeFile.h
#ifndef _EXEFILE_H
#define _EXEFILE_H
extern void hello_world();
#endif
hello_world.c
#include <stdio.h>
#include "exeFile.h"
void hello_world()
{
printf("Hello World\n");
}
you can set up a make file that generates dependencies and ensures that the program will always be compiled correctly:
CC=gcc
CFLAGS=-Wall
SOURCES=exeFile.c hello_world.c
EXE=exeFile
OBJ=$(SOURCES:%.c=%.o)
DEPDIR := .deps
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $# -MMD -MP -MF $(DEPDIR)/$*.Td
COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
COMPILE.cc = $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
POSTCOMPILE = #mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $#
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(COMPILE.c) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
%.o : %.cc
%.o : %.cc $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
%.o : %.cxx
%.o : %.cxx $(DEPDIR)/%.d
$(COMPILE.cc) $(OUTPUT_OPTION) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
$(EXE): $(OBJ)
$(CC) -o $# $(OBJ) $(LDFLAGS)
clean:
$(RM) $(OBJ) $(EXE)
dev-clean: clean
$(RM) -r $(DEPDIR)
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
Let's go over the relevant parts about dependencies
DEPDIR =
This implementation places dependency files into a subdirectory named .deps .
$(shell mkdir -p $(DEPDIR) 2>/dev/null)
GCC does not create subdirectories for output, this line ensures that the DEPDIR directory always exists.
DEPFLAGS = ...
These are GCC-specific flags which tell the compiler to generate dependency info.
-MT $#
Set the name of the target in the generated dependency file.
-MMD
Generate dependency information in addition to compiling. -MMD omits system headers from the generated dependencies: if you prefer to preserve system headers as prerequisites, use -MD instead.
-MP
Adds a make target for each prerequisite in the list, this avoids errors when deleting files.
-MF $(DEPDIR)/$*.Td
Write the generated dependency file to a temporary file $(DEPDIR)/$*.Td e.g. hello_world.c will generate hello_world.Td as temp dependency content for use in Makefile.
POSTCOMPILE = ...
First rename the generated temporary dependency file to the real dependency file. We do this in a separate step to side-step compile errors. Next we explicitly touch the files to avoid a gcc bug.
%.o : %.c
Delete the built-in rules for building object files from .c files, so that our rule is used instead. Do the same for the other built-in rules.
... $(DEPDIR)/%.d
Declare the generated dependency file as a prerequisite of the target, so that if it’s missing the target will be rebuilt.
$(DEPDIR)/%.d: ;
Create a pattern rule with an empty recipe, so that make won’t fail if the dependency file doesn’t exist.
.PRECIOUS: $(DEPDIR)/%.d
Mark the dependency files precious to make, so they won’t be automatically deleted as intermediate files.
include ...
Include the dependency files that exist: translate each file listed in SOURCES into its dependency file. Use wildcard to avoid failing on non-existent files.
1 See Auto-Dependencies Generation for details.
Fix:
Tell make that the executable depends only on the object file and the object file depends on the header files:
execFile: execFile.o
execFile.o: functions.h newDataTypes.h
Explanation:
In order to build your executable two steps are needed:
compilation of C source files (that include header files) to produce object files,
linking of the object files to produce the executable.
So, when changing your header files you must re-compile, that is re-built the object files, not just re-link that would produce the same executable from the same object files.
In your Makefile the dependencies are not properly defined. You did not tell make that the object file (execFile.o) shall be rebuilt when your header files change. Instead, you told it that the executable (execFile) shall be rebuilt.
First of all, your dependencies are mistaken. Your executable does not depend on the .h header files, as they are using only at compilation time. The dependencies are normally between .o files and .h files, as when you modify one .h file, the including .c file must be compiled to generate the .o file. so in case you have execFile.o (which, on lack of complete information, I'll suppose it depends on execFile.c, which #includes functions.h and newDataTypes.h, the rule should be:
execFile.o: execFile.c functions.h newDataTypes.h
As it has been pointed out in other responses, there's no need to write the command to build the .o file, as there is a default rule like this:
.c.o:
$(CC) $(CFLAGS) -o $# -c $<
(observe there's a -c option to the compiler indicating to compile only and don't link, we'll return here below) which means that once you detect the .o is outdated (as the dependencies on .c and .hs mark) it will be compiled with the above command, which result in:
gcc -Wall -o execFile.o -c execFile.c
making the appropiate compilation.
Other thing is the dependencies of the executable file. These have to be included, as make(1) doesn't know which object files form your final executable. In this case, assuming you have your program execFile depend on execFile.o and a.o, b.o and c.o, I normally use to write:
execFile_objs = execFile.o a.o b.o c.o
execFile: $(execFile_objs)
$(CC) $(LDFLAGS) -o $# $(execFile_objs)
so any of the .os is changed (because an indirect change in a source file) the whole program is linked again (but only the touched files are compiled)
NOTE
In the case (not normal) that you have a Makefile to create a program that has only one source file and several include files you can compile each time the whole thing each time you modify one source file, in this way:
execFile: execFile.c functions.h newDataTypes.h
$(CC) $(CFLAGS) $(LDFLAGS) -o $# execFile.c
This will execute
gcc -Wall -o execFile execFile.c
Observe that there is no -c (compile only, don't link) option in this command.
There's no mention of the include files (they are included because of the #include directives in the code... and you only state here that the executable depends also (and have to be built) in case any of the .h files are modified.
Automatic dependency rules are a little confusing at first, as they induce you to think there are such rules to make any kind of file from any other kind of file (well, there are for .c -> .o files, and .c -> <nothing> to compile directly to an executable) normally you have to include dependencies in such cases when your target depends on more files than the automatic rule states. In such cases, it is very important not to include any command, so the compiler selects the automatic rule (when you don't include a command to generate the target, the make(1) program tries to use a default rule for it, or nothing at all if you have not included commands, it only assumes your dependencies are indirect through this fake target --- and, as this fake target is not built in the process, it will fail always and be followed)

What is Eclipse CDT is doing with 'make' under the hood

I'm on Windows 7 and have MinGW/gcc installed. I'm using the Eclipse CDT plugin to compile and build my first simple C programs, and am trying to follow what exactly the plugin is doing under the hood.
I create a new "Hello World!" C project with the following directory structure:
helloworld/
src/
helloworld.c
Where helloworld.c is:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("Hello World!");
return EXIT_SUCCESS;
}
So I created a Run Configuration in Debug Mode (as opposed to "Release Mode", not a "Debug Configuration" in typical Eclipse parlance!) and ran my app, and it works beautifully, printing "Hello World!" to the Eclipse console.
Now I'm looking on my file system and the file/project structure is like so:
helloworld/
src/
helloworld.c
Debug/
src/
helloworld.d
helloworld.o
subdir.mk
helloworld.exe
makefile
objects.mk
source.mk
I assume that running my Run Configuration in Eclipse (hence compiling/building/running helloworld inside Eclipse) created everything under Debug. Furthermore I assume that helloworld.d and helloworld.o are compiled binaries, and that helloworld.exe is the packaged executable containing those binaries and everything they'red linked to (stdio and stdlib). I also assume makefile is the actual Make file (buildscript), and that the *.mk files are somehow inputs to that buildscript. So, for starters, if any of those assumptions are wrong, please begin by correcting me!
When I open makefile I see this:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include src/subdir.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: helloworld
# Tool invocations
helloworld: $(OBJS) $(USER_OBJS)
#echo 'Building target: $#'
#echo 'Invoking: Cross GCC Linker'
gcc -o "helloworld" $(OBJS) $(USER_OBJS) $(LIBS)
#echo 'Finished building target: $#'
#echo ' '
# Other Targets
clean:
-$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) helloworld
-#echo ' '
.PHONY: all clean dependents
.SECONDARY:
-include ../makefile.targets
Please note: I am not looking for someone to explain to me how Make works, I can RTFM for that ;-)
I am just trying to understand what it would take to compile, build and run helloworld from the command-line, outside of Eclipse. What command line invocations would I need to accomplish this, and why? Once I see that, combined with perusing Make docs, I should be able to fill in the gaps and understand everything that is going on.
That depends a bit on the paths that Eclipse generates in the files source.mk and objects.mk but most likely you need to cd into the Debug folder.
Inside of that, you can then run make all to compile the project.
If Eclipse generated absolute paths, you can use make -f .../path/to/helloworld/Debug/makefile all from anywhere.
The *.o files are the object file(s) created by compilation. these files are typically build by a command like:
Gcc -ansi -Wall -pedantic -c helloworld.c -o helloworld.o
(apologies foe capitalization of gcc, my iPad insists on correct my typing)
The *.exe is the actual executable, which may or may not contain the library functions. This depends on static versus dynamic linking. The executable is created typically by:
Gcc helloworld.o -o helloworld.exe
The *.d files are dependency files, built by gcc attempting to determine dependencies between files, typically built with the following command
MAKEDEPEND = gcc -M $(CPPFLAGS) -o $*.d $<
(Rule taken from make online documentation).
So,to answer your final question, to compile from the command line, a command like:
Foo gcc -ansi -WAll -pedantic helloworld.c -o helloworld.exe
Should do the trick for you. Note, the flags to the compiler are the minimum that I like to use, you will probably have a different set of switches.
Hopes this help,
T

Unable to understand the errors given by running make

My directory structure is /home/akshayaj/Desktop/System Programs/dictionary/
Inside dictionary I have 3 files:
libdictionary.c (implements all the functions except main),
libentrypoint.c (contains main()),
libdictionary.h (contains declaration of all the functions)
Both C files include the header file
Now I wrote a make file for the above project. It goes like this:-
CFLAGS=-I /home/akshayaj/Desktop/System Programs/dictionary/
libdict: libentrypoint.o libdictionary.o
cc $(CFLAGS) -o libdict libentrypoint.o libdictionary.o
libentrypoint.o: libentrypoint.c libdictionary.h
cc $(CFLAGS) -c libentrypoint.c
libdictionary.o: libdictionary.c libdictionary.h
cc $(CFLAGS) -c libdictionary.c
Now when I ran it, I got these errors:-
cc -I /home/akshayaj/Desktop/System Programs/dictionary/ -c libentrypoint.c
cc: error: Programs/dictionary/: No such file or directory
make: *** [libentrypoint.o] Error 1
Where am I going wrong?
Note:- In CFLAGS I have given the whole path because I saw it in a similar question, but that didn't work. Here is the link to that question.
C Compile Error (No such file or directory, compilation terminated)
Try to use path /home/akshayaj/Desktop/System\ Programs/dictionary/, where \ handles the space.
Think about how that command line would be parsed...
cc -I /home/akshayaj/Desktop/System Programs/dictionary/ -c libentrypoint.c
^^ ^------------------------------^ ^------------------^ ^-----------------^
| | | |
Command -I arg BAD ARG -c arg
As you can see, the space between "System" and "Programs" is read as a separator between two command args.
Your options are either:
Change the path so that the space is removed (recommended). e.g. /home/akshayaj/Desktop/System-Programs/dictionary/.
Add a backslash before the space to escape it. e.g.:
/home/akshayaj/Desktop/System\ Programs/dictionary/
As a general rule, it's not wise to use paths with spaces in them when building stuff using make, or just building stuff in general. It makes ambiguities like this hard to solve.

Compile and link when dependent header file changed in other directory

I have 3 questions about compiling and linking my project in fewer steps...
First, my project looks like: ( I use Watcom C to compile//link my project )
Directory 'MyProject' contains 3 sub directories for different modules and some files:
directory 'A' ( a.h and a.c included )
directory 'B' ( b.h and b.c included )
directory 'C' ( c.h and c.c included )
my.c and my.h
my.lnk
makefile
And within each sub directory there is one corresponding makefile...
[Q1] Assume I update a.h in directory A and a.h is referenced by b.c in directory B, then my original steps will be:
compile in directory A ( obj and lib generated...)
compile in directory B ( obj and lib generated...)
back to directory MyProject then compile and link
Can I just take one step to cover above ?
[Q2] If I want to ignore all existing obj/lib and rebuild all, how to do it ?
I know this takes time but sometimes "kill and rebuild" will be better...
[Q3] If my.h is updated and it is referenced by a.c,b.c, and c.c...
Can I just take one step to cover above ?
[My makefile in sub directory looks like]
INCLUDE1 = -ic:\watcom\h
OBJECTS1 = a.obj
CFLAGS = -zq -mf -oxsbl $(INCLUDE1)
DEST = a.exe
COMPILER = wpp386
.erase # special cmd, tell wmake to "erase" target if make is not successful
.cpp.obj: .AUTODEPEND
$(COMPILER) $(CFLAGS) $<
$(DEST) : $(OBJECTS1) makefile
[My makefile in main directory looks like]
INCLUDE1 = -i=c:\myproj\my -i=c:\watcom\h
OBJECTS1 = my.obj
CFLAGS = -zq -fp6 -mf -6r -s -oxsbl $(INCLUDE1)
DEST = my.exe
COMPILER = wpp386
LINKER = wlink
LNK_FILE = my.lnk
.erase # special cmd, tell wmake to "erase" target if make is not successful
.cpp.obj: .AUTODEPEND
$(COMPILER) $(CFLAGS) $<
$(DEST) : $(OBJECTS1) makefile my.lnk
$(LINKER) #$(LNK_FILE)
[Update 1]
I use wpp386 as compiler and it is watcom c++ tool.
To build the target I use one batch file to compile cpp file:
#echo off
del a1.lib
del *.err
wmake -h
wlib -q a1.lib + a.obj
del *.obj
I can successfully compile cpp file and everything is fine.
In directory B, I use the same way(batch file+makefile) to compile b.cpp
To sum up my project works and the reason why I ask is to find "faster compiling/linking sequence" if I just update some header file...
I tried add the command ehco hello to the rule $(DEST) and found it was ok. Then use echo $(MAKE) and got:
...
echo C:\WATCOM\BINW\WMAKE.EXE
C:\WATCOM\BINW\WMAKE.EXE
...
Thanks !
I'm not familiar with your compiler, so I can't see how these makefiles work, so we'll have to take this one step at a time.
1) when you go into a subdirectory A, what command do you use to build the targets? Does it work? How about in subdirectory B?
2) In the main makefile, can you add a command, like echo hello to the $(DEST) rule? If that works, try echo $(MAKE).
EDIT:
Non-GNU versions of Make are troublesome, but we'll see what we can do.
Try editing the makefile in subdir A:
INCLUDE1 = -ic:\watcom\h
OBJECTS1 = a.obj
CFLAGS = -zq -mf -oxsbl $(INCLUDE1)
DEST = a1.lib # NOTE THIS CHANGE
COMPILER = wpp386
.erase # special cmd, tell wmake to "erase" target if make is not successful
.cpp.obj: .AUTODEPEND
$(COMPILER) $(CFLAGS) $<
$(DEST) : $(OBJECTS1) makefile
wlib -q $# + $(OBJECTS1)
del $(OBJECTS1)
Instead of the batch file, just run make -h. This should rebuild the library (if the library needs rebuilding). If it works, try moving up into MyProject and running make -h -C A. This should execute the makefile in A and rebuild the library there (unless WMAKE has some other syntax).
If that works, try making the same changes in B, then editing the $(DEST) rule in the main makefile:
$(DEST) : $(OBJECTS1) makefile my.lnk
$(MAKE) -h -C A
$(MAKE) -h -C B
$(LINKER) #$(LNK_FILE)
Cross your fingers and run make -h. This should rebuild both libraries, compile, link, and solve Q1...

Resources