Compile perlbrew with libperl.so versus libperl.a - apache

I've been working on moving some software from RHEL 7 to Ubuntu 22.04.
I utilize Perlbrew. When I built the new 5.36.0 everything seemed normal until I started working on compiling mod_perl for my apache servers.
I built perlbrew with this:
perlbrew install perl-5.36.0 --as=perl-5.36.0 -Duseithreads
Then I tried compiling mod_perl.
It flopped while trying to use the libperl.a library.
I hit an error:
/usr/bin/ld: /perl5/perls/perl-5.36.0t/lib/5.36.0/x86_64-linux-thread-multi/CORE/libperl.a(op.o): relocation R_X86_64_PC32 against symbol `PL_hash_state_w' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
I did the googling and I think I'm trying to do a 'make' against a library that is static versus a shared object library? I may have the wrong idea but I'm chasing down this in hopes of solving the issue or finding more info along the way.
How do I set perlbrew install options to compile this as a .so library in Ubuntu just like it is in my previous version in RHEL?
/perl5/perls/perl-5.26.2/lib/5.26.2/x86_64-linux-thread-multi/CORE/libperl.so
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 7.6 (Maipo)
Release: 7.6
Codename: Maipo
/perl5/perls/perl-5.36.0/lib/5.36.0/x86_64-linux-thread-multi/CORE/libperl.a
Distributor ID: Ubuntu
Description: Ubuntu 22.04.1 LTS
Release: 22.04
Codename: jammy
TIA
Perlbrew installed without issues, but apache mod_perl won't compile unless it has a libperl.so versus a libperl.a library. Trying to figure out how I force the installer to create libperl.so versus libperl.a that's in there now.

INSTALL from 5.36.0 says:
Building a shared Perl library
Currently, for most systems, the main perl executable is built by linking the "perl library" libperl.a with perlmain.o, your static extensions, and various extra libraries, such as -lm.
On systems that support dynamic loading, it may be possible to replace libperl.a with a shared libperl.so. If you anticipate building several different perl binaries (e.g. by embedding libperl into different programs, or by using the optional compiler extension), then you might wish to build a shared libperl.so so that all your binaries can share the same library.
The disadvantages are that there may be a significant performance penalty associated with the shared libperl.so, and that the overall mechanism is still rather fragile with respect to different versions and upgrades.
In terms of performance, on my test system (Solaris 2.5_x86) the perl test suite took roughly 15% longer to run with the shared libperl.so. Your system and typical applications may well give quite different results.
The default name for the shared library is typically something like libperl.so.5.8.8 (for Perl 5.8.8), or libperl.so.588, or simply libperl.so. Configure tries to guess a sensible naming convention based on your C library name. Since the library gets installed in a version-specific architecture-dependent directory, the exact name isn't very important anyway, as long as your linker is happy.
You can elect to build a shared libperl by
sh Configure -Duseshrplib
[snip]
So you would pass -Duseshrplib to perlbrew install.

Related

Anyone use GMP on Xeon Phi?

I compiled GMP with icc and -mmic option, but can't install on MIC. How should I install?
I wrote a demo program, compiled with icc. It says can't find gmp.h.
How should I install GMP library on MIC and where to place gmp.h?
Build GMP with Intel Compiler:
cd /home/
wget https://gmplib.org/download/gmp/gmp-6.0.0.tar.bz2
tar -xf gmp-6.0.0.tar.bz2
rm -f gmp-6.0.0.tar.bz2
cd gmp-6.0.0
mkdir mic
cd mic
../configure CC=icc CFLAGS="-mmic" --host=x86_64 --disable-assembly --prefix /home/gmp-6.0.0/mic/
make
make install
Use the Intel Compiler with environment variables for mic development:
GMP_INCDIR=/home/gmp-6.0.0/mic/include
GMP_LIBDIR=/home/gmp-6.0.0/mic/lib
Though I don't have any expertize on Xeon Phi or even ICC if you are running on Unix-like environment, then you might to try to step through normal configure/make procedure on GMP sources pointing on ICC compiler instead of default GCC in order to build static and/or shared library along with generated gmp.h header, that you can then link with your application. You might want to see GMP documentation on that. Here are some advices, that I stepped to trying to compile it for NVIDIA CUDA:
Supply ./configure with CC and CFLAGS variables to point to desired compiler and its whatever options that you want
Be sure that there is no ABI incompability between your host and Xeon Phi device, especially between 32 and 64 bit architecture.
Consider adding --disable-assembly option to generate "pure-C" build (I am not familiar with Xeon Phi assembly and if/how it is compatibile with x86)
Don't forget to run make check (possibly with -j parameter) after you compiled GMP in order to check if tests are passing, it's very important step if you want use it for some professional purpose.
The library is installed in OS by make install command, for default under /usr/local directory (you might add --prefix option if you want it somewhere else), specifically:
/usr/local/include for gmp.h header file
/usr/local/lib for static and/or shared libgmp binaries
You might also try to compile your application with mini-gmp package, which is contained within GMP sources (it's located under mini-gmp directory). It's a subset of mpz_* and mpn_* routines, not as sophisticated and fast as normal GMP (and it doesn't have as much serious tests coverage), but it could make the job done with small footprint (it's contained in one header and C-source file). For such option be sure to obtain most recent version of GMP (or even get it from their repository).

Static library GNUSTEP and correct linking

I was checking out the portability of Objective-C via gnustep and ran into some problems...
I mean everything works on my 2 machines but the major problem is if I run my application on a platform where gnustep is not pre-installed... So I want to build it with static libraries. But I ran into several problems:
1.) I cant find the static libaries under /usr/local/lib so the question came up do they even exist within gnustep?
2.) In case there are static libraries available how to integrate it correctly into my gcc command?
sudo gcc -o main main.m GameRef.m SDLApplication.m SDLEvent.m SDLImage.m SDLMap.m SDLSprite.m Settings.m Utility.m -I -static `gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS` -L `gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES` -lgnustep-base -lSDL -fconstant-string-class=NSConstantString -std=c99 2>logFile
I'm currently using Ubuntu 12.04LTS and installed the SDL and Gnustep on one machine so the application runs fine... But not on the second because the shared libraries are missing so I need to add them as static but how?
The libraries in /usr/local/lib and other system 'lib' directories will be dynamic. They can't be used as static (AFAIK), and finding them wouldn't really help.
I'm no expert with GNUstep, but it sounds like you are missing the Objective-C runtime. You will need to download the source code of the GNUstep libraries and frameworks, and then compile them into static libraries yourself.
Really, wrapping all of those frameworks into your application will just add unnecessary work for both you and your end users. Dynamic libraries exist for a purpose. There's no reason to have multiple copies of the same code on the filesystem. Just require GNUstep as a dependency. Although its a slight pain for the users, they only need to do it once, and with most distros, installation is only a command or two away.

Building a cross-platform application (using Rust)

I started to learn Rust programming language and I use Linux. I'd like to build a cross-platform application using this language.
The question might not be related to Rust language in particular, but nonetheless, how do I do that? I'm interested in building a "Hello World" cross-platform application as well as for more complicated ones. I just need to get the idea.
So what do I do?
UPDATE:
What I want to do is the ability to run a program on 3 different platforms without changing the sources. Do I have to build a new binary file for each platform from the sources? Just like I could do in C
To run on multiple platforms you need to build an executable for each as #huon-dbauapp commented.
This is fairly straightforward with Rust. You use "--target=" with rustc to tell it what you want to build. The same flag works with Cargo.
For example, this builds for an ARM target:
cargo build --target=arm-unknown-linux-gnueabihf
See the Rust Flexible Target Specification for more about targets.
However, Rust doesn't ship with the std Crate compiled for ARM (as of June 2015). If this is the case for your target, you'll first need to compile the std Crates for the target yourself, which involves compiling the Rust compiler from source, and specifying the target for that build!
For information, most of this is copied from: https://github.com/japaric/ruststrap/blob/master/1-how-to-cross-compile.md
The following instructions are for gcc, so if you don't have this you'll need to install it. You'll also need the corresponding cross compiler tools, so for gcc:
sudo apt-get install gcc-arm-linux-gnueabihf
Compile Rust std Crate For ARM
The following example assumes you've already installed the current Rust Nightly, so we'll just get the sources and compile for ARM. If you are using a different version of the compiler, you'll need to get that to ensure your ARM libraries match the version of the compiler you're using to build your projects.
mkdir ~/toolchains
cd ~/toolchains
git clone https://github.com/rust-lang/rust.git
cd rust
git update
Build rustc for ARM
cd ~/toolchains/rust
./configure --target=arm-unknown-linux-gnueabihf,x86_64-unknown-linux-gnu
make -j4
sudo make install
Note "-j4" needs at least 8GB RAM, so if you hit a problem above try "make" instead.
Install ARM rustc libraries In native rustc build
sudo ln -s $HOME/src/rust/arm-unknown-linux-gnueabihf /usr/lib/rustlib/arm-unknown-linux-gnueabihf
Create hello.rs containing:
pub fn main() {
println!("Hello, world!");
}
Compile hello.rs, and tell rustc the name of the cross-compiler (which must be in your PATH):
rustc -C linker=arm-linux-gnueabihf-gcc-4.9 --target=arm-unknown-linux-gnueabihf hello.rs
Check that the produced binary is really an ARM binary:
$ file hello
hello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), (..)
SUCCESS!!!:
Check: the binary should work on an ARM device
$ scp hello me#arm:~
$ ssh me#arm ./hello
Hello, world!
I've used this to build and link a Rust project with a separate C library as well. Instructions similar to the above on how to do this, dynamically or statically are in a separate post, but I've used my link quota up already!
The best way to figure this out is to download the source code for Servo and explore it on your own. Servo is absolutely a cross-platform codebase, so it will have to address all of these questions, whether they be answered in build/configuration files, or the Rust source itself.
It looks like the rust compiler might not be ready to build standalone binaries for windows yet (see the windows section here), so this probably can't be done yet.
For posix systems it should mostly Just Work unless you're trying to do GUI stuff.
Yes, you won't need to change the source, unless you are using specific libraries that are not cross-platform.
But as #dbaupp said native executables are different on each platform, *nix uses ELF, Windows PE, and OSX Mach-O. So you will need to compile it for each platform.
I don't know the state of cross-compiling in rust, but if they already implemented it, then you should be able to build all the binaries in the same platform, if not, you will have to build each binary on it's platform.

How to cross compile CMake for ARM with CMake

In short I'm trying to cross compile CMake with CMake, and I don't think I'm linking libraries correctly. What I want to do may not be possible, but I'd at least like to know why it isn't possible if that's the case.
System: The host is a Linux box with a Cavium ARM9 CPU. It's currently running version 2.6.24.4 of the Linux kernel and Debian 5.0 (Lenny). My workstation is a Core i5 running Ubuntu 12.04 LTS (Precise Pangolin).
My overall goal is to get ROS running on the Linux box. I have to compile from source rather than use apt since Debian 6.0 (Squeeze) binaries require thumb support that the Cavium does not give, and not many of the needed packages are available for Debian 5.0 (Lenny). I'd made progress installing the various libraries needed, but when I got to step 1.3.1 and tried to run CMake, I got the error
CMake 2.8 or higher is required. You are running version 2.6.0
Next I tried to download and build CMake 2.8.8 on the Linux box itself, but it was too much for the system. When that failed, I downloaded the toolchain suggested on the manufacturer's website and used the cross-compiling guide at [www.cmake.org/Wiki/CMake_Cross_Compiling] to build the CMake executables. Here is my toolchain file:
# This one is important
SET(CMAKE_SYSTEM_NAME Linux)
# Specify the cross compiler
SET(CMAKE_C_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc)
SET(CMAKE_CXX_COMPILER /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-g++)
# Where is the target environment
SET(CMAKE_FIND_ROOT_PATH /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu /pathto/crosstool-linux-gcc-4.5.2-gclibc-2.9-oabi/arm-unknown-linux-gnu/arm-unknown-linux-gnu)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# For libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
However, use of the binary on the Linux box gives the error
cmake: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by cmake)
Sure enough, the library is not there:
prompt# strings /usr/lib/libstdc++.so.6 | grep GLIBC
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBC_2.3
GLIBC_2.0
GLIBC_2.3.2
GLIBC_2.1
GLIBC_2.1.3
GLIBC_2.2
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH
I've never cross-compiled before, but I can see one of two scenarios happening: either the binary got created with a link to a higher version of glibcxx on the host machine or the manufacturer's toolchain is more modern than their image. I don't know how to check which is happening or if something else is happening that I don't know about.
My last effort involved trying to statically cross-compile CMake to hopefully get rid of the linking error with
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-technologic.cmake -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXE_LINKER_FLAGS_RELEASE="-static" ..
I got build errors, and that binary didn't work either. I got:
FATAL: kernel too old
Segmentation fault
I'd try installing glibcxx 3.4.14 on the Linux box, but it doesn't look like it's available for this processor.
I've tried searching for CMake dependencies or system requirements and can't find anything. I've also searched on how to build CMake, but most searches turn up how to build other things with CMake rather than building CMake itself.
I do cross-compile a lot for ARM9 devices using CMake, and indeed this looks like you're not linking to the same libs you have on your target device. You shouldn't need to build CMake yourself to get this done, since it does have good support for cross-compiling since version 2.6. Just make sure you set the CMAKE_FIND_ROOT_PATH variable to a path where you have an exact copy of the root filesystem you have on your target device (with libraries and binaries pre-compiled for the target processor). That should solve your problems.
As a sidenote, I like to use crosstool-ng for building my cross-compilers. It is a really nice tool which helps you to build them from scratch, so I try to match the compiler version and glibc to the ones originally used to build the root filesystem (I usually start with a ready made root filesystem from ARMedslack, since I use Slackware for my development box and ARMedslack for my ARM targets).

Does WxPack works with GCC 4.5/4.6 Series

Hello I have installed TDM-GCC compiler suite for windows. Do i need to install MinGW 5.1.3 gcc 3.4.5 (candidate) to make wxpack work as said here
A late reply but here goes...
You can rebuild wxwidgets with whatever version you have I think.
In the build/msw directory you'll find a wxBuild_wxWidgets.bat file supporting
any number of compilers (I recompiled to match my VC++2008).
Near the top of the batch file are two variables, GCCDIR and GCC4DIR. Set the latter
to point to your GCC 4.x location. Then rebuild with
wxBuild_wxWidgets.bat MINGW4 ALL
It should work but I haven't tried it. On my old P4 Dell the build with VC90 took awhile.