I want to compile all files in my directory i wrote
find *.c | gcc -o * *.c
but it dosent work
Help pliz
Well, if every is a main:
#!/usr/bin/ksh
for f in *.c
do
gcc -o ${f%.c} $f
done
If they are all subroutines but one with a main, use this:
gcc -c *.c
ar all.a *.o
gcc -o my_name all.a
Not sure at all about the ar command line being correct, just a hint. Subroutine order in a *.a is not important like on a cc/link, so linking from all.a always works. Since it is an ar from scratch, you want the anti-quadratic option!
Does gcc even take piped input? I don't think I've ever seen any compiler used that way.
What are you trying to accomplish? Compile a bunch of C files into one executable? There's an even simpler way than the examples DGPickett provided:
gcc *.c -o yourBinaryFileName
The "*.c" argument is expanded by your shell to every file in your current directory that ends in ".c", no matter what it begins with (as long as it doesn't start with a "." character, anyway), and the "-o" argument tells gcc that the next argument is the name of the file it's to use to write its output to.
What about using Makefile(s) ?
Cheers, Lo�c
Make is great, except nobody seems to keep it clean enough to work right, and so has to purge and build from scratch all the time, or has n different versions of the same source file in production. I noticed in Ant they said don't bother, just make it all again. Of course, it is nice if you can do that quickly, like in parallel, but with clean logging and error handling, so you can tell if it ran, and if not, why not, and where.
---------- Post updated at 03:43 PM ---------- Previous update was at 01:19 PM ----------
PS: If the files are subroutines but one or no mains, and you compile them all at once, some compilers can optimize between files, like inlining.
That might be a good down-to-earth comment for many SW-development teams... But with such an answer, you won't get any vacancy in my team
*LOL*
Cheers, Lo�c
I have made my living cleaning up make files, an endless task, even with the cc support and even with dynamic libs. I used to run all prod through a what script to see the multiple versions installed. However, many make a good living chasing this butterfly!
you did not specify if you want to compile them into a single program, into separate programs, into objects files (into a library, ...), so i'm making some random examples...
you do not need a pipe in any case... just, assuming you want to compile them into a single program:
gcc -o foo *.c
will; do fine...
this is wrong on so many levels...
first, your usage of 'find' is pointless...
*.c will be expanded by the shell, and the list of matches will be passed to find, which will just print them.
(unless you have a directory matching *.c, which will have it's contents recursively printed)
the correct syntax for find would be:
find . -type f -name '*.c'
which will recursively print the paths to all .c files.
secondly, you are trying to pipe fileNAMES into gcc... gcc never reads fileNAMES from anywhere but it's command line arguments...
there is a program that will conveniently take data from stdin and put it into commandline arguments, which is commonly used in such a situation:
find . -type f -name '*.c' | xargs --no-run-if-empty gcc -o /tmp/test
that will compile all your C files, (assuming exactly one of them contains a main function, and there are no other conflicts between them) into /tmp/test
(beware that there is a limit of the length of commandlines, if you had too many files, xargs would invoke gcc multiple times, overwriting the previous output file)
if you want to compile each file into a separate output file, you will need one gcc invokation per file.
(i don't think it has a mode where it will generate output object files in one run).
a fix of your example in that direction could be: assuming they are standalone programs:
for f in *.c ; do gcc -o "${f%.c}" "$f" ; done
assuming they are modules to be linked together later:
for f in *.c ; do gcc -c "$f" ;done
or, recursively:
find . -type f -name "*.c" | xargs --no-run-if-empty -n 1 gcc -c
(-n1 has xargs call gcc on batches of one file each)
that said, gcc WILL happily compile input files read from stdin:
(note that you have to specify the input filetype using -x, as it's normally guessed from the file extension)
echo -e '#include \nint main(void){printf("%s\\n","Hello World!");return 0;}' | gcc -o /tmp/test -xc - && /tmp/test Hello World!
or, for your case, assuming you want a single output program:
cat *.c | gcc -o program -xc -
If each dir contains a group of c files but one mail, you can compile -c all in that dir, put them in a .a archive using ar, and compile the *.a into an executable without worrying about order on the command line.
I was thinking of writing a main that calls ld() to find a subroutine named like argv[0], so one main could support all executables from dynamic libraries without ever being recompiled. I guess in c++ it would have to worry about mangling.
- order on the command line is irrelevant to begin with, you can always compile and link all your source files in one step
(just if you try that on large projects, the compiler's memory usage will go through the roof) - also generating a .a static library in between is unnecessary, you could pass gcc the object files directly (and order is, again, irrelevant)
in case of nonbelievers:
$ cat >foo.c
int foo(void){return 34;}
$ cat >main.c
int main(void){return foo();}
$ gcc -o test foo.c main.c && { ./test ; echo $?; }
34
$ gcc -o test main.c foo.c && { ./test ; echo $?; }
34
A couple of simpler, portable, find-only alternatives to the suggested find-xargs pipelines:
find . -type f -name '*.c' -exec gcc -o /tmp/test {} +
find . -type f -name '*.c' -exec gcc -c {} \;
Regards,
Alister
note that the topic was "gcc _with_pipes_"... the main reason to include the xargs examples was to get filenames from a pipe into gcc.... ![]()
granted, -exec + is more elegant than xargs (and its in posix, says the manpage).
using xargs for building a single binary (the -o case) is a really bad idea anyway, as it will break in funny ways if you have too many files...
also, removing the --no-run-if will get you an error if there are no .c files to compile... (a rather useful gnu extension... at least gcc prints a reasonable error message for the empty argument list case - most programs resort to their help text, which causes confusion and/or havoc, depending on the text ending up on the terminal or in a pipe to another program)
xargs -n is quite definitely POSIX. The find + syntax, while also POSIX, is rather new POSIX, there's many modern implementations that don't support it yet.
find/exec will definitely deal with newlines and spaces in filenames better than xargs will unless you use the GNU --null extensions...
Anything will break in funny ways if you have too many files, -exec + included: find has no magical way to cram in more arguments than the system allows, it splits too.
I think that's the point you'd have to break your code into sub-libraries, shoehorn the resulting .o's into single .a's for each library, then link together individual a's instead of mountains of o's.
---------- Post updated at 02:08 PM ---------- Previous update was at 01:56 PM ----------
That's quite true with gcc but it depends on the compiler. Some are more picky about library ordering.