QMAKE_EXTRA_COMPILER execution order - fortran

Is there some way to arbitrarily assign an order on when the make is performed for the QMAKE_EXTRA_COMPILER option? It seems that declaration order seems to affect it, but it doesn't work it seems...
I have a bunch of fortran code that needs to be compiled then archived into a static library (using the ar command) to be used by a DLL I'm building. Iv been streamlining this in my .pro file to make everything happen in one go but am having a little trouble.
Heres the important stuff:
win32 {
gfortran.commands = gfortran $${FORTRAN_FLAGS} ${QMAKE_FILE_NAME} -c -o ${QMAKE_FILE_OUT}
gfortran.input = FORTRAN_SOURCE
gfortran.output = ../../src/SupMods/FireNetworkDLL/${QMAKE_FILE_BASE}.o
gfortran.CONFIG = target_predeps
QMAKE_EXTRA_COMPILERS += gfortran
}
win32 {
archive.commands = ar -qsc ${QMAKE_FILE_OUT} $${FORTRAN_OBJ}
archive.input = FORTRAN_OBJ
archive.output = ../../src/SupMods/FireNetworkDLL/libORAN.a
archive.CONFIG = combine target_predeps
QMAKE_EXTRA_COMPILERS += archive
}
This only works some of the time...no idea why. Also FORTRAN_SOURCE is just a list of all the fortran files (ex: fire.f95) and $${FORTRAN_OBJ} is a list of all the fortran .o files.
So is there some way I can always have the object files generated from gfortran first and follow that by the ar command? (im guessing it has something to do with dependency_type or depends...)
Also if someone has a better approach I'm all ears, first time messing with qmake really.
**Could this have something to do with the variable FORTRAN_OBJ referencing .o files that aren't actually there before the build start?

The order of processing of qmake extra compilers is determined by chaning of input/output variables of the compilers. For example, if the first compiler gets input files from the variable A and writes output file names to the variable B and the second compilers gets its files from the variable B, then the first compiller will be processed by the qmake before the second.
It is unclear from your sources how you populate FORTRAN_OBJ variable. Judging from the symptoms you report I suspect you fill the variable by hand. I suggest not to. Let the QMAKE_EXTRA_COMPILER to do the work automatically.
The following code should work (untested):
gfortran.commands = gfortran $${FORTRAN_FLAGS} ${QMAKE_FILE_NAME} -c -o ${QMAKE_FILE_OUT}
gfortran.input = FORTRAN_SOURCE
gfortran.output = ../../src/SupMods/FireNetworkDLL/${QMAKE_FILE_BASE}.o
gfortran.CONFIG = target_predeps
# the only change required I guess
gfortran.variable_out = FORTRAN_OBJ
QMAKE_EXTRA_COMPILERS += gfortran
archive.commands = ar -qsc ${QMAKE_FILE_OUT} $${FORTRAN_OBJ}
archive.input = FORTRAN_OBJ
# I suggest to use $$OUT_PWD here
archive.output = ../../src/SupMods/FireNetworkDLL/libORAN.a
archive.CONFIG = combine target_predeps
QMAKE_EXTRA_COMPILERS += archive
Do not confuse processing order (generating rules to a Makefile by qmake) with execution order (execution of the rules when running make). In general the last have to be managed carefully by specifying dependencies between targets. But in this case all needed dependencies will be generated automatically thanks to the fact that by default qmake generates a dependency for each pair of the corresponding in and out files. So in this case libORAN.a will depend on all the files in FORTRAN_OBJ variable which in turn will depend on the corresponding source fortran files and the proper sequence of events is guaranteed.
If you can read Russian there is more info about QMAKE_EXTRA_COMPILERS in my blog.

Well... ended up just adding all the object files to the final DLL instead of using a static library! Should have done that awhile ago...

Related

makefile file name parameter

I remember doing this in my advanced C++ class, but it's been a couple years and I forgot.
I want to make a sort of simple re-usable makefile where I just type "make programName" and it compiles programName.cpp into programName.exe.
I've looked for this for a couple hours, but haven't found what I need. I know this will get marked as duplicate, but at least point me to what I need.
Make has a built-in variable called $(MAKECMDGOALS), which contains all targets specified as command line parameters.
You can use it to generate recipes, like so:
# Stop if 0 or 2+ targets were specified.
$(if $(filter-out 1,$(words $(MAKECMDGOALS))),$(error Expected one target))
name := $(MAKECMDGOALS)
$(name).exe: $(name).cpp
g++ $^ -o $#
Adding a way to customize compiler executable and flags is left as an exercise to the reader. As well as conditionally removing .exe from the target name when building on Linux.
Why do you want your output to be suffixed with .exe? That's a Windows convention that is not followed on POSIX systems like Linux.
If you don't want that you don't even need a makefile at all. You can type make programName with no makefile and if you have a file programName.c, it will be built into an executable programName via make's built-in rules.

Using External Binary Resource

I'm on a project that used to have Compiled-in Resources.
Now, the user can choose the theme that he wants to work on. No problems until there, in a little research I started to use the External Binary Resource approach.
My resources were build successfully and the QResource::registerResource("/path/to/myresource.rcc"); returns true.
It is not working properly though. Apparently the compiled-in resource is still there, in the executable. I can't see the different icons stored in my external binary resource.
How do I remove this compiled-in resource? Do I need to do that to work properly?
Assuming you are using a .pro file for your project, you need to remove the resource file from the RESOURCES list. If you still want it to be listed in your project, you can use OTHER_FILES.
Before:
RESOURCES += file1.qrc file2.qrc
After:
RESOURCES += file2.qrc
OTHER_FILES += file1.qrc
If you want to go a step further you can automate the build of qrc files:
RCC_BINARY_SOURCES += file1.qrc
asset_builder.commands = $$[QT_HOST_BINS]/rcc -binary ${QMAKE_FILE_IN} -o ${QMAKE_FILE_OUT} -no-compress
asset_builder.depend_command = $$[QT_HOST_BINS]/rcc -list $$QMAKE_RESOURCE_FLAGS ${QMAKE_FILE_IN}
asset_builder.input = RCC_BINARY_SOURCES
asset_builder.output = $$OUT_PWD/$$DESTDIR/${QMAKE_FILE_IN_BASE}.qrb
asset_builder.CONFIG += no_link target_predeps
QMAKE_EXTRA_COMPILERS += asset_builder
OTHER_FILES += $$RCC_BINARY_SOURCES
You have to change the way the resources are compiled. By default, every resource file (resources.qrc, for example) included in a Qt project is compiled to C++ code (the qrc_resources.cpp you've probably seen after compiling the project). That makes the resource is compiled and linked with your executable (or library). The Qt for Visual Studio plugin does exactly that: adds a custom build step to every QRC file. Open the properties of the QRC file to take a look (right-click on the QRC file, then Properties):
Command line: "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" -no-compress "%(FullPath)" -o .\GeneratedFiles\qrc_%(Filename).cpp
Outputs: .\GeneratedFiles\qrc_%(Filename).cpp
%(Filename) is, as you can figure out, the extension-less name of the file
To avoid this behaviour just remove the QRC file from the project. Of course, the problem is that you'll have to manually build the .rcc file. You can do it using a script as part of your makefile.
On the other hand, if you're using Visual Studio, you can change the command used to compile it, adding the -binary option to the rcc tool so it compiles to an external file. In this way it will be included in your usual compilation workflow:
Command line: "$(QTDIR)\bin\rcc.exe" -name "%(Filename)" "%(FullPath)" -binary -o "%(Outputs)"
Outputs: $(OutDir)\%(Filename).rcc - it is different from screenshot because I took it from an existing project, use the one in the text to place the RCC file in the same dir of your executable.
Important note: be sure you change the build tool for all the configurations.
If you use a makefile or Qt Creator instead, you can use this as a base to create the needed script.
Hope this can help you.

Automake AM_LDADD workaround

I want to set the same LDADD attribute (Unit test library) to a large number of targets (unit test C++ files). I first though that maybe automake has AM_LDADD variable to add that library to all the targets within the file but is not the case.
In some mail list I found some short discussion asking to add it:
http://gnu-automake.7480.n7.nabble.com/AM-LIBS-AM-LDADD-td3698.html
My question is, how do you deal with that? is it there any way to avoid manually adding LDADD attribute to each target?
So far my Makefile.am looks like:
test1_SOURCES = ...
test1_LDADD = -llibrary
...
...
test20_SOURCES = ...
test20_LDADD = -llibrary
The equivalent of an AM_LDADD variable is simply LDADD. e.g.,
LDADD = -llibrary
test1_SOURCES = ...
...
test20_SOURCES = ...
If you need to override LDADD for a particular program: prog, then prog_LDADD will always take precedence.
I always assumed that since there was no LDADD standard environment variable passed to configure - as you can see with configure --help - there is no real reason for an AM_LDADD. This kind of makes sense, as the configure script, and any options, e.g., --with-foo=<path> should (ideally) work out the library dependencies.
On the other hand, passing CFLAGS via configure might still need an AM_CFLAGS that combines CFLAGS and with other compiler flags determined by the configure script; or even a foo_CFLAGS override. Since configure must be informed of your custom CFLAGS.
Also, I don't know if the test<n> programs only take a single C++ source file, but if so, you can simplify the Makefile.am with:
LDADD = -llibrary
check_PROGRAMS = test1 test2 ... test20
AM_DEFAULT_SOURCE_EXT = .cc # or .cpp
as described here.
In regards to your comment, your can use a convenience library for that purpose - which is particularly useful for common code used by test programs:
noinst_LIBRARIES = libfoo.a # or noinst_LTLIBRARIES = libfoo.la
libfoo_a_SOURCES = MyClass.hh MyClass.cc # or libfoo_la_SOURCES
LDADD = ./libfoo.a -llibrary # or libfoo.la if using libtool.
... etc ...
It's a bad idea to modify LDADD in your Makefile.am, even if it seems convenient. It will make your build system very fragile.
In particular, if the user attempts to override LDADD from the make command line, then your definition of LDADD in Makefile.am will disappear. It's not unreasonable to expect that a user might override LDADD, so you should definitely protect yourself against this situation.
Your original definitions of test1_LDADD, ...,test20_LDADD are much more robust and, as far as I understand the automake manual, the recommended use.
See the remarks here for more info:
https://www.gnu.org/software/automake/manual/html_node/User-Variables.html
https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html

Makefile process different files in different steps

I have the following makefile using GNU autotools:
AUTOMAKE_OPTIONS = subdir-objects
bin_PROGRAMS = app
app_SOURCES = \
core/main.cpp
nodist_app_SOURCES = \
index.cpp \
index.ecpp.js.cpp
AM_INCLUDES = -I$(top_srcdir)/src
index.cpp: index.ecpp
$(ECPPC) index.ecpp -o index.cpp
index.ecpp.js.cpp: index.ecpp.js
$(ECPPC) -b index.ecpp.js
index.ecpp:
vulcanize -o index.ecpp core/view/index.html --inline --strip --csp
What happens (in this case only for index.html):
vulcanize creates a .ecpp and a .ecpp.js file out of a .html file
those newly created files are compiled to .cpp files by the ecppc compiler
the created .cpp files are compiled with g++
I have a lot of .html files which need to be processed, how can I accomplish that?
You can use either Suffix rules or Pattern rules. In your case, both should do the job equally well.
The only difference is that Pattern rules are GNU-Make-specific (not compatible with Unix make), though the GNU manual I linked to discourages the use of the Suffix rules, probably because its possible use cases are a lot more limited than those of Pattern rules.

CXXSources-- what are they?

I'm new to compiling C/C++ with the aid of make. I downloaded an open source project and noticed that there is in the make file CXXSources and CXXObjects. I think I understand roughly what the make file is doing with them but...
I don't have any of the source files listed under CXXSources. Are these like dependences I'm supposed to know how to find? Is there any custom as to what CXXSource is versus just Source?
Added link to project: http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html
More specifically, the GML parser, eg. http://www.fim.uni-passau.de/fileadmin/files/lehrstuhl/brandenburg/projekte/gml/gml-parser.tar.gz
It seems to be getting stuck on the line:
gml_to_graph : $(CXXOBJECTS) gml_scanner.o gml_parser.o
$(CXX) -o gml_to_graph_demo $(CXXOBJECTS) gml_parser.o gml_scanner.o -L$(LEDADIR)/lib -lG -lL -lm
The $CXXObjects is defined by
CXXSOURCES = gml_to_graph.cc gml_to_graph_demo.cc
CXXOBJECTS = $(CXXSOURCES:.cc=.o)
So I need gml_to_graph.cc, it seems. Or maybe I'm wrong?
Usually, the variables are set before the point where you see them. This could be
(a) via the environment
(b) before including the quoted makefile
(c) in the quoted makefile, but preceding the location quoted
To see (verbosely) what GNU make takes into account, do:
make -Bn
(it will show everything that _would get executed)
Even more verbose:
make -p all
It will show you all the internal variable expansions.
If you post a link or more information, we will be able to come up with less generic (and hence possibly less confusing) answers