I’m taking a class where we are learning c, our professor told us to install bash in wsl and to use makefiles to run our code.
I often have small mistakes in my code the first time I run, so it is frustrating having to type:
$ make filename
$ ./filename
Especially because I’m dyslexic and often misspell my filename. I’m therefore looking for a faster way to execute my code using a makefile. Something like the extension code runner which I used before taking the class were all I had to do was hit ctrl + alt + n.
You can have a target to run your code: Imagine this simple Makefile:
my_prog_objs = a.o b.o c.o
my_prog_args = a b c
my_prog_out = my_prog.out
.PHONY: all clean run
all: my_prog
clean:
rm -f my_prog $(my_prog_objs)
# THIS IS THE IMPORTANT TARGET, first builds the
# program, then runs it.
run: my_prog
my_prog $(my_prog_args) >$(my_progs_out)
my_prog: $(my_prog_objs)
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $($#_objs)
by using make you get everything built, but running make run you build everything and run my_prog with the arguments shown in the Makefile (a b c) and the output redirected to my_prog.out and this will save a lot of typing if you need to test it.
Related
System: VirtualBox Ubuntu 20.04
This question sounds like stupid, but I have stuck at this problem for hours. (Purely new to Makefile)
Here is the description:
The program (sh.c)simulates a shell, which is a infinite loop. User can exit if they enter builtin command exit, like below:
> gcc -o sh sh.c
> ./sh
>>> $ (user can enter command)
...
...
>>> $ exit
Goodbye!
> (back to bash)
The question is if I want to place gcc -o sh sh.c and ./sh into Makefile and enter make to run, bash will stuck like this:
> make
gcc sh.c -o sh
./sh
(stucking...)
and I cannot type commands also cannot exit by Ctrl + C.
I believe the problem is in the Makefile, because program can run smoothly if I don't use Makefile, and below is my Makefile:
all: compile run
.PHONY: all clean
CC := gcc
FLAG := -Wall
SRC := sh.c
EXE := sh
compile: $(SRC)
$(CC) -o $(EXE) $(SRC)
run:
./$(EXE)
clean:
rm -rf $(EXE)
I wonder what is the problem in the Makefile, thanks in advance!
The reason for this weird behavior must be related to your implementation of sh.c. Using a normal shell, for example, works fine for me:
$ cat Makefile
run: ; /bin/sh
Now I can run make and it starts a shell and I can type stuff into it and it works:
$ make
/bin/sh
$ echo hi
hi
$ exit
But, as John says, make is not intended to allow you to run interactive programs. It's intended to allow you to build programs and run other commands non-interactively. If you use make -j for example (parallel builds) only one rule can get access to stdin at a time and there's no way to know which one it will be. Etc.
You should keep the compile rule (although it should be written differently: it's always wrong for a make recipe to build a different file than the name of the target) but throw away the run rule, and just run the command from your shell prompt after make is done.
all: $(EXE)
$(EXE): $(SRC)
$(CC) -o $(EXE) $(SRC)
The following terminal commands will compile and link my .c and .s files in linux
rm *.o
gcc -c printS.c -o printS.o
as lab8.S -o lab8.o
gcc lab8.o printS.o -o lab8test
I have never written a make file and I figure something like this deserves one. Any help is appreciated.
The same way you would make any make file. I am sure there are tons of examples out there and web pages.
ideally_the_result : dependencies
<tab>the commands
<tab>the commands
<tab>the commands
so
printS.o : printS.c
gcc -c printS.c -o printS.o
And make a rule for each of the commands you are using. I recommend you put the last one first so that it is the default if you dont have a command line option on make
also
clean :
rm -f *.o
rm -f lab8test
to cover cleanup (make clean)
That is the super simple way that just works. From there you can dig into all kinds of (make program specific, gnu make vs others) special characters that mean things to make more complicated rules.
I'm writing a small C library for some basic polygon operations and I'm trying to use LLDB from the command line for debugging. I am able to run LLDB with my compiled test runner, but I can only see assembly instructions and not C code as I step through.
I've compiled my library and test runner with the -g flag as shown here in this Makefile:
#Define compiler flags
CFLAGS = -g -Wall -Werror
#Define objects
OBJECTS = MASClip.o MASGraph.o MASClipTest.o
tests : $(OBJECTS)
cc $(CFLAGS) $(OBJECTS) -o tests
MASClip.o : MASClip.h MASClip.c
cc $(CFLAGS) -c MASClip.c
MASGraph.o : MASGraph.h MASGraph.c
cc $(CFLAGS) -c MASGraph.c
MASClipTest.o : MASClipTest.c
cc $(CFLAGS) -c MASClipTest.c
test :
make
make clean
./tests
.PHONY : clean
clean :
rm *.o
I can set breakpoints by function name so I don't understand why the code is not displayed.
I've searched around, but I don't see that I'm doing anything different from what the tutorials and other questions say. I must be missing something obvious.
Also, I realise I could just do this in Xcode, but when I write straight C I like to use VIM and it would be nice to be able to use LLDB from the command line.
How do I get LLDB to display the actual C code when debugging?
On OS X debug info is stored in .o files. The debugger refers back to the .o files using a "debug map" in the executable. Looks like you are deleting the .o files before you try to debug, so there's no debug information for the debugger.
Either leave the .o files in place when you debug, or run the dsymutil tool on the executable to produce a linked debug output file (.dSYM.) If you put the dSYM next to the executable (or anywhere that Spotlight searches) then lldb will find it automatically.
Note that if you just give the compiler a list of .c files, it will make a dSYM for you automatically - since it will delete the .o files when it is done - so that debugging is still possible.
I'm working on an open source C project that has two example files to run the library, one called example.c, and one called test.c.
The Makefile consists of the following:
test: test.c src/term.c
$(CC) $^ -o $#
example: example.c src/term.c
$(CC) -std=c99 $^ -o $#
.PHONY: test example
However, when I run make and then do ./test, test runs, but when I do ./example, it doesn't. Any ideas why?
When you just type make the first target is being executed, in your case its test. So you will get only test executable. But if you type make example then example target is executed and you will get example binary. I think you need fresh up with Makefile rules.You can refer this for basic concepts or this for in depth understanding
I have downloaded the cmocka example files and followed all the instructions. All test files were succesfully generated and I can run them, but no output appears in the console. I have tried to alter the CMOCKA_MESSAGE_OUTPUT environmental variable, tried to write my own tests and compile them, tried to recompile and reinstall cmocka several times - nothing made the tests output anything. I work on Windows 7 32-bit, so I figured to try also cygwin, but cygwin just throws that it cannot find public libraries, so I abandoned this fork of my research - after all cmocka should also normally work in windows cmd. Does anyone know how to make the tests output anything to the console?
EDIT
I'm adding my make info in case there was some problem with compilation/linking, although I don't see any (it doesn't produce any error and outputs correctly the tests.exe file):
makefile
OBJ_DIR = obj
HDR = $(wildcard *.h)
SRC = $(HDR:.h=.c)
OBJ = $(HDR:%.h=$(OBJ_DIR)\\%.o)
CC = gcc
CFLAGS = -I"C:\Program Files\cmocka\include" -I"C:\Program Files\cmocka\lib" -I"C:\Program Files\cmocka\bin" -llibcmocka -lcmocka
.PHONY: all clean
all: tests.exe
$(OBJ_DIR)\\%.o: %.c %.h
$(CC) $< -c -o $# $(CFLAGS)
$(OBJ_DIR)\tests.o: tests.c
$(CC) $< -c -o $# $(CFLAGS)
tests.exe: $(OBJ) $(OBJ_DIR)\tests.o
$(CC) $^ -o tests.exe $(CFLAGS)
clean:
del $(OBJ) $(OBJ_DIR)\tests.o tests.exe
note1: the numerous paths in cflags are put out of desperation - at first I had been using only the first one.
note2: when I try to run this script in Netbeans or cygwin I change del to rm -f and switch slashes. The output is like described above: the make is done without any errors and outputs the tests.exe, but once executed, it throws error about not being able to find public libraries.
The symbol is not exported, see https://git.cryptomilk.org/projects/cmocka.git/commit/?id=7364469189558a8720b60880940a41e1a0d20452
Sorry for digging out this old thread, but i recently stumbled over exactly the same problem. Compiled everything by myself with meson/ninja and did not get any output neither from the test itself, nor from a simple printf.
I solved the problem by using the precompiled library from here.
Just install/start MSYS2 and use
for 64-bit MINGW:
pacman -S mingw-w64-x86_64-cmocka
for 32-bit MINGW:
pacman -S mingw-w64-i686-cmocka
Then I recompiled my hello world test, and output worked as intended.
I had the same problem, and for me it was that I had not properly passed the state argument to the tests. My tests had this signature:
void test_something() { /* ...snip... */ }
but it should have been
void test_something(void **state) {
(void) state; /* unused */
/* ...snip... */
}
After fixing this, the output properly appeared.
your problem is in the tests.c that has the unit tests, not your setup. Show us your tests.c file where you wrote your unit tests.
I have had the same problem.
Especially I also used gcov to see the coverage and it claims that nothing gets ever executed.
My solution was that I just forgot to add cmocka to my environment-path. After adding "cmocka.dll" to the path everything finally works.