GNU make is adding white space after -I (shared directory) option - makefile

I'm trying to use armclang compiler through a GNU makefile, but there is a clash between both tools when using -I option.
For armclang compiler, the -I means "Adds the specified directory to the list of places that are searched to find included files.Syntax -Idir" without a space.
For GNU makefile ‘-I dir’ has the same meaning (but with a space).
in My makefile I have the following:
$(aarch32_bootobj): %.o: %.s
#echo " [ASM ] $<"
#armclang --target=armv8a-arm-none-eabi -Icommon/shared -c $< -o $#
When Running the Makefile, I'm getting the following Warning and Error :
armclang: warning: argument unused during compilation: '-I common/shared'
aarch32/shared/bootcode.s:32:10: error: Could not find include file 'boot_defs.hs'
Where boot_defs.hs exists under common/shared
When running the same armclang command outside the makefile, it works. therefore I'm assuming that makefile has formatted the -Icommon/share option and added automatic space just after the -I.
Is there any way to run the armclang command correctly? in other worlds, is it possible to let the makefile parse the -Icommon/shared without any automatic formatting?
I have been trying a lot of tricks to workaround that without any success.
Thanks a lot In advance.

GNU make doesn't split the -Icommon/shared option, and even if it did armclang would be able to parse that. If you remove the # from the armclang call in the Makefile, you'll see exactly what make does and that the -Icommon/shared parameter remains intact.
Your problem is with armclang; see this bug on the tracker. It doesn't pass -I flags to its integrated assembler. A workaround, then, should be to pass -no-integrated-as to armclang:
#armclang -no-integrated-as --target=armv8a-arm-none-eabi -Icommon/shared -c $< -o $#
If that doesn't work, replace the .include directive with #include and either rename your asm files to .S (upper-case S), which indicates that they need C preprocessing, or pass armclang the -x assembler-with-cpp flag. The behavior of this is documented here.

Related

GNU make generate assembly first, them compile them to .o and link

SOURCE=a.c b.c c.c
ASM=$(patsubst %.c,%.s, $(SOURCE))
all:%.o
gcc -o test $^
$(ASM):%.c
gcc -S -o $# $<
%.o:%.s
gcc -c -o$# $<
I want to generate assembly code (.s) first, then compile the assembly code to object (.o), then link them.
But it seems above makefile code does not work. What is the correct code?
When asking questions, does not work is never very useful... if it worked you probably wouldn't be asking a question! :-) Instead you should always show the command you ran and the output you received (or at least the failing part of the output if it's long). Please cut and paste the actual text rather than paraphrasing messages. Also, including the version of the make program you're using (make --version) and the platform you're running on is often helpful.
Luckily this time we can figure out the problem without this information:
This:
$(ASM):%.c
gcc -S -o $# $<
where ASM is a.s b.s c.s, is not a pattern rule because the targets don't contain a pattern character %. That means the prerequisite %.c is not treated as a pattern, but as an actual file name, literally %.c which obviously doesn't exist.
Similarly, this:
all: %.o
has the same problem: all is a target, so this depends on the literal file named %.o which doesn't exist, and can't be created.
Also as a general rule every recipe that creates a target must create the actual target you told make it would, so this all rule is wrong because the target name is all but the recipe creates the target test.
Finally, it's a very bad idea to name your program test because test is a common UNIX program and a shell built-in, so if you run test it won't do the right thing (if you run ./test it will work).
You want to have all depend on the program you want to build, say mytest, and mytest should depend on the actual .o files:
all: mytest
mytest: $(SOURCE:.c=.o)
gcc -o $# $^
Next, you need to define a pattern rule that knows how to create an assembly file from a source file:
%.s : %.c
gcc -S -o $# $<
That, along with your other pattern rules, is all you need: make will figure it all out from that.
Finally, make has a built-in rule that tells it how to build object files directly from source files. It's best to get rid of this to force make to use your rules; add this to your makefile to delete it:
%.o : %.c

Getting rid of QMAKE-generated makefile's output spam

If I would write makefile by hand , I can do something like this
CXX = #g++
%.o: %.cpp makefile
#echo Compiling $< ...
$(CXX) -c $(FLAGS) $<
This would hide the executed command (thanks to #) but leaves all diagnostic and compiler's output. It would remove huge lists of parameters out of output log, but also would leave a comprehensive message.
I'm unable to reproduce this behaviour with Qmake, because all I can supply is a variable named QMAKE_CXX, content of which it would paste as a compiler, no way to insert a line break to my knowledge. Using these commands results in output like this
Compiling main.cpp...; #g++ -c -o main.o main.cpp
Can I organize output similar to manual compiler while using only QMAKE project file?
Should be something like this:
QMAKE_CXX = #echo "Message" && $$QMAKE_CXX
QMAKE apparently got undocumented QMAKE_UIC and QMAKE_MOC, with former being broken in some versions. Also an undocumented CONFIG += silent which replaces command lines with similar messages and uses same principle.

Produce both assembly and object file with gcc/clang: Possible? How?

Is it possible to produce both the object file and the source file in once command with gcc/g++/clang/clang++ ? How?
I need to pass a lot of other options, so I would like to avoid duplicating them in 2 separate commands:
gcc -S test.cc # produce assembly
gcc -c test.cc # produce object file
You can give the -save-temps option to gcc: it will leave all the temporary files (including the .s files) in the current directory (works also with clang):
gcc -c --save-temps test.cc
or use the -Wa,-aln=test.s option:
gcc -c -Wa,-aln=test.s test.c
From gcc documentation:
-Wa,option
Pass option as an option to the assembler. If option contains commas, it is split into multiple options at the commas.
From as documentation:
-a[cdghlmns] Turn on listings, in any of a variety of ways:
-al include assembly
-an omit forms processing
[...]
You may combine these options; for example, use -aln for assembly listing without forms processing.
Clang has an integrated assembler that should be switched off (How to switch off LLVM's integrated assembler?):
clang++ -c -no-integrated-as -Wa,-aln=test.s test.c

How to use command line argument in GNU make?

For example, I have 10 source files named ex1.c, ex2.c, ex3.c....ex10.c and maybe more in the future.
Is it possible that I can use commandline argument as a variable in GNU Make so that when I want to compile ex1.c, I can type in make 1. If I want to compile ex10.c, I can type in make 10. And I don't need to add more lines to makefile when I add more sources like ex100.c later.
This doesn't strike me as a good idea, but yes, you can do it.
To build object files (e.g. ex3.o):
%: ex%.c
$(CC) -c $< -o ex$*.o
To build executables (e.g.ex3):
%: ex%.c
$(CC) $< -o ex$*

GNU make not recognizing %

I'm trying to make a makefile for compiling various examples that are within a subfolder. The makefile consisting of just:
S_1_2.exe : Twister.cpp Parsing.cpp ./Surfaces/S_1_2.cpp
g++ -o $#.exe $^ -I . -W -Wall
Works fine when run with the command "make S_1_2.exe". However:
%S_1_2.exe : Twister.cpp Parsing.cpp ./Surfaces/S_1_2.cpp
g++ -o $#.exe $^ -I . -W -Wall
fails, even when run with the command make S_1_2.exe, with the error "make: * No rule to make target 'S_1_2.exe'. Stop."
Shouldn't %S_1_2.exe do pattern matching and so match S_1_2.exe? In which case why is it not matching this rule?
I am using GNU Make 3.81
The percentage symbol matches a non-empty string. So you should use %_1_2.exe or better yet - %.exe. I don't know if there is any other symbol that matches empty strings too.
The % is for matching a part of the target against the same part in one or more dependencies.
You can't omit it from all dependencies.

Resources