What exactly does -x option mean in Perl if - perl

I know no Perl, so please be patient!
This is a bit from the script, that generates the error:
if (-x '/usr/bin/gcc') {
$gcc = Fink::Services::enforce_gcc(<<GCC_MSG);
Under CURRENT_SYSTEM, Fink must be bootstrapped or updated with gcc
EXPECTED_GCC, however, you currently have gcc INSTALLED_GCC selected.
This typically is due to alteration of symlinks which were
installed by Xcode. To correct this problem, you will need
to restore the compiler symlinks to the configuration that
Apple provides.
GCC_MSG
$gcc = "-gcc" . $gcc;
}
This script installs fink package manager on Macs. (I'm not a Mac user, trying to help out my friend to install a program that is originally a GNU program and needs to be compiled from sources).
The install script complains about the version of GCC being not what it expects. I suspect that this is the place that fails, but don't quite understand what is it doing.
I've tried creating a symlink to the installed GCC, which is version 4.2.1, while fink wants version 4.2.
This message is displayed if I put a symlink to GCC into /usr/bin. Otherwise it identifies the version of GCC properly and refuses to install.
I thought that -x switch is similar to Bash and means that it is checking that the file is an executable, but I'm not sure what exactly does it do in Perl and would it treat a link to an executable as executable?
Thanks!

it test is the file has the executable bit set.
in your case: chmod -x /usr/bin/gcc will cause your if block to no execute.
chmod +x /usr/bin/gcc will casue your if block to get execute.

Perl's file test operators (you can see the documentation using the command: perldoc -f -x) usually do follow symlinks, with the exceptions of -l and lstat(). If you specifically want to test the link rather than the target, you can first do one of those, and then test -x _; _ as an argument makes it reuse the last stat results.

-X File is executable by real uid/gid

Related

How to pass compile options to perl using plenv or perlbrew

I have one machine that runs Windows 10 with Bash on Ubuntu on Windows. It uses some kind of FUSE filesystem that has no proper hard link support.
Because of this, a typical perl compilation fails. If I want to compile, I need to do:
echo "dont_use_nlink='define'" >> Policy.sh
./Configure -des
make
make install
What I'd ideally want is to be able to use either perlbrew or plenv to manage my perls and pass the dont_use_nlink parameter to any perl I build. Is there any way to do this?
Fortunately, it looks like the underlying issue in Win10 WSL is fixed, and will be (hopefully) released soon.
As MichielB pointed out, -A or -D seem like they should accomplish this, but it appears from some of my testing that perl's Configure doesn't honor -A or -D arguments when -de is also passed (see "usage" in perl's metaconfig for the significance of those args). Despite clearly seeing properly formed -A and -D flags in the args list of the generated config.sh, the dont_use_nlink never gets added.
As it happens, perlbrew passes those as the defaults unless you use the special PERLBREW_CONFIGURE_FLAGS environment variable.
However, there is a workaround. You can use PERLBREW_CONFIGURE_FLAGS to use -f to pass our own configuration file. We can use the mostly-correct config.sh generated by a failed "perlbrew install" run, then tweak it and pass it in.
Steps:
Run a perlbrew install that will fail, eg:
perlbrew install perl-5.24.0
Copy the generated config.sh file somewhere for modification and reuse:
cp /home/USERNAME/perl5/perlbrew/build/perl-5.24.0/config.sh ~/config_dont_use_nlink.sh
Edit the file to and insert dont_use_nlink='define'. If you're being tidy and filing it alphabetically, it'll go between dlsrc and doubleinfbytes:
dlsrc='dl_dlopen.xs'
dont_use_nlink='define'
doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
Run perlbrew install, but set an environment variable that will cause "-f" to be passed through to the new perl's Configure script:
PERLBREW_CONFIGURE_FLAGS="-de -f /home/USERNAME/config_dont_use_nlink.sh" perlbrew install perl-5.24.0
That compiles for me on a mostly-clean WSL on Win10 build 14393, and has nearly all tests pass (with the remainder looking like stuff with WSL bugs already filed).
I haven't looked at Windows 10 or the new bash shell for Windows, so I don't know how compatible that new Windows bash environment is with perlbrew or plenv.
An alternative approach would be to leverage versions of portable Strawberry Perl. A while back, David Farrell wrote berrybrew to mimic perlbrew on Windows using portable Strawberry Perl rather than compiling Perl from source code. He wrote a blog post about it and put his stuff out on GitHub (berrybrew). Later, Steve Bertrand wanted to add more functionality and eventually ended up forking the project. You can read more about it on his blog post and his forked project is out on GitHub (see here).
Unless you're needing/wanting to build Perl versions from source code, using berrybrew may provide you with the functionality that you're looking for.

DDT error: D Standard Library [Error: none found]

I have installed dmd and ddt as instructed:
DMD64 D Compiler v2.066.0
Copyright (c) 1999-2014 by Digital Mars written by Walter Bright
Documentation: http://dlang.org/
but when I create a dub project in eclipse, I dot an error that says standard libray not found:
(source: p.im9.eu)
any ideas?
OS: Mac OSX 10.9
Eclipse: 4.4
DDT: 0.10.2
I've also posted a temporary workaround in the discussion group (link):
# cd /usr/share/dmd
# mkdir dummy
# mkdir dummy/bin
# touch dummy/bin/dmd
# launchctl setenv DUB_COMPILERS_PATH /usr/share/dmd/dummy/bin
# killall Dock
Note that the DUB_COMPILERS_PATH variable shouldn't point to the binary itself, it acts like an additional PATH variable, i.e should contain bin dirs.
To make this survive a reboot, add the launchctl line to /etc/launchd.conf:
launchctl setenv DUB_COMPILERS_PATH /usr/share/dmd/dummy/bin
You might need to create it if it doesn't already exist.
This seems to be a reported bug of DDT:
https://github.com/bruno-medeiros/DDT/issues/75
Basically, it boils down to the directory structure of the installed dmd. As they are many distributions and many installers, each one with its own convention, DDT missed some.
They should be added and recognized shortly, in the pending release.
Please follow the reported issue on github/DDT page.
Yes, I know this thread is really old, and yes DDT seems to be no longer in development.
However, for those of us who are new to D, Eclipse and DDT, and relatively new to using Linux (I'm using Mint 19.3), I have the following solution which worked for me. No doubt this is common knowledge somewhere, but I had to scratch around quite a lot to discover this. (Of course, your dmd version number may be different.)
Note that dub is automatically installed along with dmd in:
$HOME/dlang/dmd-2.090.1/linux/bin64/dub
The command
source ~/dlang/dmd-2.090.1/activate
will modify the $PATH variable to allow access to the compiler.
NOTE that this only changes the path for the shell where the command is issued... and only for the current session!
If you want the path change to be permanent (who doesn't?), add the following to ~/.profile using a text editor, e.g. nano ~/.profile or xed ~/.profile , etc.:
# Add dlang dmd compiler path
if [ -d "$HOME/dlang/dmd-2.090.1/linux/bin64" ] ; then
PATH="$HOME/dlang/dmd-2.090.1/linux/bin64:$PATH"
fi
This corrects the Eclipse error:
"D Standard Library [Error: none found]"
in the Project tree, and also allows dub to be run from any directory, e.g. from a terminal.
HTH.

How do I install cygwin components from the command line?

Is there a tool in the Cygwin package similar to apt-get on Debian or yum on redhat that allows me to install components from the command line?
Cygwin's setup accepts command-line arguments to install packages from the command-line.
e.g. setup-x86.exe -q -P packagename1,packagename2 to install packages without any GUI interaction ('unattended setup mode').
(Note that you need to use setup-x86.exe or setup-x86_64.exe as appropriate.)
See https://cygwin.com/packages/ for the package list.
For a more convenient installer, you may want to use
apt-cyg as your package manager. Its syntax similar to
apt-get, which is a plus. For this, follow the above
steps and then use Cygwin Bash for the following steps
wget https://raw.githubusercontent.com/transcode-open/apt-cyg/master/apt-cyg
chmod +x apt-cyg
mv apt-cyg /usr/local/bin
Now that apt-cyg is installed. Here are few examples of
installing some packages
apt-cyg install nano
apt-cyg install git
apt-cyg install ca-certificates
There is no tool specifically in the 'setup.exe' installer that offers the
functionality of apt-get. There is, however, a command-line package installer
for Cygwin that can be downloaded separately, but it is not entirely stable and
relies on workarounds.
apt-cyg: http://github.com/transcode-open/apt-cyg
Check out the issues tab for the project to see the known problems.
There exist some scripts, which can be used as simple package managers for Cygwin. But it’s important to know, that they always will be quite limited, because of...ehm...Windows.
Installing or removing packages is fine, each package manager for Cygwin can do that. But updating is a pain since Windows doesn’t allow you to overwrite an executable, which is currently running. So you can’t update e.g. Cygwin DLL or any package which contains the currently running executable from the Cygwin itself. There is also this note on the Cygwin Installation page:
"The basic reason for not having a more full-featured package manager is that
such a program would need full access to all of Cygwin’s POSIX functionality.
That is, however, difficult to provide in a Cygwin-free environment, such as
exists on first installation. Additionally, Windows does not easily allow
overwriting of in-use executables so installing a new version of the Cygwin
DLL while a package manager is using the DLL is problematic."
Cygwin’s setup uses Windows registry to overwrite executables which are in use
and this method requires a reboot of Windows. Therefore, it’s better to close
all Cygwin processes before updating packages, so you don’t have to reboot
your computer to actually apply the changes. Installation of a new package
should be completely without any hassles. I don’t think any of package managers
except of Cygwin’s setup.exe implements any method to overwrite files in use,
so it would simply fail if it cannot overwrite them.
Some package managers for Cygwin:
apt-cyg
Update: the repository was disabled recently due to copyright issues (DMCA takedown). It looks like the owner of the repository issued the DMCA takedown on his own repository and created a new project called Sage (see bellow).
The best one for me. Simply because it’s one of the most recent. It doesn’t use Cygwin’s setup.exe, it rather re-implements, what setup.exe does. It works correctly for both platforms - x86 as well as x86_64. There are a lot of forks with more or less additional features. For example, the kou1okada fork is one of the improved versions, which is really great.
apt-cyg is just a shell script, there is no installation. Just download it (or clone the repository), make it executable and copy it somewhere to the PATH:
chmod +x apt-cyg # set executable bit
mv apt-cyg /usr/local/bin # move somewhere to PATH
# ...and use it:
apt-cyg install vim
There is also bunch of forks with different features.
sage
Another package manager implemented as a shell script. I didn't try it but it actually looks good.
It can search for packages in a repository, list packages in a category, check dependencies, list package files, and more. It has features which other package managers don't have.
cyg-apt
Fork of abandoned original cyg-apt with improvements and bugfixes. It has quite a lot of features and it's implemented in Python. Installation is made using make.
Chocolatey’s cyg-get
If you used Chocolatey to install Cygwin, you can install the package cyg-get, which is actually a simple wrapper around Cygwin’s setup.exe written in PowerShell.
Cygwin’s setup.exe
It also has a command line mode. Moreover, it allows you to upgrade all installed packages at once (as apt-get upgrade does on Debian based Linux).
Example use:
setup-x86_64.exe -q --packages=bash,vim
You can create an alias for easier use, for example:
alias cyg-get="/cygdrive/d/path/to/cygwin/setup-x86_64.exe -q -P"
Then you can, for example, install Vim package with:
cyg-get vim
First, download installer at: https://cygwin.com/setup-x86_64.exe (Windows 64bit), then:
# move installer to cygwin folder
mv C:/Users/<you>/Downloads/setup-x86_64.exe C:/cygwin64/
# add alias to bash_aliases
echo "alias cygwin='C:/cygwin64/setup-x86_64.exe -q -P'" >> ~/.bash_aliases
source ~/.bash_aliases
# add bash_aliases to bashrc if missing
echo "source ~/.bash_aliases" >> ~/.profile
e.g.
# install vim
cygwin vim
# see other options
cygwin --help
I wanted a solution for this similar to apt-get --print-uris, but unfortunately apt-cyg doesn't do this. The following is a solution that allowed me to download only the packages I needed, with their dependencies, and copy them to the target for installation. Here is a bash script that parses the output of apt-cyg into a list of URIs:
#!/usr/bin/bash
package=$1
depends=$( \
apt-cyg depends $package \
| perl -ne 'while ($x = /> ([^>\s]+)/g) { print "$1\n"; }' \
| sort \
| uniq)
depends=$(echo -e "$depends\n$package")
for curpkg in $depends; do
if ! grep -q "^$curpkg " /etc/setup/installed.db; then
apt-cyg show $curpkg \
| perl -ne '
if ($x = /install: ([^\s]+)/) {
print "$1\n";
}
if (/\[prev\]/) {
exit;
}'
fi
done
The above will print out the paths of the packages that need downloading, relative to the cygwin mirror root, omitting any packages that are already installed. To download them, I wrote the output to a file cygwin-packages-list and then used wget:
mirror=http://cygwin.mirror.constant.com/
uris=$(for line in $(cat cygwin-packages-list); do echo "$mirror$line"; done)
wget -x $uris
The installer can then be used to install from a local cache directory. Note that for this to work I needed to copy setup.ini from a previous cygwin package cache to the directory with the downloaded files (otherwise the installer doesn't know what's what).
Old question, but still relevant. Here is what worked for me today (6/26/16).
From the bash shell:
lynx -source rawgit.com/transcode-open/apt-cyg/master/apt-cyg > apt-cyg
install apt-cyg /bin
Dawid Ferenczy's answer is pretty complete but after I tried almost all of his options I've found that the Chocolatey’s cyg-get was the best (at least the only one that I could get to work).
I was wanting to install wget, the steps was this:
choco install cyg-get
Then:
cyg-get wget
Usually before installing a package one has to know its exact name:
# define a string to search
export to_srch=perl
# get html output of search and pick only the cygwin package names
wget -qO- "https://cygwin.com/cgi-bin2/package-grep.cgi?grep=$to_srch&arch=x86_64" | \
perl -l -ne 'm!(.*?)<\/a>\s+\-(.*?)\:(.*?)<\/li>!;print $2'
# and install
# install multiple packages at once, note the
setup-x86_64.exe -q -s http://cygwin.mirror.constant.com -P "<<chosen_package_name>>"

How do I stop cpan from reconfiguring each time? + More

I'm running on a Mac (version 10.6.3) and am struggling to understand what is going on with my Perl installation.
I let the system do a copy from my previous mac, and I appear to have a second perl installed, which appears earlier in my path. I can't tell (or remember) if I might have installed it with fink, macports or CPAN or what.
type -a cpan
cpan is /opt/local/bin/cpan
cpan is /usr/bin/cpan
I'm seeing two oddities. (To start with!) When I run cpan, and let it configure in ~lcuff/.cpan, each time I run it, it wants to reconfigure, giving the message:
Sorry, we have to rerun the configuration dialog for CPAN.pm due to
some missing parameters...
Also, when I try to install File::Find::Rule (so I can list my CPAN modules, per the FAQ) I end up with an error message that I can't decipher or Google a solution for:
Use of inherited AUTOLOAD for non-method Digest::SHA::shaopen() is deprecated at /opt/local/lib/perl5/vendor_perl/5.8.9/darwin-2level/Digest/SHA.pm line 55.
Catching error: "Can't locate auto/Digest/SHA/shaopen.al in \#INC (\#INC contains: /sw/lib/perl5 /sw/lib/perl5/darwin /opt/local/lib/perl5/site_perl/5.8.9/darwin-2level /opt/local/lib/perl5/site_perl/5.8.9 /opt/local/lib/perl5/site_perl /opt/local/lib/perl5/vendor_perl/5.8.9/darwin-2level /opt/local/lib/perl5/vendor_perl/5.8.9 /opt/local/lib/perl5/vendor_perl /opt/local/lib/perl5/5.8.9/darwin-2level /opt/local/lib/perl5/5.8.9 /Users/lcuff) at /opt/local/lib/perl5/vendor_perl/5.8.9/darwin-2level/Digest/SHA.pm line 55\cJ" at /opt/local/lib/perl5/5.8.9/CPAN.pm line 359
CPAN::shell() called at /opt/local/bin/cpan line 198
I just went through my first migration to a new Mac last week, including a switch from fink and system perl to MacPorts and custom perl, so I remember the pain all too well...
As Schwern said, /opt/local is the default install location for MacPorts; fink uses /sw.
I did encounter a similar problem with CPAN configuration, although I didn't make any attempt to determine whether it was repeatable or not.
The first time I ran CPAN config, it said that I had an existing CPAN dir at ~/.cpan and stored the configuration there.
The second time, it wanted to configure into an existing CPAN dir at ~/Library/Application Support/.cpan. I didn't feel like repeating the CPAN configuration, so I broke out, did a quick cd ~/Library/Application Support/.cpan ; rm -rf .cpan ; ln -s ~/.cpan ., and it's worked great for me since then.
Hopefully this will at least help get you pointed in the right direction.
Have a look at Perlbrew.
Perlbrew allows you to install and manage mulitple versions for Perl under your home directory at ~/perl5
Installation is easy:
curl -LO http://xrl.us/perlbrew
chmod +x perlbrew
./perlbrew install
and simply follow the instructions.
Been using it for past few months on Mac OSX and it worked like a charm!
/I3az/

What is ltmain.sh, and why does automake say it is missing? What is a good auto (make/conf/etc) generator?

I just want to develop a C app in linux with the auto(make/conf/...) stuff automatically generated. I tried generating it with ede and anjuta, but it doesn't seem to generate Makefile.am. So, I tried running automake, and it says "ltmain.sh" isn't found. Is there some easy to generate the basic build files for linux C/C++ apps. What is the standard practice? Do most people write these files themselves?
Generating a really trivial set of autotool files is pretty easy. Here's a (really basic) example. After you run these, you should get a copy of ltmain.sh in the directory, and you'll be all set to run the configure script:
$ mkdir sample
$ cd sample
$ echo 'int main( void ) { return 0; }' > foo.c
$ echo 'bin_PROGRAMS = foo' > Makefile.am
$ autoscan
$ mv configure.scan configure.ac
$ # edit configure.ac, add AM_INIT_AUTOMAKE([foreign])
$ # and LT_INIT, set project name and bug-report-address
$ autoreconf -ivf
Note that in this example, libtool really isn't necessary since
the example is just building a simple app. But you asked about
ltmain.sh, and that's a libtool thing so LT_INIT is needed to
address that portion of the question. If you want to build
a library, change bin_PROGRAMS to lib_LTLIBRARIES.
EDE can work with your Automake files in two different ways. If you write your own automake files, it will read them, and tweak them via the UI.
If you prefer, you can have EDE do the whole thing for you. First, create your first C file, then when it is on disk, do:
M-x ede-new RET Automake RET
then from the project/project options menu, add a target, like "program".
If you fill in your C file, you can then choose Project->Build->build currentproject from the menu, and it will create and setup everything needed for Automake to do it's thing, in addition to running all the misc automake commands needed.
Lastly, there is a 'run' option somewhere to run your program.
I'd consider not using autoconf and automake at all -- their complexity outweighs their benefit, particularly if you're targeting only Linux.
Note that "git", for example, doesn't use them at all; instead it simply has a moderately-complex (but comprehensible) Makefile.