When it comes to the sighandler stuff in https://github.com/GenericMappingTools/gmt/blob/master/src/gmt_common_sighandler.c, I have to admit I’m on deep water. I did a bit of googling and testing, but no bright lights yet.
Made a bug report about this (https://github.com/GenericMappingTools/gmt/issues/4396) so it’s in the system.
On a Raspberry Pi with FreeBSD 12.2-RELEASE (“RPI3”, SD Card Image), I got the following error:
[ 3%] Building C object src/CMakeFiles/gmtlib.dir/gmt_common_sighandler.c.o
/home/anbj/gmt/gmt/src/gmt_common_sighandler.c:178:14: error: no member named 'mc_eip' in 'struct __mcontext'
array [0] = UC_IP (uc); /* caller's address */
^~~~~~~~~~
/home/anbj/gmt/gmt/src/gmt_common_sighandler.c:75:49: note: expanded from macro 'UC_IP'
# define UC_IP(uc) ((void *) (uc)->uc_mcontext.mc_eip)
~~~~~~~~~~~~~~~~~ ^
1 error generated.
*** Error code 1
Stop.
make[2]: stopped in /home/anbj/gmt/b
*** Error code 1
Stop.
make[1]: stopped in /home/anbj/gmt/b
*** Error code 1
Stop.
make: stopped in /home/anbj/gmt/b
Adding add_definitions(-DNO_SIGHANDLER) to cmake/ConfigUser.cmake
as Paul suggested, fixes the problem.
I dont know why this error occurs on the FreeBSD Raspi SD Image, and not on a “normally” installed system. I dont know how the Raspi system differs.
Not necessarily something that should be looked at, but nice to know.
Attached are the cmake
logs. NB! Had to rename to .zip or else I was not allowed to upload. They are plain text files.
cmake_build.zip (1.2 KB) cmake_config.zip (13.1 KB)
I came across the same problem and found out that the error is caused by a missing library in the linker flags. I was never able to add the flag to the CMake configuration but ended up compiling the library manually by running “make VERBOSE=1;” to see the full commandline where the error occurs and then running it manually, adding -lexecinfo to the commandline to pull in the library. Once that’s done, compilation continues without problems when you run make again.
A suggestion to the developers who are versed in the black magic of CMake would be to add -lexecinfo to the linker command line on FreeBSD. See this message on the gcc.gnu.org mailing list.
Anders
Anders,
Thank you for sharing this. Great to know.
Best,
Andreas
Yes, I found that post and added it to the 6.1.1 sources I downloaded as a tar file earlier. It worked very well. Adding this just after line 300 in src/CMakeLists.txt works on 6.1.1 too.
FreeBSD uses a separate library for backtracking
if (${CMAKE_SYSTEM_NAME} STREQUAL “FreeBSD”)
find_library (EXECINFO_LIBRARY NAMES execinfo)
list (APPEND GMT_OPTIONAL_LIBRARIES ${EXECINFO_LIBRARY})
endif (${CMAKE_SYSTEM_NAME} STREQUAL “FreeBSD”)
Cheers,
Anders
@ahogrelius Is this related to the issue I initially described? Or the issue with compiling on the Raspberry Pi?
This is related to the first issue. The second issue on Raspberry Pi is not as easy to solve. If you look up the manpage for ucontext where the struct is described on FreeBSD it will tell you that “The uc_mcontext field is machine-dependent and should be treated as opaque by portable applications.”
If it even is possible, this means that you would have to add FreeBSD ARM specific code to gmt_common_sighandler.c to make it work as the mc_eip member doesn’t exist at all on FreeBSD ARM. Depending on the implementation on GMT it is also possible that you would have to write your own sighandler.
Update:
After studying the problem a bit more I have to report that the only thing you can do is to add the definition NO_SIGHANDLER. The ARM architecture doesn’t allow you to find the address of the calling function unless you have special unwind libraries added to your application and it will add a lot of unnecessary overhead.
Hi @Andreas @ahogrelius,
I know both of you are FreeBSD users. Do you also use Python, or even PyGMT?
The PyGMT project is planning to provide some basic support for FreeBSD (see the linked issue below), but none of the developers are using FreeBSD. We would appreciate it if you can help us confirm some information about FreeBSD. It would be even better if you can run PyGMT once and let us know it works as expected.
Please see the linked issue below for more details.
@seisman I’m almost exclusive a command line user (bash
, that is). But I’m more than happy to help.
Let me know if I should test differently.
$ python3
Python 3.7.9 (default, Oct 3 2020, 01:29:35)
[Clang 8.0.1 (tags/RELEASE_801/final 366581)] on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.platform)
freebsd12
>>>
Can’t say for certain, but doing a listing of /usr/lib
and usr/local/lib
sure indicates that the suffix for shared libraries is .so
.
Installed PyGMT via $ pip install pygmt
and tried:
$ python3
Python 3.7.9 (default, Oct 3 2020, 01:29:35)
[Clang 8.0.1 (tags/RELEASE_801/final 366581)] on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygmt
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/__init__.py", line 3 2, in <module>
_begin()
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/session_management.p y", line 16, in begin
with Session() as lib:
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/clib/session.py", li ne 183, in __enter__
self.create("pygmt-session")
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/clib/session.py", li ne 336, in create
restype=ctp.c_void_p,
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/clib/session.py", li ne 284, in get_libgmt_func
self._libgmt = load_libgmt()
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/clib/loading.py", li ne 35, in load_libgmt
lib_fullnames = clib_full_names()
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/clib/loading.py", li ne 99, in clib_full_names
libnames = clib_names(os_name=sys.platform) # e.g. libgmt.so, libgmt.dylib, gmt.dll
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/clib/loading.py", li ne 77, in clib_names
raise GMTOSError('Operating system "{}" not supported.'.format(sys.platform) )
pygmt.exceptions.GMTOSError: Operating system "freebsd12" not supported.
>>>
@Andreas Thanks for your information. It’s really helpful. I’ve opened a PR (https://github.com/GenericMappingTools/pygmt/pull/700) for it.
You can install that branch by running:
pip install git+https://github.com/GenericMappingTools/pygmt.git@freebsd
and then you can test it in a Python console:
import pygmt
pygmt.show_versions()
Please let me know if you find any problems.
This is what I get after installing the branch you linked to:
$ python3
Python 3.7.9 (default, Oct 3 2020, 01:29:35)
[Clang 8.0.1 (tags/RELEASE_801/final 366581)] on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygmt
>>> pygmt.show_versions()
PyGMT information:
version: v0.2.2.dev7+g07edbd3
System information:
python: 3.7.9 (default, Oct 3 2020, 01:29:35) [Clang 8.0.1 (tags/RELEASE_801/final 366581)]
executable: /usr/local/bin/python3
machine: FreeBSD-12.2-RELEASE-amd64-64bit-ELF
Dependency information:
numpy: 1.19.4
pandas: 1.1.4
xarray: 0.16.1
netCDF4: 1.5.4
packaging: 20.4
ghostscript: None
gmt: 6.2.0_3390d08_2020.11.21
GMT library information:
binary dir:
cores: 4
grid layout: rows
library path: /usr/local/lib/libgmt.so
padding: 2
plugin dir: /usr/local/lib/gmt/plugins
share dir: /usr/local/share
version: 6.2.0
>>>
I’m able to create the figure as described here https://www.pygmt.org/latest/tutorials/first-figure.html.
Just a note on that; I’m getting an error when doing fig.show()
:
$ python3
Python 3.7.9 (default, Oct 3 2020, 01:29:35)
[Clang 8.0.1 (tags/RELEASE_801/final 366581)] on freebsd12
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygmt
>>> fig = pygmt.Figure()
>>> fig.basemap(region=[-90, -70, 0, 20], projection="M8i", frame=True)
>>> fig.coast(shorelines=True)
>>> fig.show()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/anbj/.local/lib/python3.7/site-packages/pygmt/figure.py", line 289, in show
"or use 'external=True' to open in an external viewer.",
pygmt.exceptions.GMTError: Cannot find IPython. Make sure you have it installed or use 'external=True' to open in an external viewer.
Apparently missing IPython
. Should this be installed as a dependency pr. default?
Thanks for your feedback! I think it means PyGMT works well on FreeBSD, at least the simplest examples should work.
The error you’re seeing is because the default Python console can’t “show” the image you’re plotting. You have to use fig.show(method="external")
to open the figure using your default PDF viewer. (Please note that the error message says “use 'external=True
” but the message is out-of-date and should be fixed.)
Great work @seisman.
I’ll play around and do some more testing when I have the time and let you know if I encounter any problems.
I tried to install pygmt using the command:
pip install git+https://github.com/GenericMappingTools/pygmt.git@freebsd
It doesn’t work. I get this error message.
Collecting git+https://github.com/GenericMappingTools/pygmt.git@freebsd
Cloning https://github.com/GenericMappingTools/pygmt.git (to revision freebsd) to /tmp/pip-req-build-yfd06wdt
WARNING: Did not find branch or tag ‘freebsd’, assuming revision or ref.
ERROR: Command errored out with exit status 1: git checkout -q freebsd Check the logs for full command output.
This is on FreeBSD 12.1-RELEASE amd64
@ahogrelius Thanks for your trying to help. We already merged the “freebsd” branch into master branch (i.e., PyGMT now provides some basic support for FreeBSD, although there is no guarantee that it works well as expected).
To install the latest PyGMT, you can use the following command:
pip install git+https://github.com/GenericMappingTools/pygmt.git
@Andreas @ahogrelius Again, Thanks for all your help. If you find any problems, please open an issue in the PyGMT repository (https://github.com/GenericMappingTools/pygmt) so that we can better keep track of them.
I added the code segment below manually to the clib_names function in /usr/local/lib/python3.7/site-packages/pygmt/clib/loading.py
elif os_name.startswith("freebsd"):
libnames = ["libgmt.so"]
After the addition I get the following:
Python 3.7.9 (default, Oct 3 2020, 01:29:35)
[Clang 8.0.1 (tags/RELEASE_801/final 366581)] on freebsd12
Type “help”, “copyright”, “credits” or “license” for more information.
import pygmt
pygmt.show_versions()
PyGMT information:
version: v0.2.1
System information:
python: 3.7.9 (default, Oct 3 2020, 01:29:35) [Clang 8.0.1 (tags/RELEASE_801/final 366581)]
executable: /usr/local/bin/python3
machine: FreeBSD-12.1-RELEASE-amd64-64bit-ELF
Dependency information:
numpy: 1.19.4
pandas: 1.1.4
xarray: 0.16.1
netCDF4: 1.5.4
packaging: 20.4
ghostscript: None
gmt: 6.1.1
GMT library information:
binary dir:
cores: 16
grid layout: rows
library path: /usr/local/lib/libgmt.so
padding: 2
plugin dir: /usr/local/lib/gmt/plugins
share dir: /usr/local/share/gmt
version: 6.1.1
Yes, this also worked and the result looked like expected.
import pygmt
fig = pygmt.Figure()
fig.basemap(region=[-90, -70, 0, 20], projection=“M8i”, frame=True)
fig.coast(shorelines=True)
fig.savefig(“test.pdf”)