Cmd prompt windows compiling - c

For my WINAPI projects, I am using atom IDE with c programming, I could compile my code from cmd prompt without a problem until I have started using .rc files. but now that I am using rc files before compiling my program I need to run these commands on the cmd prompt.
gcc -c jake.c
gcc -o jake jake.o -mwindows
windres -o jakerc.o jakerc.rc
gcc -o jake jake.o jakerc.o -mwindows
typing them all again and again to see if my program works correctly each time is really tedious. (Also please do not tell me to use IDEs like DEV c++ or Visual Studio because I don't like them as much as I like atom.)
so I have came up with this solution. I have made an extra file called compile.c which inside it looks like this.
#include <stdio.h>
#include <stdlib.h>
int main() {
system("C:\\Users\\hashtag\\Desktop\\rawsock\\kokul gcc -c jake.c");
system("C:\\Users\\hashtag\\Desktop\\rawsock\\kokul gcc -o jake jake.o -mwindows");
system("C:\\Users\\hashtag\\Desktop\\rawsock\\kokul windres -o jakerc.o jakerc.rc");
system("C:\\Users\\hashtag\\Desktop\\rawsock\\kokul gcc -o jake jake.o jakerc.o -mwindows");
return 0;
}
When I compile and run this program I get this error:
'C:\\Users\\hashtag\\Desktop\\rawsock\\kokul' is not recognized as an internal or external command,
operable program or batch file.
How do I get rid of this error, and how do I automatically compile my files when I run compile.exe?

as mentioned in my comment, i'd recommend using a batchfile and not a compiled c program for this.
Example:
#ECHO off
SET workingDirectory=%~dp0
SET fileName=%1
echo using %workingDirectory% as working directory
gcc -c %fileName%.c
gcc -o %fileName% %fileName%.o -mwindows
windres -o %fileName%rc.o %fileName%rc.rc
gcc -o %fileName% %fileName%.o %fileName%rc.o -mwindows
you could run your desiered commands with nameofthebatchfile.bat jake

As long as kokul is a directory the command line
C:\\Users\\hashtag\\Desktop\\rawsock\\kokul gcc -c jake.c
Doesn't make sense.
You can combine multiple commands. If you want to change into the directory kokul and start the compile this will work
CD C:\\Users\\hashtag\\Desktop\\rawsock\\kokul & gcc -c jake.c
But anyhow writing a batch file is much easier:

You can do it with two lines
windres -o jakerc.o jakerc.rc
gcc -o jake jake.c jakerc.o -mwindows
Save them to file "mj.bat", then run form command prompt by typing "mj".
When your project grows beyond two or thre files, you should use makefile
GCC and Make Compiling, Linking and Building C/C++ Applications
Check also atom-shell-commands or run-command package for Atom. You can run this directly form editor.

If you're working with command-line tools, this task just seems to cry out for a Makefile. Not only will make automate the necessary actions, it will try to work out from the file timestamps which actions actually need to be carried out. If you haven't changed a C source file, for example, you don't need to recompile it. The effectiveness of make, or similar, will increase enormously as your applications get larger and have more complicated dependencies between components.
You can do some of this stuff with simple batch files but, ideally, the batch file needs to stop when any of the steps encounters an error. There's no point carrying on a long build process that is doomed to fail, and finding the relevant error message in pages of irrelevant output can be a chore. This is another thing that make just does right.
It can take a while to get on top of Makefiles, with their arcane syntax. However, the effort will be rewarded many times over in the longer term.

Related

command line prompt command (want to understand what its doing)

I am doing the CS50 class, I have installed the cs50.h.
Based on the instructions I used the following command in terminal to compile my simple program and just want to make sure I understand everything im asking terminal to do.
Line is:
gcc -g hello.c -o hello -lcs50 -lm
I know the following*: gcc =
gcc = gnu compiler for C
-g = generate source-level debug information
Hello.c = name of the file we want to compile
-o = write output file
hello = our output file name
Can anyone tell me what -lcs50 and -lm are? My guess is that its calling on the library lcs50 in (-lcs50) but again this is a guess and would like to know for sure.
Everything works as it should with no issues
Thanks,
Mostly correct.
-o is not required to generate the output file, it's only needed to customize the name. (-o and the following name can only appear together).
-lcs50 means "link the library called cs50", not lcs50. It will try to find this file using several different name patterns, e.g. libcs50.so (on Linux), [lib]cs50.dll[.a] (on Windows), libcs50.a (on both), something else on Mac.
-lm links the standard math library, but I don't think you need to manually specify it on most modern GCC distributions.
Yes. For -lm, it's for the maths library, which is not linked by default. This is explained well at Why do you need an explicit `-lm` compiler option.

Can a C program be executed, in the same makefile as it is being built?

I have a makefile which builds my .C project, and produces an executable file. I know this can then be run from using the command ./(NAME) from the terminal.
My question is this - is it possible to actually build AND run within the makefile, so that i would just be able to type 'make' in the terminal, and the program would be built and run, all from this one file & command? (without the need of manually running the executable file).
Thanks :)
No idea what is you makefile, but you could do something like that:
PROGARGS=
.PHONY:all run
all:prog
#...
run:all
./prog $(PROGARGS)
Yes, it can.
For example:
TARGET=hoge
CC=gcc
.PHONY: compileandrun
compileandrun: $(TARGET)
./$(TARGET)
$(TARGET): $(TARGET).c
$(CC) -o $(TARGET) $(TARGET).c
If you have this Makefile and the source code hoge.c in your writable current directory, the program will be compiled and run with make command.
The other answers are good; however, you can use this other variant (a quick-and-dirty solution).
Suppose your makefile has this line to build your program:
NAME:
gcc source.c -o NAME
You can add your running command directly below:
NAME:
gcc source.c -o NAME
./NAME
This does the same as && concatenation: it runs the first command, and if successful, the second command too.
As long as you sequence your makefile dependencies correctly, there is nothing stopping you from running you C program from the makefile. That said, most people would expect a makefile to just build the file and not also run it at the same time.
I would recommend just writing the make command and the run command in a single line in the command line. This way you only need to press enter once but don't need to do anything fancy in the makefile itself. If your shell supports history completion, the next time you want to build and run again you only need to press "UP" and "ENTER"...
make && ./NAME
If you really want to put everything inside the makefile, I would recommend creating a separate "run" target in your makefile to reduce the chance of confusion, like in jdarthenay's answer.

gcc is working, but not yielding executable

My C compiler was working a second ago and making executables, but I started working on a new .c file and suddenly it won't work anymore. I haven't changed anything and I'm still using the same commands, Gitbash version, etc. The compiler is still able to catch errors, so gcc works, but after calling:
gcc -std=c99 my_file.c
there is no executable called my_file.exe. Help sites online suggest installing additional software to fix the error, but I'm hesitant to do so because everything was working fine earlier and I don't want to aggravate the problem with additional software.
Since you have not specified the name of the file to output, GCC will output a.exe.
If you desire output named something else, you must use the -o flag, for example:
gcc -std=c99 -o my_file.exe my_file.c
On Unix, that compiler command would generate an executable a.out. You may find that there is an executable with a default name — but I don't have Windows to check what that name is. Guesses might include a.exe, a_out.exe, aout.exe, etc.
To get my_file.exe:
gcc -std=c99 -o my_file.exe my_file.c
If you don't specify an output -o flag you will get a.exe by default (a.out on other platforms),
gcc -std=c99 my_file.c
If it is working, produces
a.exe
I think you wanted
gcc -std=c99 -o my_file.exe my_file.c

How to run a c program in ubuntu 12.04

Hello i am new to ubuntu. I want to run a c program in ubuntu.On the terminal i typed "make ex1.c" (my file name is ex1) and the after pressing enter button , terminal is telling me that
"no rule to make target 'ex1.c'. stop " .
How can i proceed?
Try this
$ gcc -Wall ex1.c -o ex1
$ ./ex1
-Wall makes all the warnings explicit. It is considered to be a good practice to always enable -Wall option. -o ex1 specifies the output executable to be ex1.
GCC is the default C compiler on Ubuntu. An elegant introduction to gcc can be read in here.
make needs no rules to make a simple C file, all it needs is the basename, without the .c extension:
make ex1
./ex1
I advise you to start using the gcc command though. You will have more control on how stuff is compiled and along the way, you'll learn how building an application works. make will start making sense if you have a larger project with many (inter dependent) files.
More (a lot!) information here: http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/, or by typing man gcc in the terminal.
Best is to use GCC or you are getting error because you are attaching ".c".So don't put extension in make command.Try without putting extension like following:
make ex1
./ex1

Include an external library in C

I'm attempting to use a C library for an opencourseware course from Harvard. The instructor's instructions for setting up the external lib can be found here.
I am following the instructions specific to ubuntu as I am trying to use this lib on my ubuntu box. I followed the instructions on the page to set it up, but when I run a simple helloWorld.c program using a cs50 library function, gcc doesn't want to play along.
Example:
helloWorld.c
#include <stdio.h>
#include <cs50.h>
int
main(void){
printf("What do you want to say to the world?\n");
string message = GetString();
printf("%s!\n\n", message);
}
$ gcc helloWorld.c
/tmp/ccYilBgA.o: In function `main':
helloWorld.c:(.text+0x16): undefined reference to `GetString'
collect2: ld returned 1 exit status
I followed the instructions to the letter as stated in the instructions, but they didn't work for me. I'm runing ubuntu 12.04. Please let me know if I can clarify further my problem.
First, as a beginner, you should always ask GCC to compile with all warnings and debugging information enabled, i.e. gcc -Wall -g. But at some time read How to invoke gcc. Use a good source code editor (such as GNU emacs or vim or gedit, etc...) to edit your C source code, but be able to compile your program on the command line (so don't always use a sophisticated IDE hiding important compilation details from you).
Then you are probably missing some Harvard specific library, some options like -L followed by a library directory, then -l glued to the library name. So you might need gcc -Wall -g -lcs50 (replace cs50 by the appropriate name) and you might need some -Lsome-dir
Notice that the order of program arguments to gcc is significant. As a general rule, if a depends upon b you should put a before b; more specifically I suggest
Start with the gcc program name; add the C standard level eg -std=c99 if wanted
Put compiler warning, debugging (or optimizing) options, eg -Wall -g (you may even want to add -Wextra to get even more warnings).
Put the preprocessor's defines and include directory e.g. -DONE=1 and -Imy-include-dir/
Put your C source file hello.c
Put any object files with which you are linking i.e. bar.o
Put the library directories -Lmy-lib-dir/ if relevant
Pur the library names -laa and -lbb (when the libaa.so depends upon libbb.so, in that order)
End with -o your-program-name to give the name of the produced binary. Don't use the default name a.out
Directory giving options -I (for preprocessor includes) and -L for libraries can be given several times, order is significant (search order).
Very quickly you'll want to use build automation tools like GNU make (perhaps with the help of remake on Linux)
Learn also to use the debugger gdb.
Get the habit to always ask for warnings from the compiler, and always improve your program till you get no warnings: the compiler is your friend, it is helping you!
Read also How to debug small programs and the famous SICP (which teaches very important concepts; you might want to use guile on Linux while reading it, see http://norvig.com/21-days.html for more). Be also aware of tools like valgrind
Have fun.
I take this course and sometimes I need to practice offline while I am traveling or commuting. Under Windows using MinGW and Notepad++ as an IDE (because I love it and use it usually while codding python) I finally found a solution and some time to write it down.
Starting from scratch. Steps for setting up gcc C compiler, if already set please skip to 5
Download Git and install. It includes Git Bash, which is MINGW64 linux terminal. I prefer to use Git as I need linux tools such as sed, awk, pull, push on my Windows and can replace Guthub's terminal.
Once Git installed make sure that gcc packages are installed. You can use my configuration for reference...
Make sure your compiler works. Throw it this simple code,
by saving it in your working directory Documents/Harvard_CS50/Week2/
hello.c
#include <stdio.h>
int main(void)
{
printf("Hello StackOverflow\n");
}
start Git Bash -> navigate to working directory
cd Documents/Harvard_CS50/Week2/
compile it in bash terminal
gcc helloworld.c -o helloworld.exe
execute it using bash terminal
./helloworld.exe
Hello StackOverflow
If you see Hello StackOverflow, your compiler works and you can write C code.
Now to the important bit, installing CS50 library locally and using it offline. This should be applicable for any other libraries introduced later in the course.
Download latest source code file cs50.c and header file cs50.h from https://github.com/cs50/libcs50/tree/develop/src and save them in Documents/Harvard_CS50/src
Navigate into src directory and list the files to make sure you are on the right location using
ls
cs50.c cs50.h
Cool, we are here. Now we need to compile object file for the library using
gcc -c -ggdb -std=c99 cs50.c -o cs50.o
Now using the generated cs50.o object file we can create our cs50 library archive file.
ar rcs libcs50.a cs50.o
After all this steps we ended with 2 additional files to our original files. We are interested in only 2 of them cs50.h libcs50.a
ls
cs50.c cs50.h cs50.o libcs50.a
Copy Library and header files to their target locations. My MinGW is installed in C:\ so I copy them there
cs50.h --> C:\MinGW\include
libcs50.a --> C:\MinGW\lib
Testing the cs50 Library
To make sure our library works, we can throw one of the example scripts in the lecture and see if we can compile it using cs50.h header file for the get_string() method.
#include <stdio.h>
#include <cs50.h>
int main(void)
{
printf("Please input a string to count how long it is: ");
string s = get_string();
int n = 0;
while (s[n] != '\0')
{
n++;
}
printf("Your string is %i chars long\n", n);
}
Compile cs50 code using gcc and cs50 library. I want to be explicit and use:
gcc -ggdb -std=c99 -Wall -Werror test.c -lcs50 -o test.exe
But you can simply point the source, output filename and cs50 library
gcc test.c -o test.exe -lcs50
Here we go, program is compiled using header and methods can be used within.
If you want Notepad++ as an IDE you can follow this tip to set it up with gcc as a compiler and run your code from there.
Just make sure your nppexec script includes the cs50 library
npp_save
gcc -ggdb -std=c99 -Wall -Werror "$(FULL_CURRENT_PATH)" -lcs50 -o "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"
cmd /c "$(CURRENT_DIRECTORY)\$(NAME_PART).exe"
Download the cs50 from: http://mirror.cs50.net/library50/c/library50-c-5.zip
Extract it. (You will get two files cs50.c and cs50.h)
Now copy both the files to your default library folder. (which includes your stdio.h file)
Now while writing your program use: #include < cs50.c >
You can also copy the files to the folder containing your helloWorld.c file.
You have to use: #include " cs50.c ".
OR =====================================================================>
Open cs50.c and cs50.h files in text editor.
In cs50.h, just below #include < stdlib.h > add #include < stdio.h > and #include < string.h > both on new line.
Now open cs50.c file, copy everything (from: /**Reads a line of text from standard input and returns the equivalent {from line 47 to last}) and paste it in cs50.h just above the #endif and save the files.
Now you can copy the file cs50.h to either your default library folder or to your current working folder.
If you copied the file to default folder then use: #include < cs50.h > and if you copied the files to current working folder then use: #include " cs50.h ".
You need to link against the library during compilation. The library should end in .a or .so if you are on Ubuntu. To link against a library:
gcc -o myProgram myProgram.c -l(library name goes here but no parentheses)
You have to link against the library, how come GCC would know what library you want to use?
gcc helloWorld.c -lcs50
Research Sources:
building on the answers above given by Basile Starynkevitch, and Gunay Anach
combined with instructions from some videos on youtube 1 2
Approach:
covering the minimum things to do, and sharing the "norms" separately
avoiding any modification to anywhere else on the system
including the basic breakdown of the commands used
not including all the fine details, covering only the requirements absolute to task or for effective communication of instructions. leaving the other mundane details to the reader
assuming that the other stuff like compiler, environment variable etc is already setup, and familiarity with shell's file navigation commands is there
My Environment:
compiler: gcc via msys2
shell: bash via msys2
IDE: doesnt matter here
Plan:
getting the source files
building the required files: *.o (object) and *.a (archive)
telling the compiler to use it
Action:
Let's say, current directory = "desktop/cs50"
It contains all the *.c files like test-file.c which I will be creating for assignments/problem sets/practise etc.
Get the *.h and *.c files
Source in this particular case: https://github.com/cs50/libcs50/tree/main/src
Go over each file individually
Copy all the content of it
Say using "Copy raw contents" icon of individual files
Create the corresponding file locally in the computer
Do it in a a separate folder just to keep things clean, let's say in "desktop/cs50/src" aka ./src
Build the required files using in the terminal after changing your current directory to "desktop/cs50/src" :
gcc -c cs50.c to create the "cs50.o" object file from "cs50.c" using "gcc"
ar cr libcs50.a cs50.o to create "libcs50.a" archive file which'll be containing "cs50.o" object file
Here, "libcs50" = "lib" prefix + "cs50" name (same as the header file's name)
This is the norm/standard way where the prefix "lib" is significant as well for a later step
However, prefix can be skipped, and it's not compulsory for name to match the header file's name either. Though, Skipping prefix is not recommended. And I can't say for sure about the name part
To tell the compiler to be able to use this infrastructure, the commands will be in following syntax after going to the parent directory (i.e. to "desktop/cs50"):
gcc test-file.c -Isrc -Lsrc -lcs50 if you used "lib" prefix in step 2.2 above
here, -I flag is for specifying the directory of *.h header file included in your test_file.c
and -L flag is for specifying the directory to be used for -l
and -l is for the name of the *.a file. Here the "lib" prefix talked about earlier, and ".a" extension is not mentioned
the order of these flags matter, keep the -I -L -l flags after the "test-file.c"
Some more notees:
don't forget to use the additional common flags (like those suggested above for errors etc)
if you skipped the "lib" prefix, then you can't use -L -l flags
so, syntax for command will become: gcc test-file.c -Isrc src/libcs50.a
say i created my test-file.c file in "desktop/cs50/psets", so, it can be handled in 2 notable ways (current dir = "desktop/cs50/") :
cd psets then changing the relative address correspondingly in -I -L, so result:
gcc test-file.c -I../src -L../src -lcs50
keeping current directory same, but then changing the file's relative address correspondingly, so result:
gcc psests/test-file.c -Isrc -Lsrc -lcs50
or use absolute addresses 😜
as it can be seen that this becomes quite long, that's when build automation tools such as make kick in (though i am accomplishing that using a shell script 😜)

Resources