How to build Qhull into Javascript with Emscripten? - windows

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.

Related

`make` doesn't notice modifications in a Rust module - how to better integrate Rust into the build?

In a simple embedded project, i have two files main.rs and module.rs. To build the project, I use something similar to this:
all: main.o
$(CC) main.o $(LDFLAGS)
%.o: %.rs
$(RUSTC) $(RUSTFLAGS) -o ${#} ${<}
If only module.rs is changed, make all won't recompile my Rust code. How can I fix this?
I'm posting a suboptimal self-answer as a first step, but would love to see better ways.
The best way to use Make is to encode every single dependency into the Makefile. That's what gives Make the power to know what to rebuild in order to reach a goal state.
To do this for a C project, you'll often use something like the GCC command line option -M. This brings the compiler into the mix as it's the best tool to parse C source code and understand the dependencies between the
files.
There is actually an equivalent switch for rustc, the Rust compiler: --emit=dep-info. When you run this on a source file, it will output a file with the extension .d, which contains an almost-Makefile-compatible list of dependencies. If you had a main.rs that referenced the module foo.rs, it would output something like:
main.d: main.rs foo.rs
With a bit of sed tweaking you can get this to play nicely. You can then include this in your Makefile:
main.o:
rustc -o $# $<
main.d: main.rs
rustc --emit=dep-info $<
# Add the object file as a rule
gsed 's/:/ $(#:.d=.o):/' -i $#
-include main.d
Here, I've specified main in a few parts, but I believe that you can easily modify them into pattern rules.
The pragmatic solution is to just use Cargo, the Rust build tool and package manager. Let it deal with dependencies (both local modules and other crates).
libbar.dylib: target/debug/libbar.dylib
cp $< $#
.PHONY: target/debug/libbar.dylib
target/debug/libbar.dylib:
cargo build --verbose
Here, I've marked the rule as PHONY, which says "always run this rule". I've added --verbose to have Cargo print out what it is doing so you can verify when things are rebuilt.
I'd recommend dropping off the cp step if you can and instead just use the nested path, but the copy might be needed if other things rely on the current location.
The pattern
%.o: %.rs
is familiar from building C projects, but that's not the only way a target can be written. Specific to the setup above, this would fix the situation:
main.o: main.rs module.rs
$(RUSTC) $(RUSTFLAGS) -o main.o main.rs
A noteworthy difference to the original code is that the names of the inputs is not really what matters for the command. We can generalize this as follows:
main.o: $(wildcard *.rs)
$(RUSTC) $(RUSTFLAGS) -o ${#} ${#:.o=.rs}
This is a start, but it still has some downsides I couldn't get rid of:
The main.o: part is hardcoded. If there are multiple top-level modules to compile, there would be code duplication
All Rust files will be considered for all top-level modules, due to the wildcard. In other words, changing any Rust file will require a full recompilation.

make command with math library

I need to just run the make command for makefile. But when I run this make command I get the error that "undefined reference to `log'" because I know this fact that it doesn't include math Library and we have to include at runtime. I know that if I run this using gcc comiler then i can write -lm at the end, it will include math library. My problem is I need to run it using make command that is- make lu.
In this if I write make lu -lm it is not linking math library. Please help
Using this link How to use LDFLAGS in makefile
I updated my make file but still same problem persists. Please Help.
SHELL=/bin/sh
BENCHMARK=ep
BENCHMARKU=EP
include ../config/make.def
OBJS = ep.o ${COMMON}/c_print_results.o ${COMMON}/c_${RAND}.o \
${COMMON}/c_timers.o ${COMMON}/c_wtime.o
include ../sys/make.common
LDLIBS=-lm
LDFLAGS=-lm
${PROGRAM}: config ${OBJS}
${CLINK} ${CLINKFLAGS} -o ${PROGRAM} $(LDFLAGS) $(LOADLIBES) ${OBJS} ${C_LIB}
ep.o: ep.c npbparams.h
${CCOMPILE} ep.c
clean:
- rm -f *.o *~
- rm -f npbparams.h core
Why does your makefile refer to all sorts of variables that don't exist, like LOADLIBES, C_LIB? Why do you set variables that you never use, like LDLIBS?
The reason it doesn't work is that you're putting the library reference in the LDFLAGS variable, which comes early in your link command before any of your object files. So when the linker goes to link in the math library it thinks that it's not needed because nothing is using it yet.
You have to put libraries at the end of the link line.
Since you already have the C_LIB variable at the end which you are not using, if you add:
C_LIB = -lm
then it should work.

How can I use a makefile for D?

I have written complicated C and C++ makefiles in the past. However, I cannot seem to get my D makefile to work. It throws over a thousand lines of "undefined reference" errors, which look as if Phobos is failing to be linked. How can I fix that?
I am using GNU make and LDC2 on Fedora 19 Linux.
Edit: Compiling and linking directly using LDC2 works correctly. Only when invoked with 'make' is there an error. It seems that make is trying to invoke a separate linker.
Edit 2: Here is my makefile:
# This macro contains the source files
sources := $(wildcard *.d)
binaries := $(sources:%.d=%)
all: $(binaries)
%.o:%.d
ldc2 $< -O5 -check-printf-calls
Deleting the .o fixed it.
I don't know the intricacies of Pattern Rules, but I believe that is where your problem lies.
%.o:%.d
ldc2 $< -O5 -check-printf-calls
You've asked make to convert every .d file into a .o by calling the ldc2 command. However, you aren't requesting ldc2 to build object files, you're asking it to build an executable (I don't know which flag you want dmd/gdc: -c). Though I would have expected compiler errors from this before linker.
By removing the .o I must assume that Make is instead passing all the .d files at once rather than individually.

Library Linking

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.

Portable make clean rule

I am writing a smallish C program for fun. I decided to just use MinGW (only C), make and Notepad++ as an exercise in not using fancy IDEs for a change. So far so good and fun.
(MinGW == I am working on Windows.)
Now since the program compiles against vanilla C I thought of making it fully portable. MinGW make and gcc is smart enough create a program from the rule:
myprog: myprog.o other.o
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $#
Obviously, since I am on windows the compiler creates myprog.exe. This is quite smart and makes the entire thing quite portable.
As far as standard targets go I want to at least implement clean since I actually use that rule. Now the clean target, that actually works on Windows looks like this:
clean:
rm myprog.exe *.o
This rule will definitely not work in a POSIX environment, because programs don't have extensions there. (PSOIX: think GNU/Linux)
Is there a portable way implement a clean without to much make fu?
So far I have not found any really useful documentation around this issue. If you look at how autoconf and automake tackle the issue, they introduce the pattern #EXEEXT#. But that relies on lengthy configure code testing the environment.
Define the binary name as a variable (optionally deduce it from the name of the source file defining "main()" with a simple egrep command):
EXE_EXT_LINUX:=
EXE_EXT_WINDOWS:=exe
EXE_EXT:=$(EXE_EXT_$(PLATF))
BINARY_NAME:=$(notdir $(basename $(shell egrep -r -l --include=*.cpp '^[ \t]*?int[ \t]*?main[ \t]*?\(') ) )$(EXE_EXT)
And use this macro instead of hardcoded name
If solved it the following way:
UNAME = $(shell uname -o)
ifeq ($(UNAME), Msys)
EXEEXT = .exe
endif
clean:
rm *.o myprog$(EXEEXT)
It solved the issue quite nicely. Although it is not totally 100% portable it works most common cases.

Resources