Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0000008OCamlOCaml generalpublic1999-12-20 11:212000-02-07 14:11
Reporteradministrator 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000008: ocamldep generates wrong dependencies on .cmo in native-code-only project
DescriptionFull_Name: Markus Mottl
Version:
OS:
Submission from: estephe.inria.fr (128.93.11.95)
Submitted by: xleroy


> This has worked OK so far, so I'd like to understand better the
> problem those ".cmo dependencies" create in your example.

The problem is that I always use the corresponding compiler (native code or
byte code compiler) to generate the compiled interface files if there is no
.mli-file (if there is one, ocamlc will be used to compile the interface).

The intention is that I do not have to create superfluous .cmo-files when I
want to have native code only - i.e. I want to generate both the .cmi and
the .cmx-file in one step from the .ml-file to save compilation time.

This, of course, means that the way in which ocamldep prints dependencies
leads to problems, because the native code compiler will not emit a ".cmo"
file. This causes "make" to mistakenly recompile some files, because it
believes this will finally produce one.

Here part of an example "make"-run:

  ocamlopt -c -I /hame/markusm/prog/ocaml/lib ocaml_str.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib directory_intf.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib directory_impl.ml
  ocamlc -c \
                          -I /hame/markusm/prog/ocaml/lib flow.mli
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib flow.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib semantics.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib ocaml_str.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib directory_intf.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib directory_impl.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib semantics.ml
  ocamlc -c \
                          -I /hame/markusm/prog/ocaml/lib parser.mli
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib parser.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib scanner.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib main.ml

As can be seen, "ocaml_str.ml directory_intf.ml directory_impl.ml and
semantics.ml" are compiled two times.


I have solved this problem by replacing every ".cmo"-occurrence by ".cmi"
in the output of ocamldep. This works for both byte code and native code.

The above example then compiles in the minimum number of steps (and time):

  ocamlopt -c -I /hame/markusm/prog/ocaml/lib ocaml_str.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib directory_intf.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib directory_impl.ml
  ocamlc -c \
                          -I /hame/markusm/prog/ocaml/lib flow.mli
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib flow.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib semantics.ml
  ocamlc -c \
                          -I /hame/markusm/prog/ocaml/lib parser.mli
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib parser.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib scanner.ml
  ocamlopt -c -I /hame/markusm/prog/ocaml/lib main.ml

Your solution is probably simpler to use in a Makefile, but is not optimal
for generating native code. My current solution seems to work, but "sed"ing
ocamldep output is definitely also not very elegant...

Thanks, however, for pointing out the intention of your approach. It
brought me to an idea how to improve my generic Makefile (OcamlMakefile)...

Best regards,
Markus Mottl

--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl [^]


TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0000282)
administrator (administrator)
2000-02-07 14:10

> The intention is that I do not have to create superfluous .cmo-files when I
> want to have native code only - i.e. I want to generate both the .cmi and
> the .cmx-file in one step from the .ml-file to save compilation time.

As a partial solution to this problem, I have added a flag "-native" to
ocamldep
instructing it to generate dependencies on .cmx files (instead of .cmo files)
when no explicit interface (.mli file) exists. (If a .mli exists, ocamldep
generates dependencies on the corresponding .cmi, as always.)

- Xavier Leroy
(0000283)
administrator (administrator)
2000-02-07 14:11

Fixed in 3.00 (added -native flag to ocamldep)
(0000284)
administrator (administrator)
2000-02-07 16:27

> As a partial solution to this problem, I have added a flag "-native" to
> ocamldep
> instructing it to generate dependencies on .cmx files (instead of .cmo files)
> when no explicit interface (.mli file) exists. (If a .mli exists, ocamldep
> generates dependencies on the corresponding .cmi, as always.)

Thanks - this will allow me to get rid of the dependency preprocessing with
"sed"! The last solution has the same effect, only with more file system
accesses, but worked correctly in all common situations. So I think that
this new "partial" solution should be just fine...

Best regards,
Markus Mottl

--
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl [^]

(0000285)
administrator (administrator)
2002-02-13 19:04

Bonjour Nicolas,

> Le programme suivant génère des résultats différents suivant qu'on
> le compile avec ocamlc ou ocamlopt :

Ce n'est pas un bug, juste une feature de l'arithmétique flottante sur
le Pentium. Ce processeur calcule sur ses registres flottants en
précision étendue (80 bits), et arrondi à 64 bits lorsqu'on stocke un
résultat en mémoire. L'interprète de bytecode stocke en mémoire tous
les résultats intermédiaires d'un calcul flottant, mais pas ocamlopt:

> let pvect a b c d =
> (b.x-.a.x)*.(d.y-.c.y)-.(d.x-.c.x)*.(b.y-.a.y)

Ici, les soustractions et les produits sont faits en registres,
i.e. avec plus de précision.

Quand tu es dans un cas "limite" (on soustrait 2 nombres très
proches), ça peut donner des résultats nettement différents. Surtout
quand ensuite tu amplifies les différences par un test:

> tc > 0. && tc < 1. && ta > 0. && ta < 1.

Il suffit que tc = epsilon devienne tc = -epsilon pour faire passer
le résultat de true à false.

Le même phénomène peut s'observer sur des processeurs ayant une
instruction "multiply-add", comme le PowerPC et l'IA64. L'instruction
combinée est plus précise qu'une multiplication suivie d'une addition.

- Xavier Leroy


- Issue History
Date Modified Username Field Change
2005-11-18 10:13 administrator New Issue


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker