I'm trying to use GCC in a shell script, but i want to use no input file, but a variable that contain my code.
For now I do :
echo '
#include <stdio.h>
int main(){
int a=1,b;
printf("Donnez un nombre : ");
scanf("%d", &b);
a+=b;
printf("test%d\n",a );
return 0;
}
' > .temp.c
#Entrez le texte ici
gcc .temp.c -o .ex -std=c99
Can I do something like gcc $inputCode -o executable ?
Moreover, if someone know if I can execute this c code without generating any file ?
Thanks !
You can do: echo whatever | gcc -x c -o .ex - but I hardly think it's worth it.
An alternate that may be cleaner [you don't have do either \" or \']. Note that the trap example may not be completely correct, but is probably something you're trying to achieve.
cat << EOF | gcc -x c -o .ex -
int
main(void)
{
return 'a';
}
EOF
trap "rm -f .ex" SIGINT
.ex
rm -f .ex
But, you're still going to have to create an output ELF executable file. Partly because the OS needs the embedded ELF loader (e.g. /lib64/ld-linux-x86-64.so.2) to know how to load the executable.
I've done the "script creates C executable from source" many times and I just create the .c and the executable and just do rm afterwards. I do this in perl where the C text appears after __DATA__ and I do an unlink function call instead of rm
Related
i have this simple code that accepts numbers from the standard input and print them , i wrote this code on code blocks and it works .. now i want to run the same code on eclipse and i don't know how it's supposed to work ? also after that i run it on eclipse i need to run it on bash where i have a directory that includes tests and i nee to check my code with these tests but i can't figure how to compile this c program there !
this is this is the simple code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
int i;
int k;
int a;
printf("Enter size of input:\n");
scanf("%d",&x);
if (x<0){
printf("Invalid size\n");
return 0;
}
int *numbers=malloc(sizeof(int)*x);
printf("Enter numbers:\n");
for(i=0;i<x;++i){
scanf("%d",&numbers[i]);
}
for(k=0;k<x;++k)
{
a=numbers[k];
printf("The number %d is a power of 2 \n",a);
}
return 0;
}
also i am tried to compile this code on bash with this line :
-std=c99 -Wall -pedantic-errors -Werror -DNDEBUG main.c compiled.o
what am i doing wrong ?
Use the following command. Works like a charm in ubuntu bash. You can just input the values in the terminal, after running the program.
gcc main.c -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -o main
Above a command generates a binary with the name main, Run the main file using following command.
./main
Then enter the your values.
To compile gcc main.c -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -o main
to run from bash and accept arguments from a file named 'testcasefile' ;type following
main < (path to file)/testcasefile. 3 as for howv to run from eclipse refer to
https://stackoverflow.com/a/16921891/6721448
Let's start anew. Make a new directory for your project main inside project directory a directory for test case testcase
mkdir -p main main/testcase
now make test cases
Test case 1
2
3
4
compile main.c as follows
gcc - std=c99 -Wall -o main main.c
execute out put main with test case
./ main < testcase/testcase1
I've been getting back into C, and I've been working on an 'academic' exercise to sharpen some old skills again. My project revolves around the rather simple process of generating sines. I started out just coding for x86 on the command line (Fedora Core 20) and everything worked fine. I then migrated the code to AVR, and I started learning a lot. For example, how to set up the UART as stdout. However, as sines are floating-point, I ran into problems using printf and sprintf.
The program generates 30 sines, and then prints the values to terminal. The text "Sine: " prints properly, but then I get question marks for the float. Replacing the variable with a constant had no effect.
The first thing I was suggested was if I had remembered the linker option for full floating point support - indeed I had forgotten. Again, adding this into my makefile had no effect.
I'm not sure of the policy here of copying and pasting code: should I paste it and my makefile here for inspection?
EDIT: Sorry for the long delay. I've done some more reading, including what the first answer links to. I had already read that reference before (the GNU one) and I have included the link in my Makefile, which is why I'm so confused. Here's my Makefile in all its glory:
P = sines
OBJ = sines.o
PROGRAMMER = buspirate
PORT = /dev/ttyUSB0
MCU_TARGET = atmega328p
AVRDUDE_TARGET = atmega328p
HZ = 16000000
DEFS =
LIBS = -lprintf_flt -lm
CC = avr-gcc
override CFLAGS = -g -DF_CPU=$(HZ) -Wall -O1 -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS= -Wl,-Map,$(P).map -u,vfprintf
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
all: $(P).elf lst text
$(P).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LIBS)
clean:
rm -rf *.hex *.bin *.map *~ sine*.csv *.o $(P).elf *.lst
lst: $(P).lst
%.lst: %.elf
$(OBJDUMP) -h -S $< > $#
text: hex bin
hex: $(P).hex
bin: $(P).bin
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $#
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $#
install: $(P).hex
avrdude -p $(AVRDUDE_TARGET) -c $(PROGRAMMER) -P $(PORT) -v -U flash:w:$(P).hex
What I'm concerned about is that perhaps the linker arguments aren't in the correct order? From what I can tell, they are but...
I'm fairly sure my code itself is fine. If wanted, I can post it here as well.
Also, thanks for transferring my question over here. Didn't quite understand the difference between the two!
Here's the source code. It's being run on an ATmega328P. This current version is printing a constant as a debug, instead of the result from sinescalc(), even though I know that function is working (at least, it should be, I'm pretty sure I checked using avr-gdb at one point -- it definitely works on the command line, and also on an MSP430).
#include <avr/io.h>
//#include <util/delay.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
static int uart_putchar(char c, FILE *stream) {
if (c == '\n')
uart_putchar('\r', stream);
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = c;
return 0;
}
void sinescalc(double *sinptr, int cycles, int size) {
double pi = acos(-1);
double step = ((pi * (cycles*2))/ size);
float temp;
double z = step;
int y;
for(y = 0; y<= size; y++) {
temp = sin(z); // calculate the current sine
*sinptr = (double)temp; // pass it into the array from main()
z += step; // add the step value to prepare for next sine
sinptr++; // should move the pointer by correct size of variable
}
}
int main(void) {
unsigned long _fosc = 16000000;
unsigned int _baud = 19200;
unsigned long _myubrr = _fosc/16/_baud-1;
unsigned int array_size = 256;
UBRR0L = (unsigned char)_myubrr;
UCSR0B = (1<<RXEN0)|(1<<TXEN0); //enable receiver and transmitter
stdout = &mystdout;
double sines[array_size];
double *sinepointer = sines; // set sinepointer to first element of sines array
sinescalc(sinepointer, 2, array_size); // calculate two cycles of sine, with 255 data points
int y;
//char msg[6] = ("Sine: ");
char output[40];
for(y = 0; y <= array_size; y++) {
sprintf(output, "Sine:\t %.6f", 1.354462);
printf(output);
printf("\n");
}
return 0;
}
This page states that to get the full printf() implementation, that supports printing floats, you should use:
-Wl,-u,vfprintf -lprintf_flt -lm
So I solved it. For those wondering, it really DOES come down to the order of arguments after -Wl. Here's the final makefile that seems to be working (so far, in a simulator):
P = sines
OBJ = sines.o
PROGRAMMER = buspirate
PORT = /dev/ttyUSB0
MCU_TARGET = atmega328p
AVRDUDE_TARGET = atmega328p
HZ = 16000000
DEFS =
LIBS = -lprintf_flt -lm
CC = avr-gcc
override CFLAGS = -g -DF_CPU=$(HZ) -Wall -O2 -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS= -Wl,-u,vfprintf,-Map,$(P).map
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
all: $(P).elf lst text
$(P).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o $# $^
I thought that I had tried that order before, and it threw an error. What I think I did wrong before was omit the comma after vfprintf. Also, the suggestion from another website of putting the -u,vfprintf AFTER the LDFLAGS (and after the -o section) was also clearly incorrect.
Edit from 2018: Recent versions of GCC seem to require the libraries to come as the last argument, no matter what other arguments there are. If you are having problems compiling (I'm not sure what versions of gcc/avr-gcc are being distributed by the various distros) and you are getting a bunch of "implicit declaration of x function" errors, it's because your library arguments are in the wrong spot. This just bit me recently, and I haven't seen any information on why this change happened, or which versions are affected.
Why it has to go in exactly that spot, I don't know yet. Perhaps someone can shed some light on it? I can't believe the answer was as inane as this. I just started moving things around until I hit on this. However, after looking at the GNU documentation again, they show the -Wl, directly before the -u,vfprintf. What threw me off was the presence of the -Map,$(P).map, which I thought had to go directly after -Wl as well. It seems like the -lprintf_flt -lm can come afterwards. I know that -lm is the option to link in the GNU math libraries, which is important for floating point math, obviously. I also understand what the other two options do (link in the correct version of the stream functions with floating-point support compiled in). But as I said before, perhaps someone can point me (and others) to a resource regarding hierarchy of gcc linker options? This problem has been dogging me for a week, and nobody was able to just point out that the -Map could come afterwards, but still needed a comma in between. I might try flipping around the -Map and the -u options, still with their commas, to see if it's THAT hierarchically important...
It isn't. Just changed it to -Wl,-Map,sines.map,-u,vfprintf and t still works with no problem. So the answer had to do with commas, which I take it means that all linker options need to be attached with commas? Why doesn't -lm need to be there as well? I'm a littl baffled, but relieved that it's working. Now I just need to try it on the hardware, though I'm pretty sure it'll work just fine.
Thanks everyone, for your help! This has been a great introduction to Stack Overflow (and all the Stacks) and I really hope that I can learn a lot, and contribute to this community. I've been carefully re-reading all the articles about asking good questions, and how the reputation and voting system works, so hopefully I get it right and I don't piss anyone off :)
Cheers!!
You can convert float (can be double, but in avr-gcc till v9 is implemented the same as float) to string prior printing it, and you can go without linker alterations by ie:
float in_volt = temp/1024.0*5.0;
char in_volt_string[8];
dtostrf(in_volt, 6, 4, in_volt_string);
That solved it for me in AVR Studio 4 with Atmega32. Then was put to lcd and tera term without problems.
I want my program to do the same thing as the terminal commands below:
gcc program1.c -o p1 funcs.c
gcc program2.c -o p1 funcs.c
This is what I've been experimenting with: Making a C program to compile another
I got as far so calling my program (./"programName") in the terminal that it replaced the need for me too type gcc but needing me too type in the rest.
You can use the Linux and POSIX APIs so read first Advanced Linux Programming and intro(2)
You could just run a compilation command with system(3), you can use snprintf(3) to build the command string (but beware of code injection); for example
void compile_program_by_number (int i) {
assert (i>0);
char cmdbuf[64];
memset(cmdbuf, 0, sizeof(cmdbuf));
if (snprintf(cmdbuf, sizeof(cmdbuf),
"gcc -Wall -g -O program%d.c fun.c -o p%d",
i, i)
>= sizeof(cmdbuf)) {
fprintf(stderr, "too wide command for #%d\n", i);
exit(EXIT_FAILURE);
};
fflush(NULL); // always useful before system(3)
int nok = system(cmdbuf);
if (nok) {
fprintf(stderr, "compilation %s failed with %d\n", cmdbuf, nok);
exit(EXIT_FAILURE);
}
}
BTW, your program could generate some C code, then fork + execve + waitpid the gcc compiler (or make), then perhaps even dlopen(3) the result of the compilation (you'll need gcc -fPIC -shared -O foo.c -o foo.so to compile a dlopenable shared object...). MELT is doing exactly that. (and so does my manydl.c which shows that you can do a big lot of dlopen-s ...)
You can use exec family function or you can directly execute shell command by using system() method
There is build in functionality in Makefile.
All you would have to call is make.
How to: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
Great stackoverflow question: How do I make a simple makefile for gcc on Linux?
So I'm trying trying to use a function defined in another C (file1.c) file in my file (file2.c). I'm including the header of file1 (file1.h) in order to do this.
However, I keep getting the following error whenever I try to compile my file using gcc:
Undefined symbols for architecture x86_64:
"_init_filenames", referenced from:
_run_worker in cc8hoqCM.o
"_read_list", referenced from:
_run_worker in cc8hoqCM.o
ld: symbol(s) not found for architecture x86_64
I've been told I need to "link the object files together" in order to use the functions from file1 in file2, but I have no clue what that means :(
I assume you are using gcc, to simply link object files do:
$ gcc -o output file1.o file2.o
To get the object-files simply compile using
$ gcc -c file1.c
this yields file1.o and so on.
If you want to link your files to an executable do
$ gcc -o output file1.c file2.c
The existing answers already cover the "how", but I just wanted to elaborate on the "what" and "why" for others who might be wondering.
What a compiler (gcc) does: The term "compile" is a bit of an overloaded term because it is used at a high-level to mean "convert source code to a program", but more technically means to "convert source code to object code". A compiler like gcc actually performs two related, but arguably distinct functions to turn your source code into a program: compiling (as in the latter definition of turning source to object code) and linking (the process of combining the necessary object code files together into one complete executable).
The original error that you saw is technically a "linking error", and is thrown by "ld", the linker. Unlike (strict) compile-time errors, there is no reference to source code lines, as the linker is already in object space.
By default, when gcc is given source code as input, it attempts to compile each and then link them all together. As noted in the other responses, it's possible to use flags to instruct gcc to just compile first, then use the object files later to link in a separate step. This two-step process may seem unnecessary (and probably is for very small programs) but it is very important when managing a very large program, where compiling the entire project each time you make a small change would waste a considerable amount of time.
You could compile and link in one command:
gcc file1.c file2.c -o myprogram
And run with:
./myprogram
But to answer the question as asked, simply pass the object files to gcc:
gcc file1.o file2.o -o myprogram
Add foo1.c , foo2.c , foo3.c and makefile in one folder
the type make in bash
if you do not want to use the makefile, you can run the command
gcc -c foo1.c foo2.c foo3.c
then
gcc -o output foo1.o foo2.o foo3.o
foo1.c
#include <stdio.h>
#include <string.h>
void funk1();
void funk1() {
printf ("\nfunk1\n");
}
int main(void) {
char *arg2;
size_t nbytes = 100;
while ( 1 ) {
printf ("\nargv2 = %s\n" , arg2);
printf ("\n:> ");
getline (&arg2 , &nbytes , stdin);
if( strcmp (arg2 , "1\n") == 0 ) {
funk1 ();
} else if( strcmp (arg2 , "2\n") == 0 ) {
funk2 ();
} else if( strcmp (arg2 , "3\n") == 0 ) {
funk3 ();
} else if( strcmp (arg2 , "4\n") == 0 ) {
funk4 ();
} else {
funk5 ();
}
}
}
foo2.c
#include <stdio.h>
void funk2(){
printf("\nfunk2\n");
}
void funk3(){
printf("\nfunk3\n");
}
foo3.c
#include <stdio.h>
void funk4(){
printf("\nfunk4\n");
}
void funk5(){
printf("\nfunk5\n");
}
makefile
outputTest: foo1.o foo2.o foo3.o
gcc -o output foo1.o foo2.o foo3.o
make removeO
outputTest.o: foo1.c foo2.c foo3.c
gcc -c foo1.c foo2.c foo3.c
clean:
rm -f *.o output
removeO:
rm -f *.o
Since there's no mention of how to compile a .c file together with a bunch of .o files, and this comment asks for it:
where's the main.c in this answer? :/ if file1.c is the main, how do
you link it with other already compiled .o files? – Tom Brito Oct 12
'14 at 19:45
$ gcc main.c lib_obj1.o lib_obj2.o lib_objN.o -o x0rbin
Here, main.c is the C file with the main() function and the object files (*.o) are precompiled. GCC knows how to handle these together, and invokes the linker accordingly and results in a final executable, which in our case is x0rbin.
You will be able to use functions not defined in the main.c but using an extern reference to functions defined in the object files (*.o).
You can also link with .obj or other extensions if the object files have the correct format (such as COFF).
Really off the wall question here, but is there a way to compile a string of C code in GCC without any medium to hold that string (eg. a source file)?
Something along the lines of:
$ gcc "#include <stdio.h> int main( void ){ printf('hello world'); return 0;}" -o test
Feels really dirty, but it would be really nice if there was some simple way to do that type of thing.
If you use - as the input file in the command line, gcc reads from standard input. Since there is no file name extension gcc could use to find out the language that should be compiled, it has to be specified with the -x flag:
$ gcc -x c -o tst - <<EOF
> #include <stdio.h>
> int main(void) {
> printf("Hello world\n");
> }
> EOF
$ ./tst
Hello world
I confess to sometimes highlighting code and using:
(cat preamble.hpp; xsel) | g++ -x c++ - && ./a.out
The same works with "-x c" for C.