Tab not registering in makefile. Getting error message [duplicate] - makefile

This question already has answers here:
makefile:4: *** missing separator. Stop
(17 answers)
Closed 7 months ago.
using UBUNTU 20.4 and compiler version gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0,
Im very new to vscode-
I built a program in C, getting in its main arguments two strings (as file names)
so I built this Makefile to save myself time during checking my code compiling and running, and wrote it like this:
all: //tried with and without "all:" line//
gcc main.c
./a.out ex1.bin ex2.bin
rm -i a.out
and for some reason after execute make I get this denied in the Terminal and getting this:
Makefile:2: *** missing separator. Stop.
what did I do wrong and how do I fix it?
thanks for the helpers

if Andrea Baldini's answer doesn't work, look to the left of this setting . You may find text that says "Spaces: 4" click this and in the drop down menu select "indent using Tabs" and then select 4 or any other value.
This solution worked for me.

Have a look to Make rules syntax:
The recipe lines start with a tab character (or the first character in the value of the .RECIPEPREFIX variable; see Special Variables). The first recipe line may appear on the line after the prerequisites, with a tab character, or may appear on the same line, with a semicolon. Either way, the effect is the same. There are other differences in the syntax of recipes. See Writing Recipes in Rules.
You have to start the commands under target all using a TAB character, so ensure your editor is not adding spaces:
all:
gcc main.c
./a.out ex1.bin ex2.bin
rm -i a.out
Since you are using VS Code you can select Makefile language mode on the bottom right corner to be sure that each time you press TAB key it'll be a real TAB instead of spaces.

If you created a Makefile manually, in a Node.js based project with Docker and docker-compose in order to run more quickly some commands with docker-compose, you have to click on the bottom tab entitled spaces and then click on Convert indentation to tabs selection option.
Below a more visual explanation
Fix Makefile indentation issue

Related

Makefile execution properly [duplicate]

I tried to use a make file in code::blocks but I am doing it wrong. I have the version installed with the compilers included. http://sourceforge.net/projects/codeblocks/files/Binaries/10.05/Windows/codeblocks-10.05mingw-setup.exe/download. What do I do with the make file? It starts with:
CC=gcc
best, US
You don't tend to execute the make file itself, rather you execute make, giving it the make file as an argument:
make -f pax.mk
If your make file is actually one of the standard names (like makefile or Makefile), you don't even need to specify it. It'll be picked up by default (if you have more than one of these standard names in your build directory, you better look up the make man page to see which takes precedence).
As paxdiablo said make -f pax.mk would execute the pax.mk makefile, if you directly execute it by typing ./pax.mk, then you would get syntax error.
Also you can just type make if your file name is makefile/Makefile.
Suppose you have two files named makefile and Makefile in the same directory then makefile is executed if make alone is given. You can even pass arguments to makefile.
Check out more about makefile at this Tutorial : Basic understanding of Makefile

Pipe and Redirect Bashcommands doesn't work in cmake [duplicate]

What I want to achieve
I try to set up a toolchain to compile OpenCL applications for Intel FPGAs. Therefore beneath building the C++ based host application I need to invoke the Intel OpenCL offline compiler for OpenCL kernels.
This step should only take place if the cl source file was edited or the resulting binaries are missing. My approach is to add a custom command to invoke the CL compiler and create a custom target that depends on the output generated by this command. The offline Open CL compiler is called aoc and due to the possibility of multiple SDK-Versions present on the system I invoke it with an absolute path that is stored in aocExecutable. This is the relevant part of my CMakeLists.txt
set (CLKernelName "vector_add")
set (CLKernelSourceFile "${PROJECT_SOURCE_DIR}/${CLKernelName}.cl")
set (CLKernelBinary "${PROJECT_BINARY_DIR}/${CLKernelName}.aocx")
add_executable (HostApplication main.cpp)
# ------ a lot of unneccessary details here ------
add_custom_command (OUTPUT "${CLKernelBinary}"
COMMAND "${aocExecutable} -march=emulator ${CLKernelSourceFile} -o ${CLKernelBinary}"
DEPENDS "${CLKernelSourceFile}"
)
add_custom_target (CompileCLSources DEPENDS "${CLKernelBinary}")
add_dependencies (HostApplication CompileCLSources)
What doesn't work
Running this in the CLion IDE under Linux leads to this error:
/bin/sh: 1: /home/me/SDKsAndFrameworks/intelFPGA/18.1/hld/bin/aoc -march=emulator /home/me/CLionProjects/cltest/vector_add.cl -o /home/me/CLionProjects/cltest/cmake-build-debug-openclintelfpgasimulation/vector_add.aocx: not found
The whole command expands correctly, copying it and pasting it into a terminal works without problems, so I'm not sure what the not found error means.
Further Question
Assumed the above problem will be solved, how can I achieve that the custom command is not only invoked if the output file is not present in the build directory but also if the CL source file was edited?
As you can see in the error message, the bash interprets the whole command line
/home/me/SDKsAndFrameworks/intelFPGA/18.1/hld/bin/aoc -march=emulator /home/me/CLionProjects/cltest/vector_add.cl -o /home/me/CLionProjects/cltest/cmake-build-debug-openclintelfpgasimulation/vector_add.aocx
as a single executable.
This is because you wrap COMMAND in your script with double quotes.
Remove these double quotes, so everything will work.
As in many other scripting languages, in CMake double quotes makes the quoted string to be interpreted as a single argument for a function or for a macro.
But in add_custom_command/add_custom_target functions a keyword COMMAND starts a list of arguments, first of which denotes an executable and others - separated parameters for that executable.

Problem executing Makefile for FPGA poject-Vivado

Hi I am new to creating makefile.
I have written the following commands in a makefile but they do not seem to execute when i type make in my terminal.
However, if i type the command separately in the terminal, it works.
I am trying to open a vivado project in this tcl file and do some spyglass analysis on it and save the result in a txt file.The tcl file also runs properly if executed separately.
I cd to my project folder where all the files- sources folder, project folder, makefile is present. I named it "makefile" so that i can execute it by typing make in the terminal.The makefile contents are as follows.
.PHONY : vivado_open
vivado_open:
$(info Hello Make)
bsub -Is -q i_soc_rh7 -R "rusage[mem=32000, temp=1GB] affinity[core(8):membind=localonly]" vivado -nolog -nojou -mode batch -source vivado.tcl
Here is the result from the terminal
$make
Hello Make
make: Nothing to be done for `vivado_open'.
Sorry, but there has to be something else going on here, that you haven't told us about. It's simply not possible for you to get that output if you typed make with that makefile.
You are using a variable, not a target named vivado_open, so make would never print nothing to be done for 'vivado_open'. It would say instead something like: nothing to be done for ../projectfiles/test.prj
Further, you didn't answer my question about TABs vs. spaces. If both the info and bsub lines are indented with TABs, there's no possible way that make would print Hello Make, without also printing the bsub command and trying to run it.
You must have another makefile in your directory, maybe named Makefile or GNUmakefile, that is being used instead of makefile. Or maybe you have an environment variable like MAKEFILES set which is causing other makefiles to be read.
If none of those appear to be true, you'll have to run make -d and see if you can figure out what's happening. That output is far too large to post to StackOverflow, so you'll have to try to read it yourself.
EDITED
OK, the problem is you're using spaces to indent your rules. In make, all recipe lines must be indented with a hard TAB character. Normal spaces don't mean anything special to make. Basically your makefile is interpreted as if you'd written this:
.PHONY : vivado_open
vivado_open:
$(info Hello Make)
bsub -Is -q i_soc_rh7 -R "rusage[mem=32000, temp=1GB] affinity[core(8):membind=localonly]" vivado -nolog -nojou -mode batch -source vivado.tcl
This is why you get this message "nothing to be done": you haven't actually defined a recipe for vivaldo_open, so there is literally nothing that make knows to do to update that target.
As an aside, normally you would get a syntax error for the bsub line because make doesn't know what that is. However, if you look carefully at your line you'll see that it contains a :. So, make is interpreting this as a set of targets and set of prerequisites, like this:
bsub ... affinity[core(8) : membind=localonly]" vivado ... vivado.tcl
(make doesn't care about quotes or other special characters like [] etc.)
So. Be sure you indent your recipe lines with TAB characters and you'll be fine. This is probably the single most common issue people have with makefiles.

How to just see a full command that gives error in GNU makefile

When I'm compiling something, it gives errors like this:
$ make
CC test/hello.o
test/hello.c:37:29: fatal error: this/is/hard/to/find.h: No such file or directory
Then, is it possible to see the full command of CC (with all the options) by just giving an proper option to make without modifying Makefile?
Usually when a Makefile is set up to print summary lines like this instead of the full command, they also define a VERBOSE or QUIET variable to control that behavior. You might try just running make as make VERBOSE=1, but if that doesn't work you'll have to check the Makefile to see if it supports verbose output through some other mechanism, or post some of your Makefile for us to see.
Alternatively, you could use something like ElectricAccelerator, a high-performance replacement for GNU make that, among other features, can produce an XML-marked-up version of your build log, including all the command-lines for every command invoked, even if the Makefile normally only prints summaries like you've shown.
(Disclaimer: I'm the architect and lead developer of ElectricAccelerator)

How to make Make *not* print "recipe for target failed?

I'm building a Makefile for a sequence of compiles to show progressive output differences to be used to synchronize with the examples in a tutorial. Some of those runs generates error codes, but since that is part of the definition of the "problem" the message output by make ("Makefile:15: recipe for target `run3' failed") when a target fails kind of gets in the way.
I know about ignoring the error code, but is it possible to suppress that output? Preferable from within the Makefile.
On a similar note, is it possible to suppress the message of entering and leaving subdirectories from within the Makefile (equivalent to '--no-print-directory')?
And, yes, I'm satisfied with a GNU Make answer.
Of course, after some googling the answer is in the GNU Make manual. The special targets .SILENT and .IGNORE did exactly what I wanted.
To achieve what you want I would use --silent --ignore-errors --no-print-directory GNU make switches and redirect stderr to /dev/null (2>/dev/null) commands in the makefile

Resources