Firefox make file - firefox

I want to backtrace the makefile for firefox so that I can get the final gcc command that is used to compile the c++ files. How can I do that?

If you find a line in there that begins with "# $(CXX)" or "# g++", then change the line to "$(CXX)" or "g++" -- in other words, delete the "#" symbol from the line. When an "#" symbol appears at the beginning of a command in a Makefile, it causes Make to not echo the command before executing it. Deleting the "#" symbol will cause the expanded form of the line to be echoed before the command is invoked.
I haven't looked at Firefox's makefile, so it is more than possible that they are using predefined pattern rules for building the code, in which case you won't see any lines beginning with "$(CXX)" . If that is the case, you will need to override the rules, so that the default build rules echo the commands before executing them.
For more information on overriding Makefile pattern build rules, see this link:
http://www.gnu.org/software/make/manual/make.html#Pattern-Rules

The usual stunt for this is to replace gcc with a program that reads the gcc command line,
store it in some log file so it can be inspected, and then launches gcc with the command line. You can do this by replacing "gcc.exe" in your development directories by this stepping stone program.

Here's the make rule that compiles C++ files:
http://hg.mozilla.org/mozilla-central/annotate/c1ab8650e0ce/config/rules.mk#l1391
If all you want to do is replace the compiler, you can (in your mozconfig, or on the configure commandline) set CXX="whatever".

Can you redirect the output of make to a file, then use a text editor to search for the line of interest?

Related

cmake 'add_custom_command' to pre-process header files?

i'm working on a project requiring cmake. i'd like to add some custom rules to my makefile, but can't quite get my head around how to do it.
both c source files and header files are in the same directory. also in this same directory are a number of .def files, which are the sources for some of the header files #included in the source during compilation.
if i were to do this in a makefile, i'd use a simple rule like
.SUFFIXES: .def
.def.h:
$(PREPROC) $< > $#
how can i do this with cmake ??
i've tried various permutations of the following, both with and without cmake working directory specifications :
add_custom_command(
OUTPUT vvr_const.h
PRE_BUILD
COMMAND preproc vvr_const.def > vvr_const.h
DEPENDS vvr_const.def
)
add_custom_target(vvr_const.h DEPENDS vvr_const.def)
but the header file isn't generated by the time the c source file is compiled, so the compile fails. i've also tried a variation where i replace the last line above with
set_property(SOURCE main.c APPEND PROPERTY OBJECT_DEPENDS vvr_const.h)
in this case, the header file is correctly generated in advance, but make can't find it, and complains that there's no rule to make the target .h.
ideally this would be a general rule, like the make rule above, but i'm not opposed to making a separate rule for each of the .def files if that's what it takes.
cheers.
There are 2 problems with the add_custom_command approach you present:
You did not specify a working directory; by default the command is run in the build directory, not in the source directory.
You rely on shell functionality here (the redirect to a file). Even though this probably still works. You should go with an approach that does not rely on the shell.
To solve issues 1 and 2 I recommend creating a seperate cmake script file receiving the absolute paths to input and output files and using those in the custom command. This allows you to use execute_process to specify the file to write without relying on the platform.
preprocess_def.cmake
# preprocess def file
# parameters INPUT_FILE and OUTPUT_FILE denote the file to use as source
# and the file to write the results to respectively
# use preproc tool to get data to write to the output file
execute_process(COMMAND preproc "${INPUT_FILE}"
RESULT_VARIABLE _EXIT_CODE
OUTPUT_FILE "${OUTPUT_FILE}")
if (_EXIT_CODE)
message(FATAL_ERROR "An error occured when preprocessing the file ${INPUT_FILE}")
endif()
CMakeLists.txt
set(_INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vvr_const.def")
set(_OUTPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vvr_const.h")
# not necessary to use build event here, if we mark the output file as generated
add_custom_command(OUTPUT "${_OUTPUT_FILE}"
COMMAND "${CMAKE_BUILD_TOOL}" -D "OUPUT_FILE=${_OUTPUT_FILE}" -D "INPUT_FILE=${_INPUT_FILE}" -P "${CMAKE_CURRENT_SOURCE_DIR}/preprocess_def.cmake"
DEPENDS "${_INPUT_FILE}")
add_executable(my_target vvr_const.h ...)
set_source_files_properties(vvr_const.h PROPERTIES GENERATED 1)
Documentation from cmake:
PRE_BUILD
On Visual Studio Generators, run before any other rules are executed within the target. On other generators, run just before PRE_LINK commands.
So possibly your command is just running too late.

How can I set the file name if I run cpp (GNU C preprocessor) from stdin?

I have a vague memory of that gcc used to pipe the source code through external preprocessor, compiler (proper) and assembler (which no longer seem to be done). Due to this I expect it to be possible to (still) set the filename for the cpp even if you preprocess from stdin. However I didn't find any such option in the manual.
Note that this matters as first the __FILE__ macro should expand to the current filename (by default "<stdin>"), second the preprocessor inserts line directives in the output containing the filename.
Although not an command line argument, you could prepend the stdin with a line directive (ie a # 1 "<desired-filename>" line). Thereby the preprocessor will be told that the line after this is the first line of the desired filename.

Missing separator in Makefile

So here's the thing.
I'm trying to build pngwriter. In the makefile there's a line saying:
include make.include
The file make.include has the function to specify the platform used via a symlink, it has just one line:
make.include.linux
(there's a file in the same directory called make.include.linux which has some necessary settings. And by the way, I'm doing this on Windows with MinGW)
in the msys shell, when I do make, it says:
make.include:1: *** missing separator. Stop.
I've looked at other missing separator posts and they're about spaces/tabs, which I think it's not the case here. I've searched about makefiles, symlinks, separators and could solve it.
Please help!
EDIT! OK, so make.include.linux isn't a command, it's a file whose contents need to be included in the original makefile. The make.include should be, as I read, a symlink to make.include.linux.
What you have there isn't valid make syntax. Commands can only be run as part of a target recipe. In your case it seems like what you want is:
all:
make.include.linux
Assuming that make.include.linux is a command, and not something else. Make sure the indentation is a tab character.

GNU make: variable for command line arguments

How to pass the entire command line (including goals, link lines, make options etc) from top level make to recursive make:
targets : prerequisites
$(MAKE) $(this should expand to top level command line) additional_args
Thanks.
I think the closest you can get is using a combination of $(MAKE), which contains the exact filename make was invoked with, $(MAKECMDGOALS), which contains the goals you specified on the command line, and $(MAKEFLAGS), which contains any variable definitions and (a subset of) the switches specified on the command line.
The $(MAKE) macro is special and expands to include some relevant options. See the section How the MAKE variable works in the Make documentation for more details. However, this doesn't include the complete line including goals etc, and I'm not sure that is possible.
Usually I try to avoid using Make recursively, there's a good article about that here: Recursive Make Considered Harmful.

GNU make yields "commands commence before first target" error

In my makefile, I would like to check for the existence of a library and give an informative error message. I created a conditional that should exit the make process when the file is not found:
9: ifeq ($(${JSONLIBPATH}),)
10: JSONLIBPATH = ${ALTJSONLIBDIR}/${LIBJSON}
11: endif
12: ifeq ($(${JSONLIBPATH}),)
13: $(error JSON library is not found. Please install libjson before building)
14: endif
My makefile gets stuck on line 13:
Makefile:13: *** commands commence before first target. Stop.
After line 13, my makefile has its targets.
I tried putting this conditional block into a target (e.g. a target called isJSONLibraryInstalled) but this does not execute correctly.
How would I check for a file's existence and handle the error case, before processing targets? Apologies if this is a dumb question.
First of all, you are looking at the contents of a variable that is named after the current path, which is probably not what you want. A simple environment variable reference is $(name) or ${name}, not $(${name}). Due to this, line 13 is always evaluated.
Second, I think it is choking on the indentation of the $(error ...) expression. While the expression resolves to an empty string, there is still a tab character at the start of the line, which indicates a command, which in turn cannot exist outside a rule.
I think using spaces rather than tabs to indent would work.
When you get Make error messages, always check the Error message documentation
On GNU Make 3.81 (error appears to have been removed from newer versions), it says:
This means the first thing in the makefile seems to be part of a command script: it begins with a TAB character and doesn't appear to be a legal make command (such as a variable assignment). Command scripts must always be associated with a target.
What makes matters more confusing is that "doesn't appear to be a legal make command" part. That explains why in:
a := b
$(error a)
the error happens at line 2 and not 1: make simply accepts statements that it can parse, like the assignment, so the following works:
a := b
a:
echo $a
Note: SO currently converts tabs to spaces in code, so you can't just copy the above code into your editor.
For me it was an unnecessary white space before the connector that was causing this.
On slickEdit I selected the option to view all special character and noticed the black sheep.
You can check whitespaces, spaces and tabs by using VSCode [View > Render Whitespace]
As you can see;
command-1 has a tab (->) and whitespace at the end
command-2 has space at first
command-3/4 has tab+spaces
So, you should remove the whitespaces at the end and apply the same spaces with the same action. e.g: tab like the following;

Resources