Gcc with pipe


 
Thread Tools Search this Thread
Top Forums Programming Gcc with pipe
# 8  
Old 03-01-2011
Quote:
Originally Posted by rzili
I want to compile all files in my directory
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:
Code:
 gcc -o foo *.c

will; do fine...
Quote:
Originally Posted by rzili
Code:
find *.c | gcc -o * *.c

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:
Code:
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:
Code:
 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:
Code:
 for f in *.c ; do gcc -o "${f%.c}" "$f" ; done

assuming they are modules to be linked together later:
Code:
 for f in *.c ; do gcc -c "$f" ;done

or, recursively:
Code:
 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)
Code:
 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:
Code:
 cat *.c | gcc -o program -xc -

# 9  
Old 03-01-2011
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.
# 10  
Old 03-01-2011
Quote:
Originally Posted by DGPickett
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.
  • 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:
Code:
$ 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


Last edited by r00t^; 03-01-2011 at 01:15 PM.. Reason: fix quotation
# 11  
Old 03-01-2011
A couple of simpler, portable, find-only alternatives to the suggested find-xargs pipelines:

Quote:
Originally Posted by r00t^
Code:
 find . -type f -name '*.c' | xargs --no-run-if-empty gcc -o /tmp/test

Code:
find . -type f -name '*.c' -exec gcc -o /tmp/test {} +

Quote:
Originally Posted by r00t^
Code:
 find . -type f -name "*.c" | xargs --no-run-if-empty -n 1 gcc -c

Code:
find . -type f -name '*.c' -exec gcc -c {} \;

Regards,
Alister
# 12  
Old 03-01-2011
Quote:
Originally Posted by alister
A couple of simpler, portable, find-only alternatives to the suggested find-xargs pipelines:
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.... Smilie
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)

Last edited by r00t^; 03-01-2011 at 03:17 PM.. Reason: fix tags
# 13  
Old 03-01-2011
Quote:
Originally Posted by r00t^
granted, -exec + is more elegant than xargs (and its in posix, says the manpage).
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...
Quote:
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...
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 ----------

Quote:
Originally Posted by r00t^
Order on the command line is irrelevant to begin with, you can always compile and link all your source files in one step
That's quite true with gcc but it depends on the compiler. Some are more picky about library ordering.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

How to ignore Pipe in Pipe delimited file?

Hi guys, I need to know how i can ignore Pipe '|' if Pipe is coming as a column in Pipe delimited file for eg: file 1: xx|yy|"xyz|zzz"|zzz|12... using below awk command awk 'BEGIN {FS=OFS="|" } print $3 i would get xyz But i want as : xyz|zzz to consider as whole column... (13 Replies)
Discussion started by: rohit_shinez
13 Replies

2. Linux

Problems with gcc

Hello I'm not able to install gcc. My platform is # uname -a Linux localhost 2.6.18-194.el5 #1 SMP Fri Apr 2 14:58:14 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux #yum install gcc I got the following error ---> Package libgfortran44.x86_64 0:4.4.4-13.el5 set to be updated ---> Package... (2 Replies)
Discussion started by: My Style
2 Replies

3. Shell Programming and Scripting

Replace pipe with Broken Pipe

Hi All , Is there any way to replace the pipe ( | ) with the broken pipe (0xA6) in unix (1 Reply)
Discussion started by: saj
1 Replies

4. UNIX for Dummies Questions & Answers

What is the difference between GCC and CC?

Can anyone briefly tell me the difference between CC and GCC? Thanks! (1 Reply)
Discussion started by: andrewust
1 Replies

5. UNIX for Dummies Questions & Answers

Help with gcc and g++

Hi, I have recently got a job in unix, now training is going on and we have been practicing on telnet, so to practice at home I have installed vmware(virtual machine) and planning to download ubuntu. So my doubt is that whether I can write c and cpp progs in vi editor and can I run them by default... (5 Replies)
Discussion started by: vishal.973s
5 Replies

6. Programming

gcc compiler

Which gcc compiler release had the Arm 9 multicore support?Whether the compiler that used for the single Arm 9 core can be used for its multicore systems ? If gcc not support,please tell me which are the compilers that are available for Arm 9 multicore systems (including commerical).Whether... (0 Replies)
Discussion started by: sujith4u87
0 Replies

7. AIX

Gcc for AIX

Hi, I am working with AIX5.3 and I downloaded the gcc-4.2.4.tar.bz2 from the site and when I am trying to un-tar it.It is throwing error-- Please help me to resolve it. Thanks in Advance.. (6 Replies)
Discussion started by: smartgupta
6 Replies

8. Solaris

Installing gcc - recieve error message gcc : cannot execute

AIM- Install Oracle 11g on Solaris using VMWare Steps 1.Logged on as root 2.Created subfolders à /usr/local/bin & /usr/local/bin/gcc 3.Downloaded gcc & libiconv & unzipped them on my harddrive & burnt them on CD 4.Copied files from CD to /usr/local/bin/gcc 5.Terminal (root) à pkgadd -d... (8 Replies)
Discussion started by: Ackers
8 Replies

9. Programming

Gcc

Dear all, Any body please guide, i require a C which will run in Linux environment. Its urgent please. warm regards, Senthil K (1 Reply)
Discussion started by: Senthil
1 Replies

10. Programming

gcc update

Hai Friends How should i update gcc (version 3.2.1) to gcc (version 3.2.2). I am using FreeBSD 5.0 RELEASE Thanks in advance Collins (0 Replies)
Discussion started by: collins
0 Replies
Login or Register to Ask a Question