How can I create static executables on OS X with Stack? - macos

I would like to create a static executable for Darwin for a small utility I wrote called difftodo. difftodo depends indirectly on pcre, and I would like people to be able to download a binary and run it without having to brew install pcre first.
If I compile without options, I get a binary that dynamically links pcre:
$ otool -L /Users/jml/src/difftodo/.stack-work/install/x86_64-osx/lts-7.1/8.0.1/bin/git-todo
/Users/jml/src/difftodo/.stack-work/install/x86_64-osx/lts-7.1/8.0.1/bin/git-todo:
/usr/local/opt/pcre/lib/libpcre.1.dylib (compatibility version 4.0.0, current version 4.7.0)
/usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
Following instructions at https://github.com/commercialhaskell/stack/issues/1032, I tried the following:
$ stack build --ghc-options -static --ghc-options -optl-static
difftodo-0.2.0: configure
Configuring difftodo-0.2.0...
difftodo-0.2.0: build
Preprocessing library difftodo-0.2.0...
ld: illegal text reloc in '_c1TGM_info' to '_stg_sel_1_upd_info' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
`gcc' failed in phase `Linker'. (Exit code: 1)
-- While building package difftodo-0.2.0 using:
/Users/jml/.stack/setup-exe-cache/x86_64-osx/setup-Simple-Cabal-1.24.0.0-ghc-8.0.1 --builddir=.stack-work/dist/x86_64-osx/Cabal-1.24.0.0 build lib:difftodo exe:all-todos exe:diff-todo exe:git-todo --ghc-options " -ddump-hi -ddump-to-file"
Process exited with code: ExitFailure 1
I don't understand this failure at all.
Creating static Mac OS X C build implies that creating fully static binary on OS X is impossible and undesirable. However, I am content to have dynamic links to libSystem etc., just not to the third-party libraries I am depending on.
Note that I have a static version of pcre available:
$ ls -la /usr/local/opt/pcre/lib/
total 2700
drwxr-xr-x 18 jml admin 612 Oct 1 11:02 .
drwxr-xr-x 13 jml admin 442 Oct 1 11:02 ..
-r--r--r-- 1 jml admin 443872 Oct 1 11:02 libpcre.1.dylib
-r--r--r-- 1 jml admin 492016 Oct 1 11:02 libpcre.a
...
http://gelisam.blogspot.co.uk/2014/12/how-to-package-up-binaries-for.html describes a method for working around this problem: edit the link tables in the executable and ship it together with the libraries. I would much rather have a single executable.

Related

Cross-compiling kernel tools, cannot find -lelf even with -L set correctly

I'm trying to cross-compile a modified version of the official Debian kernel for armhf on my amd64 machine. I'm using the HowToCrossBuildAnOfficialDebianKernelPackage instructions on the Debian wiki.
The kernel itself builds fine, but I get an error from ld when trying to build objtool for the linux-kbuild package:
# make -f debian/rules.real build-kbuild KBUILD_HOSTLDFLAGS="-L/usr/lib/arm-linux-gnueabihf"
[...]
arm-linux-gnueabihf-gcc /usr/src/linux.buster-backports/debian/build/build-tools/tools/objtool/objtool-in.o -lelf /usr/src/linux.buster-backports/debian/build/build-tools/tools/objtool/libsubcmd.a -L/usr/lib/arm-linux-gnueabihf -o /usr/src/linux.buster-backports/debian/build/build-tools/tools/objtool/objtool
/usr/lib/gcc-cross/arm-linux-gnueabihf/8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lelf
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:67: /usr/src/linux.buster-backports/debian/build/build-tools/tools/objtool/objtool] Error 1
You can see that make did add the -L/usr/lib/arm-linux-gnueabihf flag to gcc. And /usr/lib/arm-linux-gnueabihf does contain libelf:
# ls -l /usr/lib/arm-linux-gnueabihf/libelf*
-rw-r--r-- 1 root root 67296 May 28 2019 /usr/lib/arm-linux-gnueabihf/libelf-0.176.so
lrwxrwxrwx 1 root root 15 May 28 2019 /usr/lib/arm-linux-gnueabihf/libelf.so.1 -> libelf-0.176.so
# file /usr/lib/arm-linux-gnueabihf/libelf-0.176.so
/usr/lib/arm-linux-gnueabihf/libelf-0.176.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=51d60560aa6c0538f0bf34c07e4e2bc230c00834, stripped
I installed libelf like this:
dpkg --add-architecture armhf
apt-get update
apt-get install libelf1:armhf
The ld that's being used does appear to be for arm:
# /usr/lib/gcc-cross/arm-linux-gnueabihf/8/../../../../arm-linux-gnueabihf/bin/ld -V
GNU ld (GNU Binutils for Debian) 2.31.1
Supported emulations:
armelf_linux_eabi
armelfb_linux_eabi
I'm stumped. How do I get ld to link libelf?
Neither libelf-0.176.so nor libelf.so.1 are searched by the -lelf option to the linker. You still need libelf.so file. This file can be created:
By installing libelf-dev package (as usual, the libraries with exact .so are installed by *-dev packages). Make sure to choose a package suitable for cross-compiling.
By creating symlink libelf.so pointed to the libelf-0.176.so file which you have.

Mac OS 10.16 Linking Homebrew installed libraries

I have been using homebrew for long time and never faced this strange issue. For some reason I will not explain here am using MacOS 10.16 (Big Sur), a Beta version of latest MacOS and have installed libraries using homebrew. One of those library is zlib. But building with CMake, It cannot find the library. I have tried to build wxWidgets as well as libcurl. Both have failed with similar error:
-- make[2]: *** No rule to make target `/usr/lib/libz.dylib', needed by `lib/libwx_baseu-3.1.dylib'. Stop.
make[1]: *** [libs/base/CMakeFiles/wxbase.dir/all] Error 2
make: *** [all] Error 2
it seems like the libraries search path does not include /usr/local/opt/zlib/lib where the library is found. In another machine running 10.13 High Sierra it works fine.
brew info zlib
zlib: stable 1.2.11 (bottled) [keg-only]
General-purpose lossless data-compression library
https://zlib.net/
/usr/local/Cellar/zlib/1.2.11 (12 files, 376.4KB)
Poured from bottle on 2020-07-02 at 11:34:14
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/zlib.rb
==> Caveats
zlib is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
For compilers to find zlib you may need to set:
export LDFLAGS="-L/usr/local/opt/zlib/lib"
export CPPFLAGS="-I/usr/local/opt/zlib/include"
For pkg-config to find zlib you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig"
Relevant contents of CMakeList.txt
cmake_minimum_required(VERSION 2.8.11)
# Project name
project(MyApp)
# This setting is useful for providing JSON file used by CodeLite for code completion
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
set(CONFIGURATION_NAME "MacOSXDebug")
set(CL_WORKSPACE_DIRECTORY ..)
# Set default locations
set(CL_OUTPUT_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/${CL_WORKSPACE_DIRECTORY}/cmake-build-${CONFIGURATION_NAME}/output)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CL_OUTPUT_DIRECTORY})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CL_OUTPUT_DIRECTORY})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CL_OUTPUT_DIRECTORY})
set(PROJECT_Studio_PATH "${CMAKE_CURRENT_LIST_DIR}")
set(WORKSPACE_PATH "${CMAKE_CURRENT_LIST_DIR}/..")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
#Build wxWidgets first
message("Building wxWidgets Libraries")
execute_process(COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/wxWidgets)
execute_process(COMMAND git submodule update --init
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/../dependencies/wxWidgets
)
find_program(CMAKE_EXE cmake HINTS "/usr/local/bin/")
message("CMake executable at: ${CMAKE_EXE}")
execute_process(
COMMAND ${CMAKE_EXE} -DCMAKE_BUILD_TYPE=Debug -DwxUSE_EXPAT=builtin -DwxBUILD_PRECOMP=OFF ${CMAKE_SOURCE_DIR}/../dependencies/wxWidgets -B ${CMAKE_CURRENT_BINARY_DIR}/wxWidgets
ERROR_VARIABLE WX_BUILD_ERROR
COMMAND_ECHO STDOUT
)
message(STATUS ${WX_BUILD_OUTPUT})
message(STATUS ${WX_BUILD_ERROR})
execute_process(
COMMAND make -j4 #VERBOSE=1
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/wxWidgets
ERROR_VARIABLE WX_BUILD_ERROR
COMMAND_ECHO STDOUT
)
message(STATUS ${WX_BUILD_OUTPUT})
message(STATUS ${WX_BUILD_ERROR})
#Setup wxWidgets
set(ENV{PATH} "${CMAKE_CURRENT_BINARY_DIR}/wxWidgets:$ENV{PATH}")
set(WXWIN ${CMAKE_CURRENT_BINARY_DIR}/wxWidgets)
set(CMAKE_MACOSX_RPATH TRUE)
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_INSTALL_NAME_DIR "#rpath")
CMake Log
Log is so big that cannot be pasted here. See it here: https://pastebin.com/Mk4NrQgX
UPDATE
So I checked out and there is this strange thing happening. When I list with ls, I can see library exists:
ls /usr/lib/|grep libz
libz.1.1.3.dylib
libz.1.2.11.dylib
libz.1.2.5.dylib
But when I try for example to examine the library with otool
otool -L /usr/lib/libz.dylib
/Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: error: '/usr/lib/libz.dylib': No such file or directory
I guess the problem lies here, though am yet to crack the code
UPDATE 2
So ran ls -la /usr/lib | grep libz and as you can see it's all linking back to libz.1.dylib but that file does not exist.
lrwxr-xr-x 1 root wheel 12 Jan 1 2020 libz.1.1.3.dylib -> libz.1.dylib
lrwxr-xr-x 1 root wheel 12 Jan 1 2020 libz.1.2.11.dylib -> libz.1.dylib
lrwxr-xr-x 1 root wheel 12 Jan 1 2020 libz.1.2.5.dylib -> libz.1.dylib
lrwxr-xr-x 1 root wheel 12 Jan 1 2020 libz.1.2.8.dylib -> libz.1.dylib
lrwxr-xr-x 1 root wheel 12 Jan 1 2020 libz.dylib -> libz.1.dylib
We have a big epic tracker in here for MacOS 10.16/11.0 compatibility check.
https://github.com/Homebrew/brew/issues/7857
Feel free to escalate the issue in there (I actually saw the zlib marked as 🥇)
It seems some libraries in /usr/lib/are pure garbage. I can confirm zliband libiconvare corrupt, linked to non existing library. No much complain since it is a beta version. So the solution was to install brew version with brew install zlib and then overwrite terminal's current system path with
export PATH=/usr/local/opt/zlib/lib:/usr/local/opt/zlib/include:$PATH

On macOS, why doesn't otool -L show the version of libpng the application is running with?

I'm compiling an application which uses the CMake build system for macOS 10.15.4. When I run the built application, I get an error (Application built with libpng-1.5.23 but running with 1.6.37) informing me that I have a mismatch between the version of libpng that the application was compiled against and the one it's using while it runs:
Hostname:sample_data username$ ~/src/github/hoche/splat/build/src/Debug/splat -t ~/src/github/hoche/splat/sample_data/wnju-dt.qth -sdelim _ -L 5 -maxpages 4
.
.
.
Writing Signal Strength map "/Users/username/src/github/hoche/splat/sample_data/wnju-dt.png" (2400x2430 image)... libpng warning: Application built with libpng-1.5.23 but running with 1.6.37
Done!
I've told CMake to generate an Xcode project file for Xcode 11.3. The application in question uses libpng. I tell CMake to use libpng with the following clause in my CMakeLists.txt:
find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
find_package(Threads REQUIRED)
include_directories(${PNG_INCLUDE_DIR})
add_executable(splat
.
.
.)
target_link_libraries(splat bz2 ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
I've installed libpng via MacPorts. When I view the linker lines in the generated Xcode, project, they look like:
otool -L reports:
Hostname:sample_data username$ otool -L ~/src/github/hoche/splat/build/src/Debug/splat
/Users/username/src/github/hoche/splat/build/src/Debug/splat:
/usr/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.5)
/opt/local/lib/libpng16.16.dylib (compatibility version 54.0.0, current version 54.0.0)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
/opt/local/lib/libjpeg.9.dylib (compatibility version 13.0.0, current version 13.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.7.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)
If I examine the files at the location indicated on the linker line, they appear correct too:
HOstname:sample_data username$ ls -al /opt/local/lib/libpng*
lrwxr-xr-x 1 root admin 10 Oct 28 2019 /opt/local/lib/libpng.a -> libpng16.a
lrwxr-xr-x 1 root admin 14 Oct 28 2019 /opt/local/lib/libpng.dylib -> libpng16.dylib
-rwxr-xr-x 1 root admin 177352 Oct 28 2019 /opt/local/lib/libpng16.16.dylib
-rw-r--r-- 1 root admin 253120 Oct 28 2019 /opt/local/lib/libpng16.a
lrwxr-xr-x 1 root admin 17 Oct 28 2019 /opt/local/lib/libpng16.dylib -> libpng16.16.dylib
Why is libpng complaining about a version mismatch? Is it really using the wrong version? If so, why doesn't otool -L show the version it runs with?
The error is due to a mismatch between the header files used and the library. The library version as indicated in the Mach-O load commands is not the issue.
Certain calls to libpng require that you pass PNG_LIBPNG_VER_STRING as a parameter. That effectively bakes the version from the headers into the calling code and libpng compares that to its own version to check for compatibility.
Make sure the headers that come with the library are the (first) ones found by the compiler.

c++11 std::unique_ptr error cmake 3.11.3 bootstrap

I am trying to bootstrap cmake 3.11.3 on Ubuntu 16.04.4 LTS xenial.
I have upgrade my gnu g++ compiler as follows:
> $ g++ --version
g++ (Ubuntu 8.1.0-5ubuntu1~16.04) 8.1.0 Copyright (C) 2018 Free
Software Foundation, Inc. This is free software; see the source for
copying conditions. There is NO warranty; not even for MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
And manually re-pointed the symbolic links:
$ ll /usr/bin/*g++*
lrwxrwxrwx 1 root root 5 Jun 8 16:57 /usr/bin/g++ -> g++-8*
-rwxr-xr-x 1 root root 919832 Apr 24 15:02 /usr/bin/g++-5*
lrwxrwxrwx 1 root root 22 Jun 6 04:26 /usr/bin/g++-8 -> x86_64-linux-gnu-g++-8*
lrwxrwxrwx 1 root root 22 Jun 8 16:58 /usr/bin/x86_64-linux-gnu-g++ -> x86_64-linux-gnu-g++-8*
lrwxrwxrwx 1 root root 5 Apr 24 15:02 /usr/bin/x86_64-linux-gnu-g++-5 -> g++-5*
-rwxr-xr-x 1 root root 1071984 Jun 6 04:26 /usr/bin/x86_64-linux-gnu-g++-8*
However, I get the following error in the configuration of cmake:
$ sudo ./bootstrap
---------------------------------------------
CMake 3.11.3, Copyright 2000-2018 Kitware, Inc. and Contributors
Found GNU toolchain
C compiler on this system is: gcc
C++ compiler on this system is: g++
Makefile processor on this system is: make
g++ has setenv
g++ has unsetenv
g++ does not have environ in stdlib.h
g++ has stl wstring
g++ has <ext/stdio_filebuf.h>
---------------------------------------------
make: Warning: File 'Makefile' has modification time 2.3 s in the future
make: 'cmake' is up to date.
make: warning: Clock skew detected. Your build may be incomplete.
loading initial cache file /mnt/ganymede/user/gpeytavi/srv_admin/software/cmake-3.11.3/Bootstrap.cmk/InitialCacheFlags.cmake
CMake Error at CMakeLists.txt:92 (message):
The C++ compiler does not support C++11 (e.g. std::unique_ptr).
-- Configuring incomplete, errors occurred!
See also "/mnt/ganymede/user/gpeytavi/srv_admin/software/cmake-3.11.3/CMakeFiles/CMakeOutput.log".
See also "/mnt/ganymede/user/gpeytavi/srv_admin/software/cmake-3.11.3/CMakeFiles/CMakeError.log".
---------------------------------------------
Error when bootstrapping CMake:
Problem while running initial CMake
---------------------------------------------
Any idea why I get a c++11 std::unique_ptr non-compliant error?
In my case, the issue is because of the folder where I have CMake source code is in a mounted directory (in fact my entire rootfs is mounted over NFS)
So, I looked in 'mount' command output and selected '/run/user/1000' location as a local location as this is mounted using tmpfs and moved my CMake source code to this location.
with this, ./bootstrap && make && sudo make install executed successfully.
Actually the ./bootstrap script does try the different C++ standard flags with the compiler. So it should detect its capabilities automatically.
Please make sure you don't have any CXXFLAGS environment variable set and try from scratch again (the messages/warnings you get indicate several tries/errors in the same directory).
Output when Successful
As a reference on my Ubuntu calling CMake's ./bootstrap looks like this:
---------------------------------------------
CMake 3.11.20180423, Copyright 2000-2018 Kitware, Inc. and Contributors
Warning: This is an in-source build
Found GNU toolchain
C compiler on this system is: gcc
C++ compiler on this system is: g++ -std=gnu++1y
Makefile processor on this system is: make
g++ has setenv
g++ has unsetenv
g++ does not have environ in stdlib.h
g++ has stl wstring
g++ has <ext/stdio_filebuf.h>
---------------------------------------------
Debugging
For debugging your problem you also could:
Call ./bootstrap --verbose
Look into Bootstrap.cmk/cmake_bootstrap.log
Known Problem
I only once had a problem with bootstrap using clang compilers where I needed to do the following call:
export CXXFLAGS=-Xclang -std=c++1z -Xclang -stdlib=libc++
Alternative
If you just want to install the latest version see How to specify where CMake is installed in Ubuntu?
I was able to resolve the issue by ensuring that both the build machine and the NFS file server were synchronized by running ntpd on both.
For me it was clock skew. I use the below command :
date -s "2021-11-30 15:08:21"
to set the time to now for the server. Then it work, thanks...

install_name_tool malformed object (load command 23 cmdsize is zero) - Mac OS X Yosemite

Installation of cunn for torch on Yosemite fails with malformed object error.
-- Install configuration: "Release"
-- Installing: /usr/local/lib/luarocks/rocks/cunn/scm-1/lib/libcunn.so
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: object: /usr/local/lib/luarocks/rocks/cunn/scm-1/lib/libcunn.so malformed object (load command 23 cmdsize is zero)
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/install_name_tool: object: /usr/local/lib/luarocks/rocks/cunn/scm-1/lib/libcunn.so malformed object (load command 23 cmdsize is zero)
-- Installing: /usr/local/lib/luarocks/rocks/cunn/scm-1/lua/cunn/init.lua
-- Installing: /usr/local/lib/luarocks/rocks/cunn/scm-1/lua/cunn/test.lua
Updating manifest for /usr/local/lib/luarocks/rocks
cunn scm-1 is now built and installed in /usr/local/ (license: BSD)
Searching online shows that this is related to library corruption or an update to install_name_tool. I replaced the install_name_tool from XCode(6.1) into /usr/bin but I still get the same error. Below are some diagnostics
$ ls -l $(which install_name_tool)
-rwxr-xr-x 1 root admin 14192 Nov 8 11:25 /opt/local/bin/install_name_tool
$ otool -L /usr/bin/install_name_tool
/usr/bin/install_name_tool:
/usr/lib/libxcselect.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
$ pkgutil --file-info /usr/bin/install_name_tool
volume: /
path: /usr/bin/install_name_tool
pkgid: com.apple.pkg.Essentials
pkg-version: 10.10.0.1.1.1412852630
install-time: 1413599255
uid: 0
gid: 0
mode: 755
I need this to work so that I can use CUDA with torch, I have already spent hours on it, please help.
I had the same problem and I solved it by building libcunn.so locally.
Run the following commands:
git clone https://github.com/torch/cunn.git
ls cunn
cmake -E make_directory build
cd build/
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="/usr/local/bin/.." -DCMAKE_INSTALL_PREFIX="/usr/local/lib/luarocks/rocks/cunn/scm-1" && make
Then you should have
Linking CXX shared module libcunn.so
Then just copy the library to the target folder:
cp libcunn.so /usr/local/lib/lua/5.1/libcunn.so

Resources