Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ocamldep generates wrong dependencies on .cmo in native-code-only project #2333

Closed
vicuna opened this issue Dec 20, 1999 · 4 comments
Closed
Labels

Comments

@vicuna
Copy link

vicuna commented Dec 20, 1999

Original bug ID: 8
Reporter: administrator
Status: closed
Resolution: fixed
Priority: normal
Severity: minor
Category: ~DO NOT USE (was: OCaml general)

Bug description

Full_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

@vicuna
Copy link
Author

vicuna commented Feb 7, 2000

Comment author: administrator

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

@vicuna
Copy link
Author

vicuna commented Feb 7, 2000

Comment author: administrator

Fixed in 3.00 (added -native flag to ocamldep)

@vicuna vicuna closed this as completed Feb 7, 2000
@vicuna
Copy link
Author

vicuna commented Feb 7, 2000

Comment author: administrator

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

@vicuna
Copy link
Author

vicuna commented Feb 13, 2002

Comment author: administrator

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

@vicuna vicuna added the bug label Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant