Create multple object files at once without using a makefile? - gcc

When I try
gcc -c *.c
I get an invalid argument error, and it says no input files.

If you run gcc from a directory where no C source files are present, gcc will receive the *.c argument unexpanded, will try to open a file named *.c and fail, will report this failure and in the absence of further arguments, will complain about the missing input files:
$ gcc -c *.c
gcc: error: *.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.
$
The wildcard expansion is performed by the command line interpreter, aka the shell. On a unix system, there are many different shells, sh, csh, tcsh, bash, zsh... all of which expand unquoted wildcards before running the commands. On Windows, the default shells do not expand wildcards for external commands, some programs do it on their own, but most don't. If you run bash on Windows, with or without cygwin, you will get the Unix behavior, but if you run cmd.exe, you won't.
MinGW is a set of development tools to make Windows native executables. It does not provide a shell and favors using the native libraries and utilities when possible. This is the reason why your command gcc -c *.c does not undergo wildcard expansion on your machine. Install bash or cygwin for a more unix-friendly environment.

This should do what you're looking for.
find . -name '*.c' -print | xargs gcc -c

Related

MinGW Makefile is looking in c:\windows\system32 instead of /usr/bin

The following Makefile:
.PHONY: all
all: $(shell find example/data)
#echo $(shell which find)
When run with gnuwin32 Make in a MinGW bash shell, outputs the following:
$ make
FIND: Parameter format not correct
/usr/bin/find
This output is strange because the "FIND: Parameter format not correct" message comes from Windows' find.exe in C:\Windows\system32.
This means that:
$(shell find example/data) is using C:\Windows\system32\find.exe, even though
$(shell which find) identifies /usr/bin/find (the GNU find)
My question is: What is going on here? Why would $(shell find ...) be looking in C:\Windows\system32 instead of in /usr/bin? Why isn't the path consistent and what can I do to make $(shell find ...) behave the same way that find ... would behave from the MinGW bash shell?
I do not want to hard code the path to find; and I could probably get what I want by using which to find the path but I'm more concerned with the path being incorrect than I am about specifically getting find to work here.
When you say "MinGW bash shell" I assume you mean an MSYS/MSYS2 bash shell.
MSYS and MSYS2 provide a Unix/Linux-like shell, and some commands may exist in Unix/Linux with the same name as different commands in Windows.
The find is such a command.
There are several solutions to your problem:
Use the where command instead (your Makefile will be compatible with other platforms).
Specify the full path to the command you want to use. You could detect it with FINDCMD=$(shell which find) and then run it with $(shell $(FINDCMD) example/data)

Force CMake to generate zsh friendly command lines

I have a CMake such that when I executed the build (make) in verbose mode, it prints commands such as:
/usr/bin/nvcc -forward-unknown-to-host-compiler -DBOOST_ALL_NO_LIB -DBOOST_CHRONO_DYN_LINK -DBOOST_PP_VARIADICS -DBOOST_TIMER_DYN_LINK -DBOOST_UNIT_TEST_FRAMEWORK_DYN_LINK --expt-relaxed-constexpr --extended-lambda -Xcudafe "--display_error_number --diag_suppress=implicit_return_from_non_void_function --diag_suppress=class_and_member_name_conflict" --generate-code=arch=compute_61,code=[compute_61,sm_61] -std=c++17 -x cu -c /home/correaa/prj/alf/boost/multi/adaptors/thrust/test/array.cu -o CMakeFiles/array.cu.x.dir/array.cu.o
presumably, this is a bash-compatible command because I have no problem running it in bash.
However it is not a valid zsh command (the shell I use) because it gives an error:
zsh: no matches found: --generate-code=arch=compute_61,code=[compute_61,sm_61]
I presume it is the square brackets that trip zsh [...].
First question is how can I correct manually this command to run on both zsh and bash?
Second question is, is there a way to for CMake to generate makefiles that contain commands that are compatible with zsh?

About the meaning of "./a" in gcc

When I run
$ gcc hello.c
$ ./a
Hello, World.
I don't know what ./a exactly indicates.
What is it? What does it stand for?
If you know the meaning of it, I'd really appreciate that you would share.
./ is the current directory when using a Unix-like shell (like bash.) The name of the executable GCC produces is a.exe.
So to run the produced executable, you need to specify the path to to it, in this case "the current directory", which is ./, and the name of the executable, which is a.exe. Since you can omit the .exe when running executables on Windows, instead of ./a.exe you can just run it with ./a.
If you were to use the Windows command-line shell (like cmd.exe or PowerShell) you would instead just type a, because the current directory (.\ in this case, Windows uses \ instead of / for the directory separator character) is searched for executables by default. Unix shells do not, which is why you need ./.
If you want to give the produced executable a different name, for example hello.exe, you can:
gcc hello.c -o hello.exe
You would then run that with:
./hello
or:
./hello.exe
.a is the standard/default output of the compiled program, when no output name is provided.
When you've compiled C program and given no name to the output file, gcc will automatically set the output file name as a.
The file name is overwritten for the last compiled C program, when no output name is provided.
This standard is same in both Unix and Windows.
To set name for the output program, Use -o argument followed by the output name sum_program
gcc sum_program.c -o sum_program
Depending on the library use, and other linkers, additional arguments like -o can be added for compilation.

gmake using sh.exe causes build errors

I have a makefile that works on a Windows system when sh.exe is not on path. But when sh.exe is on Windows path, it stops with an error. Apparently, sh.exe can not handle paths with mixed / and \ such as this one:
cc $CFLAGS) C:\a\b/c/d/myfile.c
it generates the following error
Fatal error: could not open source file "c:ab/c/d/myfile.c"
As I am not able to change the makefile (it is auto generated by some application), how can I force gmake not to use sh.exe or force sh.exe to accept such files?
Try gmake SHELL="cmd". See the GNU make docs for more information. In particular, note this tidbit:
Note that this extended search for the shell is limited to the cases
where SHELL is set from the Makefile; if it is set in the environment
or command line, you are expected to set it to the full pathname of
the shell, exactly as things are on Unix.

How does gnu-make deal with quotes in the makefile if called in cmd.exe?

I have a c source file to which I want to pass a quoted macro via gcc's -D
command line flag. (See also How do I pass a quoted string with -D to gcc in cmd.exe?). And I am working in cmd.exe.
It's possible to compile the program directly like so:
c:\MinGW\bin\gcc.exe -DDEFINED_STRING="\"foo bar baz\"" foo.c -o foo.exe
But if I create a makefile with the following content
foo.exe: foo.c
c:\MinGW\bin\gcc.exe -DDEFINED_STRING="\"foo bar baz\"" foo.c -o foo.exe
and then execute a make, gnu's make will try to invoke /bin/sh and the backslashes of the path to gcc.exe dissapear:
gcc-4.7.0/gcc/config/avr -c c:/temp/gcc-4.7.0/gcc/gcc.c -o o/gcc/gcc.o
/bin/sh: c:MinGWbing++.exe: command not found
make: *** [o/gcc/gcc.o] Error 127
Stragnly enough, this doesn't happen when I use -DDEFINED_STRING=foo (that is: without quotes).
make -v prints GNU Make 3.81
Making in a Windows environment has many nuances. In this case, it looks like you just need to escape your backslashes like so:
foo.exe: foo.c
c:\\MinGW\\bin\\gcc.exe -DDEFINED_STRING="\"foo bar baz\"" foo.c -o foo.exe
Alternatively, switch them to forward slashes or the preferred /cygdrive/c style. As a side note, I seem to recall that Windows style filenames are no longer supported in dependencies as of Make 3.81.
You might also want to set the SHELL variable and review some of the caveats mentioned in the manual and in the NEWS file included in the source tarball.

Resources