How to check Mono version at COMPILE time with xbuild, not Runtime - mono

I know how to check at runtime, but that does no good for my current problem. I have an issue where a certain version of mono (Mono < 4.8.0) does not have TLS 1.1 nor 1.2 support and would not even compile, let alone run. So I need to add a #if to determine which version of mono is being used to compile with but I cant find anything that would do this. #if MONO is not sufficient. Another useful cheatsheet would be something that lists all of mono's predefined vars that are available to the compiler. I'm sure version would probably have been one of those items.
BTW, all users of this project would be compiling the app themselves, so there is no need to do runtime checking. If their mono doesnt support TLS 1.1/1.2, then it should still build on their machine, their particular binary just wouldnt have 1.1/1.2 in them which is completely fine since only they would be running it anyway.

You can export a env var. and use it to set a compiler directive:
Example:
export MONO_VERSION=`mono --version | grep version | cut -d " " -f 5`
echo $MONO_VERSION
5.10.0.179

Related

Compile perlbrew with libperl.so versus libperl.a

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.

Use another compiler when install R packages with Rcpp and CMake

What I'm doing I'm developing an R interface/package for C++ codes with Rcpp and CMake. Because openmp and c++11 should be supported, so I have a preference on compilers.
Problem I know that I can always put Makevars under ~/.R (Unix) to change the compiler R uses when install packages. But as a developer, it is not recommended to do so.
It is recommended to use configure file to do that. However, I don't quite know how to achieve this, because I'm writing configure file by myself and calling cmake inside my configure. I don't know what to write in configure file to search for a specific compiler.
Hope the description is clear. Thank you.
I have attached my configure file content below.
```
set -x
set -e
which cmake
rm -rf _builds
# call cmake that will set compiler flags in src/Makevars
# and download dependencies
cmake -H. -B_builds
```
I've been using CMake for building R packages for quite a while, see https://github.com/rohan-shah/mpMap2 for an example.
I completely bypass the R build system though, so I don't use configure at all.
As I understand, you want to detect if the compiler supports openmp and C++11.
There are many existing packages using configure to detect openmp support. One example is ARTP2 (https://github.com/zhangh12/ARTP2/blob/master/configure.ac), which has been mentioned in the "Writing R extension" as an example. You can also use the configure script in xgboost by me (https://github.com/dmlc/xgboost/blob/master/R-package/configure.ac) as an example. We leave OPENMP_CXXFLAGS blank if the compiler doesn't support openmp.
For C++11 support, you can try AX_CXX_COMPILE_STDCXX_11. But this will require a new version of autoconf.
I think you can also try AC_PROG_CXX to select compilers, like icc.

Is there a way to show where LLVM is auto vectorising?

Context: I have several loops in an Objective-C library I am writing which deal with processing large text arrays. I can see that right now it is running in a single threaded manner.
I understand that LLVM is now capable of auto-vectorising loops, as described at Apple's session at WWDC. It is however very cautious in the way it does it, one reason being the possibility of variables being modified due to CPU pipelining.
My question: how can I see where LLVM has vectorised my code, and, more usefully, how can I receive debug messages that explain why it can't vectorise my code? I'm sure if it can see why it can't auto-vectorise it, it could point that out to me and I could make the necessary manual adjustments to make it vectorisable.
I would be remiss if I didn't point out that this question has been more or less asked already, but quite obtusely, here.
Identifies loops that were successfully vectorized:
clang -Rpass=loop-vectorize
Identifies loops that failed vectorization and indicates if vectorization was specified:
clang -Rpass-missed=loop-vectorize
Identifies the statements that caused vectorization to fail:
clang -Rpass-analysis=loop-vectorize
Source: http://llvm.org/docs/Vectorizers.html#diagnostics
The standard llvm toolchain provided by Xcode doesn't seem to support getting debug info from the optimizer. However, if you roll your own llvm and use that, you should be able to pass flags as mishr suggested above. Here's the workflow I used:
1. Using homebrew, install llvm
brew tap homebrew/versions
brew install llvm33 --with-clang --with-asan
This should install the full and relatively current llvm toolchain. It's linked into /usr/local/bin/*-3.3 (i.e. clang++-3.3). The actual on-disk location is available via brew info llvm33 - probably /usr/local/Cellar/llvm33/3.3/bin.
2. Build the single file you're optimizing, with homebrew llvm and flags
If you've built in Xcode, you can easily copy-paste the build parameters, and use your clang++-3.3 instead of Xcode’s own clang.
Appending -mllvm -debug-only=loop-vectorize will get you the auto-vectorization report. Note: this will likely NOT work with any remotely complex build, e.g. if you've got PCH's, but is a simple way to tweak a single cpp file to make sure it's vectorizing correctly.
3. Create a compiler plugin from the new llvm
I was able to build my entire project with homebrew llvm by:
Grabbing this Xcode compiler plugin: http://trac.seqan.de/browser/trunk/util/xcode/Clang%20LLVM%20MacPorts.xcplugin.zip?order=name
Modifying the clang-related paths to point to my homebrew llvm and clang bin names (by appending '-3.3')
Placing it in /Library/Application Support/Developer/5.0/Xcode/Plug-ins/
Relaunching Xcode should show this plugin in the list of available compilers. At this point, the -mllvm -debug-only=loop-vectorize flag will show the auto-vectorization report.
I have no idea why this isn't exposed in the Apple builds.
UPDATE: This is exposed in current (8.x) versions of Xcode. The only thing required is to enable one or more of the loop-vectorize flags.
Assuming you are using opt and you have a debug build of llvm, you can do it as follows:
opt -O1 -loop-vectorize -debug-only=loop-vectorize code.ll
where code.ll is the IR you want to vectorize.
If you are using clang, you will need to pass the -debug-only=loop-vectorize flag using -mllvm option.

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.

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.