Debugging a Makefile - debugging

Let me prefice this question with the comment that I know very little about Makefiles or make.
There is a very large project that is automatically built nightly. It is built in both Debug and Release mode, Debug being used for utilities like Valgrind to provide code analysis. Somehow, some of the built libraries are losing the debug flag during the make process, which makes some analysis output unhelpful. I was tasked with finding the bug and I need some suggestions on how to go about locating/repairing the issue.
Thanks in advance

make itself also supports a debug flag, -d; depending on how your Makefiles call each other, it may be possible to pass it through (and if not, you can rewrite them to do so with a script); then if you feed the resulting output to a file you can start looking for clues.

Given the sparse information, I can only sketch a very general strategy based on what I've seen in terms of Makefile usage for a handful of large projects.
If you don't already know where the flags originate, search through the Makefiles to find out.
Something like:
find . -name Makefile -exec grep -nH -- -g {} \;
(Adjusting the -name pattern if your project uses included Makefiles like foo.mk or bar.mak or something. And adjusting the "-g" if your debug flag is something else.)
You'll probably find it assigned to a variable like CFLAGS. Look around the spot where this variable is assigned, it is probably set conditionally (e.g. ifeq($(RELEASE),1)).
Now look at the Makefile(s) in the library that isn't getting those flags. Find the spot where the compile command lives. Is it using the right variable? Are these Makefiles overriding the variable?
It may also be helpful to capture the output of a build to a file and search around for any other places that might not have the debug flags set.

use remake, its really good

Related

How to use multiple compilers with waf (Python)

I can't figure out how to use two different compilers in the same wscript. Nothing in the Waf book shows this clearly.
I tried something among those lines :
def configure(ctx):
ctx.setenv('compiler1')
ctx.env.CC = '/some/compiler'
ctx.load('compiler_c')
ctx.setenv('compiler2')
ctx.env.CC = '/some/other/compiler'
ctx.load('compiler_c')
This does not appear to work. Waf does not find any compiler when I do it that way. I have only managed to compile using two different compilers by specifying in the command line
$ CC='/some/compiler' waf configure
This is annoying because I have to manually change the CC variable every time by hand and rerun configure...
Thanks !
Well, you were close :) You just need to load the compiler tool after setting the CC env variable, conf.load("compiler_c") and use variants build. I wrote a complete example in this answer.

Preprocess conditional arch/make file to get non-conditional file

I have a conditional makefile (well, actually I am dealing with the arch file that will be called when invoking make) that is quite involved and I would like to preprocess it to get rid of all the 'ifeq', 'ifneq' parts that only worsen the readability, in order to see better what is being actually done. I tried doing
make -n -d
where I get the whole calls to the compiler, but that is also a pain since then I need to separate manually all the flags. I just want to get my nice makefile with my separate FLAGS, DFLAGS, LIBS sentences etc etc.
(My apologies if this has been said anywhere, but I am unable to find it).
Thanks!

Can MinGW Make be sped up without disabling implicit rules?

GNU Make under MinGW is known to be very slow under certain conditions due to how it executes implicit rules and how Windows exposes file information (per "MinGW “make” starts very slowly").
That previous question and all other resources on the issue that I've found on the internet suggest working around the problem by disabling implicit rules entirely with the -r flag. But is there another way?
I have a "portable" Makefile that relies on them, and I'd like to make it so that it does not take around a minute to start it up each time, rather than having to get the Makefile owner to alter it just for me.
You should use make -d to see all the things make is doing and try to see where the time is going. One common reason for lengthy make times are match-anything rules which are used to determine whether or not a makefile needs to be rebuilt. Most of the match-anything rules CAN be removed; they're rarely needed anymore.
You can add this to your makefile and see if it helps:
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
And, if you don't need to auto-create your makefile you can add:
Makefile: ;
(also put any included makefiles there that you don't need to auto-create).
ETA
It seems your real question can be summed up as, "why does make take so much longer to start on Windows than on Linux, and what can I do to fix that without changing makefiles?"
The answer is, nothing. Make does exactly the same amount of work on both Windows and Linux: there are no extra rules or procedures happening on Windows that could be removed. The problem is that Windows NTFS is slower than typical Linux filesystems for these lookups. I know of no system setting, etc. that will fix this problem. Your only choice is to get make to do less work so that it's faster, and the only way to do that is by removing built-in rules you don't need.
If the problem is you really don't want to edit the actual makefiles, that's simple enough to solve: just write the rules above into a small separate makefile, maybe something like speedup.mk, then set the environment variable MAKEFILES=speedup.mk before invoking make. Make will parse that makefile as well without you having to change any makefiles.

How to deal with a script that outputs multiple files in a Makefile?

So I have a script, myscript.py, that produces a few output files, out/a.pickle, out/b.pickle, and out/c.pickle
And I have a Makefile that has the rule:
out/a.pickle: data/data.csv
myscript.py
Now, If I update the script, firstly, make out/a.pickle says there's nothing to be done here, even though the script has been modified. Isn't make supposed to check to see if things have been updated and then run them? Do I need to add myscript.py as a dependency to out/a.pickle, or something?
Secondly, is there a way to handle the fact that the script has multiple output files? Do I need to create a rule for each?
Make does not examine time stamps on executables. Otherwise, you would have to recompile the universe if gcc or echo or the shell is upgraded, and it's a slippery slope anyway; what if libraries or the kernel also changed in a way which requires you to recompile? You need human intervention at some point anyhow. So the designers of make simply drew the line at explicit dependencies.
(GNU Make has a lot of other built-in implicit dependencies, which are convenient. I vaguely believe that the original make didn't have any built-in dependencies at all. Anybody able to confirm?)
You can declare all the outputs in one rule:
out/a.pickle out/b.pickle out/c.pickle: myscript.py data/data.csv
./$^
(Notice how the script is included in the dependencies now. You might want to change that after the script is considered stable. Then you'll need to change the action as well.)

cmake, print compile/link commands

Can somebody please enlighten me as to what the command line flag to CMake might be that will make it print out all the compile/link commands it executes?
I can't find this anywhere in the documentation. Many hours of my life have just evaporated. I'd just like to verify it's doing what I think it is, (then banish the infernal build system altogether and replace it with a GNU Makefile).
Thank you!
The verbose argument should do what you want.
Content copied (with format adjusted slightly) here for future reference:
CMake/Verbose output
CMake has a nice colored output which hides the commandline. This is pretty to look at in the long run but sometimes when you write your configurations you want to know if you got all the compiler flags right. There is two ways to disable the pretty output, well, it's essentialy the same but still two different ways.
The first way is to simply run make with the additional argument "VERBOSE=1". This will show each command being run for this session, which is the most useful way to see if the flags is correct:
make VERBOSE=1
The second way is to permanently disable the pretty output in your CMakeLists.txt by setting CMAKE_VERBOSE_MAKEFILE:
set( CMAKE_VERBOSE_MAKEFILE on )
Content is available under Attribution-ShareAlike 2.5 unless otherwise noted.
Setting CMAKE_VERBOSE_MAKEFILE Works but the generator must be make. Documentation seems to assume this the case. Should probably be explicitly noted there.

Resources