No implicit rule found in makefile - c

My makefile execution fails each time due to a dependency. I don't want to overshare so I will try to only share the necessary info. I am using GNUWin32 make so that my windows box can execute it (a constraint I have to deal with) and I am able to compile/make a decent number of files in the src\\Framework\...\\%.o realm from ..\\src\\Framework\...\\%.c.
It seems that as long as it is at least 2 folders deep, the Makefile works. Ex: src\\test.o doesn't compile but src\\tester\\test.o will compile.
My error is as follows:
make: *** No rule to make target 'src\\control.o', needed by 'proj.elf'. Stop.
but I also have the following rule which is executed from a dependency of target all:
src\\%.o: ..\\src\\%.c
which should make src\\control.o as long as ..\\src\\%.c exists.
When I use make -d all I notice that it ends with
No implicit rule found for 'src\\control.o'.
Finished prerequisites of target file 'src\\control.o'.
Must remake target 'src\\control.o'
If anyone has a solution to make this work I would be glad to hear it!

I found the problem. Apparently, even GNUWin32 make uses Unix style filenames for the targets and dependencies but in order to use the mkdir command, you must use Windows style filenames.
test/windows/%.o: ../test/windows/%.c
mkdir test\windows\make_this_dir\
I hope this helps anyone with a similar issue.

Related

CMake: how to break a PRE_LINK infinite loop?

I'm trying to automatically label my application sign-on line with a build number. This application is a plain vanilla C one without graphic UI; it is intended for command line, therefore it is a "simple" one.
The sign-on id is located in a "template" source file which is customized by CMake with a configure_file() command. Recently, I fancied to include a build number in this sign-on id. Consequently, the customization can no longer be statically done at CMake time, but everytime make is invoked.
To achieve that, there are two possibilities in CMake:
add_custom_target(), but it is triggered even when nothing else changes in the source tree which does not reflect the state of the tree;
add_custom_command(), which can be triggered only when the application (target) needs to be linked again.
I opted for the second solution and did not succeed.
Here is an extract of my CMakeLists.txt, the sign-on id being in file ErrAux.c (template in PROJECT_SOURCE_DIR, configured in PROJECT_BINARY_DIR):
add_executable(anathem ... ${PROJECT_BINARY_DIR}/ErrAux.c ...)
add_custom_command(TARGET anathem PRE_LINK
COMMAND "${CMAKE_COMMAND}" "-DVERS=${PROJECT_VERSION}"
"-DSRC=${PROJECT_SOURCE_DIR}"
"-DDST=${PROJECT_BINARY_DIR}"
-P "${CMAKE_HOME_DIRECTORY}/BuildNumber.cmake"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Numbering build"
VERBATIM
)
This launches script BuildNumber.cmake just before the link step. It computes the next build number and customizes ErrAux.c with configure_file().
It works fine, except ...
It happens late in the make sequence and the update to ErrAux.c goes unnoticed. The sign-on id in the executable contains the previous build number.
Next time I run make, make notices the generated ErrAux.c is younger than its object module and causes it to be compiled again, which in turn causes a link which triggers a build number update. This happens even if no other file has changed and this loop can't be broken. This is clearly shown in the compiling log:
Scanning dependencies of target anathem
[ 13%] Building C object AnaThem/CMakeFiles/anathem.dir/ErrAux.c.o
[ 14%] Linking C executable anathem
Numbering build
3.0.0-45
[ 36%] Built target anathem
The crux seems to be that add_custom_command(TARGET ...) can't specify an output file like add_custom_command(OUTPUT ...) does. But this latter form can't be triggered in PRE_LINK mode.
As a workaround, I forced a compilation to "refresh" the object module with:
add_custom_command(TARGET anathem PRE_LINK
COMMAND "${CMAKE_COMMAND}" "-DVERS=${PROJECT_VERSION}"
"-DSRC=${PROJECT_SOURCE_DIR}"
"-DDST=${PROJECT_BINARY_DIR}"
-P "${CMAKE_HOME_DIRECTORY}/BuildNumber.cmake"
COMMAND echo "Numbering"
COMMAND echo "${CMAKE_C_COMPILER}" "\$(C_DEFINES)" "\$(C_INCLUDES)" "\$(C_FLAGS)" -c "${PROJECT_BINARY_DIR}/ErrAux.c"
COMMAND "${CMAKE_C_COMPILER}" "\$(C_DEFINES)" "\$(C_INCLUDES)" "\$(C_FLAGS)" -c "${PROJECT_BINARY_DIR}/ErrAux.c"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Numbering build"
VERBATIM
)
An explicit compilation is forced after sign-on id customization. It mimics what is found in the various Makefile's and my not be safe for production. It's a cheat trick on both CMake and make.
UPDATE: Option -c is required to postpone link step until the final application liniking process.
This addition creates havoc in the link, as shown by the log, where you see a double compilation (the standard make one and the add_custom_command() one):
Scanning dependencies of target anathem
[ 13%] Building C object AnaThem/CMakeFiles/anathem.dir/ErrAux.c.o
[ 14%] Linking C executable anathem
Numbering build
3.0.0-47
Numbering
/usr/bin/cc -DANA_DEBUG=1 -I/home/prog/projects/AnaLLysis/build/AnaThem -I/home/prog/projects/AnaLLysis/AnaThem -g /home/prog/projects/AnaLLysis/build/AnaThem/ErrAux.c
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
AnaThem/CMakeFiles/anathem.dir/build.make:798: recipe for target 'AnaThem/anathem' failed
make[2]: *** [AnaThem/anathem] Error 1
If I force a full recompilation, to make sure all sources are compiled, *main.c* included, I get the same error on `main`.
The only logical explanation is my manual C invocation is faulty and somehow destroys vital information. I checked with *readelf* that `main` is still in the symbol table for *main.c.o* and that it is still taken into account by the link step (from file *link.txt*).
UPDATE: Even with the correct link, I'm still experiencing the infinite loop syndrom. The generated application still has its sign-on id lagging behind the actual build counter.
Can someone give me a clue for the right direction?
FYI I'm quite new to CMake, so I may do things really wrong. Don't hesitate to criticize my mistakes.
The key to the solution is to put the generated module where make expects to find it. CMake organizes the build tree in a non-trivial way.
The shortcomming in my added compilation in add_custom_command() was to believe that by default the binary will be stored in the "usual" CMake locations. Since I forge manually my compiler command, this is not the case.
I found the module in the source directory, which is a consequence of the WORKING_DIRECTORY option, with name ErrAux.o and not ErrAux.c.o.
To obtain the correct behavior, I force an output location with:
-o "${PROJECT_BINARY_DIR}/CMakeFiles/anathem.dir/ErrAux.c.o"
Now, when I run make again, nothing happens since nothing changed.
Side question
To make the solution portable (if needed), are there CMake variables for CMakeFiles and anathem.dir directories? Or in the latter case, for the current target as "anathem" as the target name in add_custom_command()?

Msys make in Powershell - No such file or directory

I installed the base package to compile C++ with MinGW Installer GUI and CMake. I created a simple file .c with hello world, and can use cmake . -G"MSYS Makefiles" normally. I added E:\Programmation\MinGW\bin and E:\Programmation\MinGW\msys\1.0\bin to my path.
Here is my CMakeLists.txt:
cmake_minimum_required (VERSION 3.3)
project (Prototype)
set (EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
file (
GLOB_RECURSE
source_files
src/*
)
add_executable (
my_exe
${source_files}
)
Once the makefile is created however, when I use make I'll get the following error:
/bin/sh:/e/Users/MyName/Documents/GitHub/ProjectName/prototype/c/E:/Programmation/MinGW/msys/1.0/bin/make.exe: No such file or directory
make.exe": *** [all] Error 127
I can compile the file main.c just fine with gcc main.c and the exe it produces works, so the problem is with the make.exe.
If I use it in the msys.bat shell, located in E:\Programmation\MinGW\msys\1.0, it works as it should. So my guess is that the problem is with Powershell and the path. I'm thinking maybe it's because of the way hard drives are designated, since in the error I get it calls my E:\ disk /e/ first then E:/. When I work in msys.bat I have to write it this way: /e/Users/MyName...
This is PEBKAC. The problem is not with make.exe, but rather, in the way you are attempting to misuse it.
How many times must I say this? Using MSYS make.exe, (or indeed any of the MSYS tools), in any environment other that the MSYS shell, which is started by running msys.bat, is definitively unsupported by the MSYS Project maintainers.
Since you say you problem goes away, when you use make.exe as you are supposed to, (in the MSYS shell, invoked by running msys.bat), this is your problem, and your problem alone. It apparently does not work, when you attempt to use it improperly, (i.e. from PowerShell): that's tough luck; when you break free software, by misusing it, you get to keep all the pieces.
Contrary to the accepted answer, it is actually possible to do this using PowerShell:
sh.exe -c "cd ""$pathToMake""; make"
Make sure you sanitise backslashes for the shell before the call above.
$pathToMake = $pathToMake -replace "\\", "/"
Also the MSYS bin has to be in your path, which would typically look like this (your path maybe different):
$env:Path = "C:\GNUstep\msys\1.0\bin;$($env:Path)"

Trying to adapt existing c project to CUDA, .cu files not found by Makefile

I'm trying to accelerate a key function in a c project (not c++) using CUDA.
For some reason, i can't get the Makefile's to recognise the .cu extension when I change the name of one of the files to .cu.
It's using a configure script and .am/.in/.deps files, which I don't really understand all that well, but basically I grepped references to file.c and changed them all to file.cu, but it produces a file.o: File Not Found error.
Top level make file
https://www.dropbox.com/s/g282qvbdu8pdas0/Makefile
Src folder makefile
https://www.dropbox.com/s/b4pq026od8gauqi/Makefile
The search command I used was
grep -R -i "file.c"
and I simply changed them all to file.cu, then re-ran configure, make clean, make all - result is File Not Found.
I suppose it must be something to do with extensions being ignored/accepted by the Makefile, but as it's been a long time since I've programmed in C and I've never used such complex Makefiles I don't know how to fix it.
Any ideas?
*PS Also, file.cu has compile errors at the moment, but the error message I'm getting is File Not Found, so I think that's not the problem.
You need to have a rule to build o file from a cu file:
cudafile.o: cudafile.cu
nvcc $(NVCC_FLAGS) -c %< -o $#
So you also need to specify the rule for the cu file, and use nvcc for compilation.
The following guide seems to cover it...
http://mcclanahoochie.com/blog/2011/02/automake-and-cuda/
Actually, most of the advice given in the link seems unnecessary for basic compilation, but for some reason I found that when I re-created the config file using autoconf it worked. No explanation comes to mind.

Makefile - Just make install (copy files), no target to build

I have a simple makefile project where I just want make install to copy files to a target folder, ie:
all:
#echo "Nothing to build"
install:
cp ./*.wav /usr/share/snd
my_custom_target:
#echo "For testing purposes"
However, whenever I try to build any targets (ie: clean, all, install, my_custom_target, etc), every single one just echos "Nothing to be done for 'clean'", "Nothing to be done for 'all'", etc. My guess is that a makefile project is expecting at least something being built (ie: C/C++ file, etc).
Does anyone have any suggestions on how to proceed with this?
Thank you.
This seems to indicate that make is not able to find, or not able to correctly parse, your Makefile. What is the file named?
Also, ensure that the commands in each rule (like the cp ./*.wav /usr/share/snd) are prefixed by an actual tab character, not spaces. In the sample that you pasted in, they are prefixed simply by three spaces, but for make to parse it properly, they need to be prefixed by an actual tab character.
One more thing to check is whether there are files named all, install, or my_custom_target. Make does not care about whether some C or C++ file is built; the rules can do anything that you want. But it does check to see if there is a file named the same as the rule, and whether it is newer than the dependencies of the rule. If there is a file, and it is newer than all dependencies (or there are no dependencies, like in this example), then it will decide that there is nothing to do. In order to avoid this, add a .PHONY declaration to indicate that these are phony targets and don't correspond to actual files to be built; then make will always run these recipes, whether or not there is an up-to-date file with the same name.
.PHONY: all install my_custom_target

how to "execute" make file

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

Resources