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.
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'm trying to setup a Makefile to compile my Rust project. To speed things up I don't want to recompile the whole project all at once. Rust allows you to create libraries that can then be linked into the main executable. Given two files src/iomrascalai.rs (the main program) and src/board/mod.rs (the library) to compile it by hand it would work like this:
$ rustc --out-dir lib src/board/mod.rs
$ ls lib/
libboard-d085aa56-0.0.rlib
$ rustc --out-dir bin -L lib src/iomrascalai.rs
$ ls bin/
iomrascalai
What I'm trying to do in the Makefile is to define dynamic rules to compile the libraries. I'm trying to do it like that as the mapping from source file (src/board/mod.rs) to library name (lib/libboard-d085aa56-0.0.rlib) is non-trivial. However, I can't seem to make it work:
MAIN = src/iomrascalai.rs
CRATES = src/board/mod.rs
LIBS = $(foreach crate, $(CRATES), $(call TO_LIB, $(crate)))
all: exe
exe: $(MAIN) $(LIBS)
rustc --out-dir bin -L lib $(MAIN)
TO_LIB = $(addprefix lib/, $(shell rustc --crate-file-name $(1)))
define COMPILE_CRATE
$(call TO_LIB, $(1)): $(1)
rustc --out-dir lib $(1)
endef
$(foreach crate, $(CRATES), $(eval $(call COMPILE_CRATE, $(crate))))
Running make results in the following error:
$ make
rustc --out-dir bin -L lib src/iomrascalai.rs
src/iomrascalai.rs:22:1: 22:20 error: can't find crate for `board`
src/iomrascalai.rs:22 extern crate board;
^~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
make: *** [exe] Error 101
So the libraries aren't compiled which means that the main program can't be compiled. When I try to run make to compile the lib target then it works:
$ rustc --crate-file-name src/board/mod.rs
libboard-d085aa56-0.0.rlib
$ make lib/libboard-d085aa56-0.0.rlib
rustc --out-dir lib src/board/mod.rs
So for some reason the exe doesn't honor the prerequisites even though the rules are defined ...
Recursively expanded make variables (those which are assigned with =) are expanded whenever the variable is substituted. That means, other variables you use need to be defined before. In your case, you need to move up the definition of TO_LIB a few lines (at least above the exe rule since the expansion of LIBS need to have TO_LIB available there)
Ive got some large make files for a third party project that are not building due to linker issues.
From looking at the make files, I think it should be executing something like:
LIBS = -lm
CC = gcc
bin = bin
myapp: $(bin)/main.o $(bin)/other.o $(bin)/etc.o
$(CC) $(bin)/main.o $(bin)/other.o $(bin)/etc.o $(LIBS) -o myapp
gcc bin/main.o bin/other.o bin/etc.o -lm -o myapp
Instead from the error it seems to be failing on something like: It also didn't put any of the .o files in the expected bin/ location, but just left them in the source directory...
cc main.o -o myapp
But I cant locate anywhere that might come from. Is there some way to get some kind of stacktrace through the make files?
I am aware of -n and -d, but neither seems to tell me what target line and file yeilded that command, or which series of targets led there and the values of any $() expansions (The one im expecting is the only myapp: I can find in any of the makefiles...)
Check out the --debug option. From my manpage:
--debug[=FLAGS]
Print debugging information in addition to normal processing. If the
FLAGS are omitted, then the behavior is the same as if -d was specified.
FLAGS may be a for all debugging output (same as using -d), b for basic
debugging, v for more verbose basic debugging, i for showing implicit
rules, j for details on invocation of commands, and m for debugging
while remaking makefiles.
remake is a very good choice but in a pinch something like the following (saved as debug.mk) can be a good help too. It won't tell you as much as remake but it might tell you enough to start with.
# Use as: MAKEFILES=debug.mk make
OLD_SHELL := $(SHELL)
ifneq (undefined,$(origin X))
override X = -x
endif
SHELL = $(if $#,$(warning Running $#$(if $<, (from: $<))$(if $?, (newer: $?))))$(OLD_SHELL) $(X)
You can print out the other automatic variables there too if you wanted to see a bit more about what was going on.
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.
I'm new to C programming. I want to compile C program using Make file. I can compile the source code file with the command:
gcc `xml2-config --cflags --libs` -o xmlexample readelementsfile.c
But when I create make file and I add the above commend into the make file I get this error:
Makefile:1: *** missing separator. Stop.
Can you tell me where I'm wrong?
You need to specify a target:
all:
gcc `xml2-config --cflags --libs` -o xmlexample readelementsfile.c
The whitespace at the start of the second line should be a Tab character.
You can also specify dependencies so that not all of your commands are run every time you build.
Related
Makefile Tutorial