I'm starting an web development project and was hoping to use Js_of_ocaml. However, when attempting to use OCamlbuild as my build tool, I've encountered the following error:
Warning 58: no cmx file was found in path for module Ocamlbuild_js_of_ocaml, and its interface was not compiled with -opaque
My Makefile is as follows:
.SUFFIXES: .ml .mli .byte .js
OFLAGS= -use-ocamlfind \
-plugin-tag 'package(js_of_ocaml.ocamlbuild)'
%.js:
ocamlbuild $(OFLAGS) $<
clean:
ocamlbuild -clean
find . -iname *.js -delete
rm -rf build
My myocamlplugin.ml file contains the text from the documentation:
let _ = Ocamlbuild_plugin.dispatch Ocamlbuild_js_of_ocaml.dispatcher
Finally, I'm trying to compile a minimal test file:
open Js;;
let rec fact = function
| 0 -> 1
| n -> n * (fact (n - 1));;
print_int (fact 10);;
If it helps, I'm on Arch Linux running OCaml 4.03.0 and ocamlbuild 0.9.3.
Thanks in advance!
This is a warning, not an error, and you can safely ignore it.
It is here to tell you that the compiler might miss optimizations (since it needs .cmx to do inlining) ... but you really don't care about optimizations for the ocamlbuild plugin, so it's fine.
You can put a bug report on js_of_ocaml's bugtracker, though. .cmx files should be installed for everything. ;)
Related
I'm trying to get a custom compiler working in CLion and having a bear of a time. Can anyone help me find out what I'm doing wrong? I have the full code on Github.
What I have
The command line tools are all behind the same executable named mpw. So the C compiler is behind mpw SC, the linker is behind mpw link. There's also a tool named Rez to add some metadata to the executable, but I'm fine if CLion just ignores that.
I'm using a make file to do the actual build.
I've created a custom compiler definition YAML and selected it in CLion's project settings. I tried to follow the Jetbrains docs [1] [2] but couldn't find out what code insight target name to use (It eventually compiles for 68000 CPU, old MacOS, anyone know where I can find a list of allowed clangd target names?).
The Makefile works when I call make clean or make all from command line.
Problem
When I open the folder in CLion, it tries to parse the Makefile and reports:
(x) Analysing makefile
(x) No compilation commands found
Goal
Get CLion to see all my code (including system headers at ~/mpw/Interfaces/CIncludes) so I can use its code navigation to auto-complete code. Refactoring would be nice too.
Get CLion to understand my Makefile so I can build using the "hammer" icon inside CLion.
Custom Compiler Definition
compilers:
- description: "MPW SC"
match-sources: ".*\\.c"
match-language: "C"
match-compiler-exe: "(.*/)?mpw SC"
code-insight-target-name: mpw
include-dirs:
- ${user-home}/mpw/Interfaces/CIncludes
defines-text: "
#define __MRC__ 0x0700
#define OLDROUTINENAMES 1
"
Makefile
SOURCES=SillyBalls.c
RFILES=SillyBalls.r Size.r
EXECUTABLE=SillyBalls
MPW=~/Programming/mpw/build/bin/mpw
RINCLUDES=~/mpw/Interfaces/RIncludes
LDFLAGS =-w -c 'SILB' -t APPL \
-sn STDIO=Main -sn INTENV=Main -sn %A5Init=Main
LIBRARIES={Libraries}Stubs.o \
{Libraries}MacRuntime.o \
{Libraries}IntEnv.o \
{Libraries}Interface.o \
{Libraries}ToolLibs.o \
{CLibraries}StdCLib.o
TOOLBOXFLAGS=-d OLDROUTINENAMES=1 -typecheck relaxed
OBJECTS=$(SOURCES:%.c=obj/%.o)
all: prepass bin/$(EXECUTABLE)
prepass:
mkdir -p obj bin
bin/$(EXECUTABLE): $(OBJECTS)
$(MPW) link $(LDFLAGS) $(OBJECTS) $(LIBRARIES) -o $#
Rez -rd $(RFILES) -o $# -i $(RINCLUDES) -append
obj/%.o : %.c
$(MPW) SC $(TOOLBOXFLAGS) $< -o $#
clean:
rm -rf bin obj
Thanks to #JohnBollinger for getting me on the right track:
CLion is apparently not smart enough to recognize $(MPW) SC as mpw SC. If I change it to
CC="~/Programming/mpw/build/bin/mpw SC"
CLion is happy, but of course there is no file named mpw SC.
So my solution was to create a shell script sc.sh:
#!/bin/zsh
~/Programming/mpw/build/bin/mpw SC $#
and then set
CC=./sc.sh
and
match-compiler-exe: "(.*/)?sc.sh"
and then use ./sc.sh everywhere where I used to have $(MPW) SC
CLion recognizes it, starts indexing the system headers, and the "hammer" icon triggers a build all just as desired.
I've been trying to build Qhull for use on the net, and to be honest. I'm completely lost. I've already installed the Emscripten SDK, and I've tried reading through the guides. From what I can gather, it seems that there are two ways to compile a large project like this one: I can either pass the files as arguments to emcc, or I can make my own custom Makefile that somehow does that for me. But I can neither figure out how to pass multiple files as arguments, nor how Makefiles work.
After scouring the web, I managed to find this port of an old Qhull version, which comes with its own Makefile:
QHULL_PATH = ./src/libqhull
TARGET = qhull.js
EMCC = ../emscripten/emcc
PREJS = ./src/pre.js
POSTJS = ./src/post.js
MAIN = ./src/main.c
EXPORTJS = "['_run_qhull']"
CFLAGS = -O1
SOURCES := $(shell find $(QHULL_PATH) -type f -name '*.c')
all: $(TARGET)
#echo "Done"
$(TARGET): $(SOURCES) $(PREJS) $(POSTJS) $(MAIN)
$(EMCC) $(CFLAGS) $(SOURCES) $(MAIN) -s EXPORTED_FUNCTIONS=$(EXPORTJS) --pre-js $(PREJS) --post-js $(POSTJS) -o $(TARGET)
clean:
rm -rf $(TARGET)
Unfortunately, the Makefile is in the Unix format, which I only figured out after about two hours of frustration. I don't know how to make it work on Windows.
So, what can I do to get the latest version of Qhull running in Javascript?
I'm using Windows, and my current IDE is Dev-C++.
So if you're new to compiling, using emscripten to compile a large library is going to be a big challenge. I suggest reading through the emscripten docs on compiling.
It looks like Qhull has both a MakeFile and a CMakeLists.txt. I suggest trying CMake.
The typical way to use CMake with emscripten on linux is something like this:
mkdir embuild
cd embuild
emcmake cmake ..
emmake make
I've never compiled on Windows (I use linux), but I believe that (at least when using Cmake) it is similar.
That probably won't work on the first try.
If (after many tries) you can't get it working, you could try compiling qhull manually with emcc. It looks harder at first, but in the long run I usually get fewer errors.
I am new to Erlang, so i am going through Joe Armstrong's book "Programming Erlang". In chapter 25 there's an example on how to work with rebar. I followed the instructions and created a Makefile
all:
test -d deps || rebar get-deps
rebar compile -v
#erl -noshell -pa './deps/bitcask/ebin' -pa './ebin' -s myapp start
and rebar.config
{deps, [
{bitcask, ".*", {git, "git://github.com/basho/bitcask.git", "master"}}
]}.
Getting the dependencies works, but compiling fails.
The verbose output tells me that this command fails
cmd: cc -c $CFLAGS -g -Wall -fPIC -I"/usr/lib/erlang/lib/erl_interface-3.7.18/include" -I"/usr/lib/erlang/erts-6.2/include" c_src/bitcask_nifs.c -o c_src/bitcask_nifs.o
with this error
/home/user/folder/deps/bitcask/c_src/bitcask_nifs.c:22:19: fatal error: errno.h: No such file or directory
But
find /usr/include -name errno.h
gives me
/usr/include/x86_64-linux-gnu/asm/errno.h
/usr/include/asm/errno.h
/usr/include/linux/errno.h
/usr/include/asm-generic/errno.h
So I was asking myself..
what am I missing?
how can I tell rebar about the depencies on the C libraries and where to find them?
why isn't this configured correctly in the Makefile of bitcask?
Maybe I was searching for the wrong terms, but I couldn't find any solution in the internets.
Many thanks in advance
There are two thing to consider
rebar options
You can set options for compiling C code with port_env option in rebar.config.
comiling deps
Since bitstack is your dependency, it is not compiled with yours rebar config, but with it's own. So if you would like to change anything, you would have to modify the bitcask file.
Fortunately, if you look into config their writen all C compilation is done with environment variable $ERL_CFLAGS. And again, in rebar source code you can see that this flag is responsible for include paths in your compilation.
So easist way would be extending $ERL_CFLAGS in your Makefile before compilation, with something like this
all: ERL_CFLAGS = "$ERL_CFLAGS -I /usr/include/linux/errno.h"
all:
test -d deps || rebar get-deps
rebar compile -v
#erl -noshell -pa './deps/bitcask/ebin' -pa './ebin' -s myapp start
Just make sure that this include works for you, and that you are not overwriting any flags you are using.
I am trying to learn to C programing using Zed Shaw's Learn C the hard way. I have been working on ex26 where we create a program "devpkg" used to install software. This exercise requires installing Apache Portable Runtime library. After writing the code for this exercise I could not get program to compile using the following makefile:
PREFIX?=/user/local
CFLAGS=-g -Wall -I${PREFIX}/apr/include/apr-1 -I{PREFIX}/apr/include/apr-util-1
LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
all: devpkg
install: all
install -d${DESTDIR}/${PREFIX}/bin/
install devpkg ${DESTDIR}/${PREFIX}/bin/
clean:
rm -f *.o
rm -f devpkg
rm -f *.dSYM
This makefile did not seem to work as when I used "$make devpkg" not all of the APR library functions were declared. As a side note I am running this on a Ubuntu virtual machine. A solution given in the text says to alter a config file and then "run ldconfig" to help the linker find the appropriate library.
I do not understand the man page for ldconfig well enough to correctly utilize the function. How do run ldconfig correctly?
Also after some digging I found a reference that using "LDLIBS" instead of "LDFLAGS" in the makefile fixed the problem. I altered the makefile and the program compiled.
What is the difference between "LDFLAGS" and "LDLIBS" that allowed the C compiler to correctly link to the APR library? Is there a handy list of commands somewhere that can help me better understand how a makefile is correctly generated?
Thanks for your time.
From the GNU Make Manual, section 10.2 Catalogue of Implicit Rules:
Linking a single object file
n is made automatically from n.o by running the linker (usually called ld) via the C compiler. The precise recipe used is '$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)'.
As you can see, LDFLAGS comes before your object file and LDLIBS after. Sometimes that order can matter - apparently it does in your case.
Editorial note: While it might sometimes be convenient to use make's implicit rule support, it almost always ends up more confusing down the road. I'd urge you to write a complete makefile - it'll help you understand what's going on better and hopefully avoid this sort of problem in the future.
I just wanted to add this answer as an alternative to changing "LDFLAGS" to "LDLIBS". The above solution did work in my case but I found an alternative (though less direct) solution before I saw this thread which others may find useful or interesting. When compiling I was seeing lots of "undefined reference" errors e.g.:
/MyCode/LCTHW/devpkg/devpkg.c:18: undefined reference to `apr_pool_initialize'
After much trial and error, I changed the makefile thus (still using LDFLAGS):
CC=gcc
PREFIX?=/usr/local
CFLAGS=-g -Wall -I$(PREFIX)/apr/include/apr-1 -I$(PREFIX)/apr/include/apr-util-1
LDFLAGS=-L$(PREFIX)/apr/lib -lapr-1 -laprutil-1 -pthread
OBJECTS=bstrlib.o db.o shell.o commands.o devpkg.o
all: devpkg
devpkg: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o devpkg $(LDFLAGS)
install: all
install -d $(DESTDIR)/$(PREFIX)/bin/
install devpkg $(DESTDIR)/$(PREFIX)/bin/
clean:
rm -f *.o
rm -f devpkg
rm -rf *.dSYM
I then had to add a .conf file to /etc/ld.so.conf.d containing the path to the apr libraries, namely
/usr/local/apr/lib
And then run
sudo ldconfig
so the system would pick up the new .conf file and so know where to find the library. From what I have read, it seems this last step was necessary because the library wasn't stored in /usr/local/lib. If I remove the .conf file and re-run ldconfig to update, the program compiles but then fails to find the libraries at run-time (whether compiled with my makefile or OP's).
While I don't fully understand my solution, it at least allowed me to compile and run the program with no errors. Hopefully this solution will be of interest to others, and maybe somebody more knowledgeable will be able to explain in more detail why it works.
Following is the directory structure of my project:
expt-main
---------
Makefile_main
/ \
subdir-1 subdir-2
-------- --------
Makefile_1 Makefile_2
mod_codeA.f90 mod_code1.f90
mod_codeB.f90 mod_code2.f90
mod_codeC.f90 mod_code3.f90
Makefile_main:
export
SHELL = /bin/sh
F90 = mpxlf95
SRCDIRS = $(subdir-1) $(subdir-2)
all:
#for DIR in ${SRCDIRS} ;
do \
back=`pwd`; \
cd $$DIR ;\
$(MAKE) ; status=$$? ; \
if [ $$status != 0 ] ; then \
echo "Exit status fro make was $$status" ; exit $$status ; \
fi ; \
cd $$back ; \
done
-------------------------------------------------------------------------------
Makefile-1:
%.o: %.f90
$(F90) $(F90FLAGS) -I$(subdir-2) -c $<
mod_codeA.o: mod_codeC.o $(subdir-2)/mod_code2.o
-------------------------------------------------------------------------------
Makefile-2:
PROG = $(exec)
subdir-1_objs = $(subdir-1)/mod_codeA.o mod_codeB.o mod_codeC.o
all: $(PROG)
$(PROG): $(subdir-2_objs) $(subdir-1_objs) -o $# $(subdir-2_objs) $(subdir-1_objs)
---------------------------------------------------------------------------------
-
I've written the Makefile_main such that it compiles the codes (modules) in subdir-1 first and then the ones in subdir-2 and finally makes the executable. The issue: modules in subdir-1 uses modules from subdir-2 and in similar fashion, modules in subdir-2 uses those in subdir-1. My make is getting failed because the modules being used is in other directory. How to write a makefile which will take care of this issue that is, while compiling modules in subdir-1, whenever it encounters the need for an object file from subdir-2, it should switch to subdir-2 compile the necessary modules and return back to subdir-1 for further action?
If modules in different subdirectories need each other as you say, then this is not a good use of recursive Make.
Do away with Makefile-1 and Makefile-2, and let Makefile_main do all the work. (I can't tell you specifically how to change Makefile-main, since I don't do Fortran, I don't understand Makefile-2, and I don't see any dependency of modules in subdir-2 upon those in subdir-1).
If you want to stick to this directory layout and still keep three separated Makefiles, then you can use compiler flags to instruct the FORTRAN compiler to put module files into a common directory of your choice.
For instance using:
$ gfortran --version
GNU Fortran (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
you can use -I and -J flags to instruct the compiler on:
where to search for module files (.mod)
where to put generated module files
That said I think that the suggestion given by Beta to join the Makefiles makes a lot of sense. To know some of the reasons why you should do that you can read this paper.
Finally, as your project seems not to be very large at this stage, I also suggest to take into consideration CMake as a build system, as it possibly provides a more convenient way of specifying dependencies between targets (as well as many other things).