I am trying to build and install a SWIG-generated perl API on OS X 10.10.2. (It's for the FreeLing 3.1 language analysis toolkit.) I have generated and compiled the SWIG files, producing freeling.so.
But when I try to use freeling in a perl script, I get the error:
Can't find 'boot_freeling' symbol in /usr/local/lib/libfreeling.dylib at freeling.pm line 11.
But boot_freeling should be defined in the SWIG-generated freeling.so, not in libfreeling.dylib (the FreeLing package lib). (nm -U confirms this: _boot_freeling is defined in freeling.so; I'm assuming the leading underscore is just part of the object file format.)
I have made sure that freeling.so comes before libfreeling.dylib in LD_LIBRARY_PATH. I've also tried unshifting the path to freeling.so onto #DynaLoader::dl_library_path.
I suspect this is not a path problem, but something about building for OS X. In the past, I have built this on Ubuntu and it works fine. I have tweaked the gcc options (-bundle instead of -shared).
Additional info:
perl -V:dlext => dlext='bundle';
Building SOso-0.01.patch.txt produces:
blib
├── blib/arch
│ └── blib/arch/auto
│ └── blib/arch/auto/SOso
│ └── blib/arch/auto/SOso/SOso.bundle
├── blib/bin
├── blib/lib
│ ├── blib/lib/SOso.pm
│ └── blib/lib/auto
│ └── blib/lib/auto/SOso
├── blib/man1
├── blib/man3
└── blib/script
Makefile target:
freeling.bundle: freeling_perlAPI.cxx
g++ -v -bundle -o freeling.bundle freeling_perlAPI.cxx -lfreeling -lperl -lboost_system -I $(FREELINGDIR)/include -I $(BOOSTDIR)/include -I $(ICU4CDIR)/include -L $(FREELINGDIR)/libfreeling -I $(PERLDIR)/CORE -L $(LIBDIR) -L $(BOOSTDIR)/lib -L $(PERLDIR)/CORE -fPIC
Ok, promoting to answer :)
What do you get for perl -V:dlext ?
When you compile this module SOso-0.01.patch.txt what files are created in blib?
Well :) if your os/perl is configured to look for a freeling.bundle, I don't think its going to try to look at freeling.so .... so I'd try to do something about that ... rename the file to use the dlext
Related
I am creating 3 separate go projects: ace, aces-client and a library shared by both projects aceslib. I am having trouble including the shared library according to the go-documentation (https://golang.org/doc/code.html#Library)
all go files in aceslib share the package-name aceslib. I am including the library in ace and aces-client with import lib "aceslib". I can build the library with go build and it gets installed with go install, in the directory listing one can see that the file go/pkg/windows_amd64/aceslib.a gets created.
But when I try to build ace or ace-client go complains:
$ go build
build ace: cannot load aceslib: cannot find module providing package aceslib
My go setup:
$ go version
go version go1.12.9 windows/amd64
$ go env
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Yulivee\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Yulivee\go
set GOPROXY=
set GORACE=
set GOROOT=c:\go
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\Yulivee\go\src\ace\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\Yulivee\AppData\Local\Temp\go-build024649150=/tmp/go-build -gno-record-gcc-switches
Directory Structure:
.
├── bin
│ ├── ace-client.exe
│ └── ace.exe
├── pkg
│ ├── mod
│ │ ├── cache
│ │ └── golang.org
│ └── windows_amd64
│ ├── ace
│ ├── aceslib.a
│ └── golang.org
└── src
├── ace
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── ace-client
│ └── main.go
├── aceslib
│ ├── README.md
│ ├── crypto.go
│ ├── go.mod
│ └── utils.go
What am I missing?
Things I have tried, that did not help and lead to the same error:
$ go clean -i -x -cache -modcache
$ chmod 755 go/pkg/windows_amd64/aceslib.a
$ go get
build ace: cannot load aceslib: cannot find module providing package aceslib
$ rm -rf go/pkg/*
The directory structure and package names are a bit off - it should be a URL to your project's repo, like every other import that isn't from the stdlib. If you have no repo and want to use local references you'll need to add a replace directive to ace/go.mod like so:
replace aceslib => ../aceslib
As documented in the Modules docs.
IIRC, package names without directories are reserved for stdlib packages. So, you should first push the source tree down at least a level so you can access it by "dir/package".
Next, do you really want to treat these packages as separate modules? You have separate mod files under ace and aceslib packages. You may combine them under one module with a single go.mod at the project root and make life easier for yourself. That way you don't need redirects, etc.
You also have to include the modules with their directories:
import lib "dir/aceslib"
When I try to link librubberband.a I get:
libavfilter/af_rubberband.c:236: error: undefined reference to 'rubberband_set_pitch_scale'
I compiled rubberband for armv7a, and created a static library (rubberband.a).
I checked the library, and It contained the needed symbols (using nm).
I verified that librubberband.a is in the libpath (-L)
I verified that extern C exists in the rubberband.c.h file.
Any ideas?
The error happened in the link stage. Make sure the link directory has been added to -L parameters of your compiler.
-L/directory/of/your/lib
And specify the library with -l option.
So make sure the option -L/directory/of/your/lib -lrubberband set for your compiler when you build ffmpeg with rubberband support.
If you didn't use pkg-config to add the library. You can use the option --extra-ldflags to add when configure ffmpeg before build.
./configure \
# some configure options
--extra-ldflags="-L/directory/of/your/lib -lrubberband" \
# more configure options
If you use pkg-config to find out the libraries. Just add the library.pc directory to PKG_CONFIG_PATH, and let the build system do the remaining.
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/directory/to/your/rubberband.pc
Updated
Finally make sure you link against to the same architecture of your library.
$ arm-linux-androideabi-readelf -h librubberband.a |grep 'Class\|Machine
For armeabi-v7a, it should be ELF32 and ARM.
Updated
I have cloned the source of rubberband from https://bitbucket.org/breakfastquay/rubberband
And found the function call rubberband_set_pitch_scale is defined at src/rubberband-c.cpp, this file is not include in Android.mk when build for Android (WHY?).
So you have to add this file to build.
RUBBERBAND_SRC_FILES = ... \
$(RUBBERBAND_SRC_PATH)/rubberband-c.cpp
After build done, you need to create directory structure like below
.
├── include
│ └── rubberband
│ ├── RubberBandStretcher.h
│ └── rubberband-c.h
└── lib
├── librubberband.a
└── pkgconfig
└── rubberband.pc
The file rubberband.pc was copied from rubberband.in.pc with some minor changes.
prefix=/path/to/rubberband/install/root
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: rubberband
Version: 1.8.1
Description:
Libs: -L${libdir} -lrubberband -L/path/to/android/ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -lgnustl_static
Cflags: -I${includedir}
Then add
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/rubberband/install/root
before ./configure to tell ffmpeg find rubberband by pkg-config.
I have tried with the latest ffmpeg, it works.
TL;DR :
Even if libffi seems installed, the configure script doesn't find it even if I give it the (correct?) prefix.
/!\ The last part (*) of this post is where I'm stuck. /!\
I only put the other information to explain how I get there. I apologize for the big post, if something seems irrelevant to you, feel free to tell me, I'll consider making my post shorter.
Why I want to compile CLISP by myself :
I have a lisp programm I would like to run but when running it with CLISP installed with brew (I have no root access) I get the following error :
*** - CFFI requires CLISP compiled with dynamic FFI support.
So I would like to compile CLISP by myself.
I was using SBCL thus far but I had a problem and was looking for an other implementation.
The problems I have when trying to compile :
I downloaded the sources, untared it.
I then trying to run ./configure.
But I get this :
Configure findings:
FFI: no (user requested: default)
readline: no (user requested: default)
libsigsegv: no, consider installing GNU libsigsegv
./configure: libsigsegv was not detected, thus some features, such as
generational garbage collection and
stack overflow detection in interpreted Lisp code
cannot be provided.
Please install libsigsegv like this:
mkdir tools; cd tools; prefix=`pwd`/x86_64-apple-darwin15.4.0
wget http://ftp.gnu.org/pub/gnu/libsigsegv/libsigsegv-2.8.tar.gz
tar xfz libsigsegv-2.8.tar.gz
cd libsigsegv-2.8
./configure --prefix=${prefix} && make && make check && make install
cd ../..
rm -f src/config.cache
./configure --with-libsigsegv-prefix=${prefix}
If you insist on building without libsigsegv, please pass
--ignore-absence-of-libsigsegv
to this script:
./configure --ignore-absence-of-libsigsegv
If you have installed libsigsegv, but clisp does not detect it,
you might have installed it incorrectly, see section 2 in in unix/INSTALL.
IMPORTANT :
libffi and libsigsegv are both installed with homebrew. But aren't found.
I tried adding --with-libsigsegv-prefix=<several values amongst ~/.brew/{opt,opt/libsigsegv,lib,Cellar/libsigsegv,...} : Still the same problem.
This is also almost the same as this post or this one. But the validated solutions doesn't work for me (OSX without root access).
When running configure with --with-dynamic-ffi and --ignore-absence-of-libsigsegv :
I tried to run ./configure --ignore-absence-of-libsigsegv and added --with-dynamic-ffi as someone suggested me in comments.
But then I got this :
Configure findings:
FFI: no (user requested: default)
readline: no (user requested: default)
libsigsegv: no, consider installing GNU libsigsegv
As you requested, we will proceed without libsigsegv...
./makemake --with-dynamic-ffi > Makefile
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
when trying to manually install libffi and libsigsegv :
I also tried the suggestion in the first error message :
When running ./configure --with-libsigsegv-prefix=${prefix} I got :
Configure findings:
FFI: no (user requested: default)
readline: no (user requested: default)
libsigsegv: yes
./makemake --with-libsigsegv-prefix=/nfs/2013/v/vmonteco/Documents/clisp-2.49/tools/x86_64-apple-darwin15.4.0 > Makefile
clang: error: unsupported option '-print-multi-os-directory'
clang: error: no input files
make: `config.lisp' is up to date.
even if I add --with-dynamic-ffi or if I try to install libffi by hand like the first error message suggested (and adding --with-ffi-prefix=${prefix} as well)
If I try to manually build and install libffcall as well :
I get many
avcall-i386.s:7:2: error: instruction requires: Not 64-bit mode
when running make
(*) So now, it does find libsigsegv, but doesn't find libffi.
Yet the tree at ${prefix} looks like this :
.
├── include
│ └── sigsegv.h
├── lib
│ ├── libffi-3.2.1
│ │ └── include
│ │ ├── ffi.h
│ │ └── ffitarget.h
│ ├── libffi.6.dylib
│ ├── libffi.a
│ ├── libffi.dylib -> libffi.6.dylib
│ ├── libffi.la
│ ├── libsigsegv.a
│ ├── libsigsegv.la
│ └── pkgconfig
│ └── libffi.pc
└── share
├── info
│ ├── dir
│ └── libffi.info
└── man
└── man3
├── ffi.3
├── ffi_call.3
├── ffi_prep_cif.3
└── ffi_prep_cif_var.3
I'm out of ideas.
On OSX (and developing for OSX only) it is a very good idea to check Clozure. http://ccl.clozure.com It includes an IDE and from speed and general performance it is comparable to SBCL. You can develop native OSX UI apps using Clozure, of course these will not be portable. If you keep to the standard, then you might even use Clozure on Linux etc.
In SCons when a folder is installed the dependency tree is not aware of the contents of the folder. This means that implicit relationships cannot be created.
env.Install("out/bin","path/to/folder")
env.Install("out/archive", Glob("out/bin/folder/library.lib"))
In this sample code the Glob returns [] because SCons is unaware the folder contains a file called library.lib.
The only workaround I've found for this is to walk the directory and install each individual file.
Does the SCons Install not have an option to do this for you?
I have run into this as well. I have not found any other solution than to walk the directories as you describe. Though the contents of the folder are copied, to SCons there is just one target, and just one source, unless you specify each one individually.
import os
def recursive_install(target, source, env):
source_dirname = os.path.dirname(source)
for root, dirnames, filenames in os.walk(source):
for filename in filenames:
env.Install(os.path.join(
target, os.path.relpath(root, os.path.dirname(source))),
os.path.join(root, filename))
env = Environment()
recursive_install("out/bin", "path/to/folder", env)
env.Install("out/archive", "out/bin/folder/library.lib")
Which when run produces...
>> scons --version
SCons by Steven Knight et al.:
script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation
>> tree
.
├── path
│ └── to
│ └── folder
│ └── library.lib
└── SConstruct
3 directories, 2 files
>> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "path/to/folder/library.lib" as "out/bin/folder/library.lib"
Install file: "out/bin/folder/library.lib" as "out/archive/library.lib"
scons: done building targets.
>> tree
.
├── out
│ ├── archive
│ │ └── library.lib
│ └── bin
│ └── folder
│ └── library.lib
├── path
│ └── to
│ └── folder
│ └── library.lib
└── SConstruct
7 directories, 4 files
SCons doesn't have an option for recursively installing all files under a top-folder, because that's considered to be a rare case (note, how SCons prefers in-source-tree builds, such that you'd have to exclude a lot of files from the Install call otherwise). If you are creating the "files to install" within the same build, the preferred method would be to use the emitted list of targets from your Builder, and put it as second argument to the Install method:
mylibs = env.AnyBuilder('library', sources)
env.Install("out/bin", mylibs)
Then you don't have to manually list all the target files again with a recursive os.walk as in Kenneth's answer.
Problem
I haven't been able to find a solution to this by looking at related questions. I can't tell what makes my Go environment different from the canonical setup.
go env returns
GOROOT="/usr/lib/go"
GOBIN=""
GOARCH="386"
GOCHAR="8"
GOOS="linux"
GOEXE=""
GOHOSTARCH="386"
GOHOSTOS="linux"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_386"
GOGCCFLAGS="-g -O2 -fPIC -m32 -pthread"
CGO_ENABLED="1"
tree $GOPATH returns
/home/USER/go
├── bin
├── pkg
│ └── linux_386
│ └── bitbucket.org
│ └── USER-NAME
│ └── PROJECT
│ └── my_package.a
└── src
└── bitbucket.org
└── USER-NAME
└── PROJECT
├── main
│ ├── main.go
└── my_package
└── my_package.go
(ALL-CAPS are substitutions)
main.go contains
package main
import (
"bitbucket.org/USER-NAME/PROJECT/my_package"
)
func main() {
my_package.Foo()
}
Calling go build in the main directory returns import "my_package": cannot find package
Volker pointed out that go env should have returned a GOPATH entry as well. The source of the env command corroborates that. However, running echo $GOPATH in bash or os.Getenv("GOPATH") in Go both return \home\USER\go. I'm not sure why the same isn't returned by go env.
Solution
I was running Go 1.0 when I was having this issue. The problem disappeared when I upgraded to Go 1.2.1.
You have a directory called main. This won't work. Change it.
Structure it like $GOPATH/src/bitbucket.com/youruser name/yourpackagename/{main.go, otherthing.go, otherpackagedirectory}.
"package main" doesn't have to be in it's own sub folder: it inherits the name of your Bitbucket project (username/myprojectname).
You did not set (or export) GOPATH. GOPATH Is much more important than GOROOT (at least in newe Go versions).