"Eric M. Ludlam" <eric@...> writes:
>>> At a guess, you could have the initialize-instance method for one kind
>>> of fortran module automatically create the other target either before,
>>> or after itself. That way a user only needs to make one kind of
>>> target, and they get ordered properly.
>>
>>But what if I already created a 'program' target, and decide later I
>>want to put some of the code into a module? Maybe I should create a
>>completely new 'fortran' target, which doesn't inherit from the
>>makefile-objectcode class, and which has support for modules?
>>
>>> We can also add a configuration piece to control the 'append' input
>>> to object-add-to-list above.
>>
>>I think it would be good to have some slot in the target class which
>>controls that. Maybe just a boolean 'append', or maybe something like
>>'priority' which holds an integer, and targets would be sorted according
>>to that?
> [ ... ]
>
> Your last idea is probably the best. It is unfortunate that the
> single compiler notation doesn't work.
>
> Once you have the fortran piece working, we could look at it to see if
> the generic "objectcode" version could be adapted to handle a
> two-target scenario in an easy way.
Maybe the best way to solve this 'module' problem is to just use the
'uselinker' slot, since the main difference for these "*.mod" files is
that they do not get linked. So here's what I've done:
* In ede-proj-obj.el I've included definitions for ede-source-f90/f77,
ede-gfortran-compiler and ede-gfortran-module-compiler. The latter is
a clone of the former, but with 'uselinker' set to nil (for details
see the attached defvar's).
* I've included these in ede-proj-target-makefile-objectcode.
* Now I create a new 'Make' project, load my module source code, create
a new 'program' target called "mymodule" and choose the
ede-gfortran-module-compiler for that target and set the linker to
'none'.
* However, compilation fails. EDE still inserts a linker command,
although the linker is set to 'none' and the 'uselinker' slot from the
compiler is 'nil'.
To solve this, I'd like to suggest to following patch, which will insert
the linker command only if any of the compilers has 'uselinker' set to t:
--8<---------------cut here---------------start------------->8---
--- ede-pmake.el.~1.56.~ Thu Mar 12 23:38:21 2009
+++ ede-pmake.el Mon Apr 27 14:33:59 2009
@@ -589,7 +589,11 @@
"Insert the commands needed by target THIS.
For targets, insert the commands needed by the chosen compiler."
(mapc 'ede-proj-makefile-insert-commands (ede-proj-compilers this))
- (mapc 'ede-proj-makefile-insert-commands (ede-proj-linkers this)))
+ (when (member t
+ (mapcar (lambda (c)
+ (oref c uselinker))
+ (ede-proj-compilers this)))
+ (mapc 'ede-proj-makefile-insert-commands (ede-proj-linkers this))))
(defmethod ede-proj-makefile-insert-user-rules ((this ede-proj-project))
"Insert user specified rules needed by THIS target.
--8<---------------cut here---------------end--------------->8---
(BTW, why can a target have more than one compiler/linker?)
Now, there still remains the problem how the order of the targets can be
determined. Instead of introducing a new slot, maybe there could be a
simple way to change the order of the target through customize? At the
moment, I can call ede-customize-project and choose "targets", but I
cannot change the order there. I think two buttons like "UP" and "DOWN"
next to "[INS] [DEL]" should be enough. The user could then easily bump
targets to the top.
Regards,
David
Here are the above mentioned defvar's:
(defvar ede-source-f90
(ede-sourcecode "ede-source-f90"
:name "Fortran 90/95"
:sourcepattern "\\.[fF]9[05]$"
:auxsourcepattern "\\.incf$"
:garbagepattern '("*.o" ".deps/*.P"))
"Fortran 90/95 source code definition.")
(defvar ede-source-f77
(ede-sourcecode "ede-source-f77"
:name "Fortran 77"
:sourcepattern "\\.\\([fF]\\|for\\)$"
:auxsourcepattern "\\.incf$"
:garbagepattern '("*.o" ".deps/*.P"))
"Fortran 77 source code definition.")
(defvar ede-gfortran-compiler
(ede-object-compiler
"ede-f90-compiler-gfortran"
:name "gfortran"
:dependencyvar '("F90_DEPENDENCIES" . "-Wp,-MD,.deps/$(*F).P")
:variables '(("F90" . "gfortran")
("F90_COMPILE" .
"$(F90) $(DEFS) $(INCLUDES) $(F90FLAGS)"))
:rules (list (ede-makefile-rule
"f90-inference-rule"
:target "%.o"
:dependencies "%.f90"
:rules '("@echo '$(F90_COMPILE) -c $<'; \\"
"$(F90_COMPILE) $(F90_DEPENDENCIES) -o $@ -c $<"
)
))
:sourcetype '(ede-source-f90 ede-source-f77)
:objectextention ".o"
:makedepends t
:uselinker t)
"Compiler for Fortran 90/95 sourcecode.")
(defvar ede-gfortran-module-compiler
(clone ede-gfortran-compiler
"ede-f90-module-compiler-gfortran"
:name "gfortranmod"
:sourcetype '(ede-source-f90)
:commands '("$(F90_COMPILE) -c $^")
:objectextention ".mod"
:uselinker nil)
"Compiler for Fortran 90/95 modules.")
(defvar ede-gfortran-linker
(ede-linker
"ede-gfortran-linker"
:name "gfortran"
;; Only use this linker when c++ exists.
:sourcetype '(ede-source-f90 ede-source-f77)
:variables '(("F90_LINK" .
"$(F90) $(CFLAGS) $(LDFLAGS) -L. -o $@")
)
:commands '("$(F90_LINK) $^")
:objectextention "")
"Linker needed for Fortran programs.")
|