Author Topic: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?  (Read 3517 times)

0 Members and 1 Guest are viewing this topic.

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« on: April 11, 2024, 11:53:58 am »
x86/64bit: x86_64-pc-linux-gnu
x86/32bit: { i486-pc-linux-gnu, i586-pc-linux-gnu, i686-pc-linux-gnu }

host: x86_64-pc-linux-gnu
target: i686-pc-linux-gnu

Code: [Select]
do_crossdev_2024_v3 build
building i686-pc-linux-gnu ...
 * Refusing to create a cross-compiler using the same
 * target name as your host_utils.

but host_utils are x86_64-pc-linux-gnu!

I'm a bit perplexed by this, also because it suggests using a wrapper
Code: [Select]
sys-devel/multilib-gcc-wrapper ...
      i686-pc-linux-gnu-cpp
      i686-pc-linux-gnu-cc
      i686-pc-linux-gnu-gcc
      i686-pc-linux-gnu-c++
      i686-pc-linux-gnu-g++
      i686-pc-linux-gnu-gfortran

Code: [Select]
/usr/bin/i686-pc-linux-gnu-gcc
COLLECT_GCC=x86_64-pc-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/12/lto-wrapper
Target: x86_64-pc-linux-gnu

Code: [Select]
/usr/bin/x86_64-pc-linux-gnu-gcc
COLLECT_GCC=/usr/bin/x86_64-pc-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/12/lto-wrapper
Target: x86_64-pc-linux-gnu

Is this how it works? it's correct? or did I mess up too much? :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #1 on: April 11, 2024, 12:08:26 pm »
(
I'm planning a multi-library stage1-4
some 32bit and some 64bit
I need two toolchains, at least apparently

the new kernel will be 64bit only
as I need to address 8Gbyte of RAM
)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14893
  • Country: fr
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #2 on: April 12, 2024, 04:51:07 am »
I'm not completely sure I got your issue here. But if you're wondering about which gcc supports what, historically the x86_64 targets well, AMD64 and i686, 32-bit x86 CPUs.
But I think you can use just a x86_64 gcc and generate 32-bit code with it using the -m32 option flag. (Unless possibly 32-bit support has been disabled when building it, which is possible.)
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #3 on: April 12, 2024, 09:23:27 am »
I'm not completely sure I got your issue here.

I have written several builders that, for different reasons, need to work with a specific toolchain for an architecture/bit, so I treat them *like if* they were completely different architectures

ARM
aarch64-unknown-linux-gnu-12
armv5tel-softfloat-linux-gnueabi-12
armv7a-unknown-linux-gnueabihf-12

HPPA
hppa-unknown-linux-gnu-12
hppa64-unknown-linux-gnu-12

x86
i686-pc-linux-gnu-11,12
x86_64-pc-linux-gnu-12

MIPS
loongarch64-unknown-linux-gnu (actually, this is not MIPS64 compatibile at the binary level)
mips-unknown-linux-gnu
mips64-unknown-linux-gnu
mipsel-unknown-linux-gnu ("el" means little endian, this compiles for the SONY Playstation1, as well as for MK routers)
mips64el-unknown-linux-gnu
mips5p-myc (this compiles for MIPS5++, it's my compiler, myc forced to "c/89" compatibility, which is 90%)

PPC
powerpc-unknown-linux-gnu-13
powerpc64-unknown-linux-gnu-13

RISCV
riscv-unknown-linux-gnu-13
riscv64-unknown-linux-gnu-13


But if you're wondering about which gcc supports what, historically the x86_64 targets well, AMD64 and i686, 32-bit x86 CPUs.

Yup, precisely  :D

crossdev was written by Vapier (Gentoo dev), I'm trying to understand a bit of his motivations.

Given that on x86_32 stage4 (like in the exable above, taken from my old macmini 2009 with 2GB of ram, running both 32bit kernel and 32bit userland) crossdev has no problems keeping separate

i686-pc-linux-gnu-11 * <------------ host compiler
x86_64-pc-linux-gnu-12 * <----------- crosscompiler

While on x86_64 stage4 (on my new mac-mini 2009 with 8GB of ram) crossdev suggests using gcc_x86_64 also for { i486, i586, i686 }, which is ... a bit weird for me  :-//

x86_64-pc-linux-gnu-12 * <----------- host compiler
i686-pc-linux-gnu-11 * <------------ should be *THE* cross compiler, but crossdev refuses to emerge, suggests templates to the host compiler

 ...and I wonder... if this is okay.


But I think you can use just a x86_64 gcc and generate 32-bit code with it using the -m32 option flag.
(Unless possibly 32-bit support has been disabled when building it, which is possible.)

from the standard profile, it has been configured:
Quote
/var/tmp/portage/sys-devel/gcc-12.2.1_p20230121-r1/work/gcc-12-20230121/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/12 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/12/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/12/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --disable-libunwind-exceptions --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 12.2.1_p20230121-r1 p10' --with-gcc-major-version-only --disable-esp --enable-libstdcxx-time --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libssp --disable-libada --disable-cet --disable-systemtap --disable-valgrind-annotations --disable-vtable-verify --disable-libvtv --without-zstd --enable-lto --without-isl --enable-default-pie --enable-default-ssp

ummm  :o
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6514
  • Country: fi
    • My home page and email address
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #4 on: April 12, 2024, 02:51:53 pm »
For what it is worth, here is how I'd investigate the issue.
  • The error message is generated in crossdev Bash script, whenever HCHOST == CTARGET.

    My first step would be to add a debug echo "HCHOST='${HCHOST}' == CTARGET='${CTARGET}'" before the exit, and rerun.
     
  • HCHOST is a copy of CHOST, only set in the setup_portage_vars() function, via portageq envvar -v CHOST.  That is, its value is set by Portage, per /var/db/repos/gentoo/profiles/info_vars.
     
  • CTARGET is parsed from the command line (-t TARGET), with the optional cross- or cross_llvm- prefix omitted.  I do believe this is i686-pc-linux-gnu.
I believe the added debug echo would output
    HCHOST='i686-pc-linux-gnu' == CTARGET='i686-pc-linux-gnu'
which would indicate that for whatever reason, your Portage CHOST is misconfigured to i686-pc-linux-gnu instead of the x86_64-pc-linux-gnu one would expect; i.e. that the problem is Portage configuration in /var/db/repos/gentoo/profiles/info_vars not matching the hardware.

Assuming this is the case, I'd investigate why that would be the case, and if there is no overriding reason, change it (to x86_64-pc-linux-gnu) and rerun.
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #5 on: April 12, 2024, 04:14:26 pm »
For what it is worth, here is how I'd investigate the issue.

I will.
Indeed, it sounds weird.

I mean, in the list above I didn't forget to mention PowerPC/LE, because all the IBM POWER9 machines were forced BE, but note that the POWER9 is a PPC64/BE and I have emerged a PPC/BE compiler to compile for the PowerMac-G4

powerpc-unknown-linux-gnu-13 <----------- cross compiler
powerpc64-unknown-linux-gnu-13 <----------- host compiler

So, we will see for x86  :o :o :o
« Last Edit: April 12, 2024, 06:35:20 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #6 on: April 12, 2024, 04:49:36 pm »
Code: [Select]
...
if [[ ${HCHOST} == "${CTARGET}" ]] ; then
        eerror "Refusing to create a cross-compiler using the same target name as your host utils."

        echo "tp1: suppa debug:"
        echo "     HCHOST='${HCHOST}'"
        echo "    CTARGET='${CTARGET}'"
        echo "     HCHOST='${HCHOST}' == CTARGET='${CTARGET}'"

        exit 1
fi

for hchost in "${HCHOSTS[@]}"; do
        if [[ ${hchost} == "${CTARGET}" ]] ; then
                eerror "Refusing to create a cross-compiler using the same target name as your host utils."
                eerror "Consider using sys-devel/multilib-gcc-wrapper package."

                echo "tp2: suppa debug:"
                echo "     HCHOST='${HCHOST}'"
                echo "    CTARGET='${CTARGET}'"
                echo "     hchost='${hchost}'"
                echo "     HCHOST='${HCHOST}' == CTARGET='${CTARGET}'"
                echo "     hchost='${hchost}' == CTARGET='${CTARGET}'"
                exit 1
        fi
...
(/usr/bin/crossdev)

Code: [Select]
do_crossdev_2024_v3 build
building i686-pc-linux-gnu ...
 * Refusing to create a cross-compiler using the same target name as your host utils.
 * Consider using sys-devel/multilib-gcc-wrapper package.
tp2: suppa debug:
     HCHOST='x86_64-pc-linux-gnu'
    CTARGET='i686-pc-linux-gnu'
     hchost='i686-pc-linux-gnu'
     HCHOST='x86_64-pc-linux-gnu' == CTARGET='i686-pc-linux-gnu'
     hchost='i686-pc-linux-gnu' == CTARGET='i686-pc-linux-gnu'
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #7 on: April 12, 2024, 04:50:26 pm »
hchost='i686-pc-linux-gnu'

this is wrong!
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6514
  • Country: fi
    • My home page and email address
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #8 on: April 12, 2024, 05:47:22 pm »
Right, so it is HCHOSTS in crossdev that contains the i686-pc-linux-gnu.  This is obtained from Portage in two steps, by looking up all ABI names using
    portageq envvar ABI MULTILIB_ABIS DEFAULT_ABI
and then adding each architecture obtained using
    portageq envvar CHOST_ABI
to HCHOSTS.

Could you run and show the output of
Code: [Select]
for evar in ABI MULTILIB_ABIS DEFAULT_ABI; do
    printf 'portageq envvar %s = "%s"\n' "$evar" "$(portageq envvar $evar)" ; do
    for abi in $(portageq envvar $evar); do
        printf 'portageq envvar CHOST_%s = "%s"\n' "$abi" "$(portageq envvar "CHOST_$abi")"
    done
done

Also, running
    grep -e i686-pc-linux-gnu /var/db/repos/gentoo/profiles/info_vars
would be informative.

I believe that the core issue is that because the host x86_64 GCC supports 32-bit x86 targets via the -m32 option, the Portage environment variables are configured to list i686_pc_linux_gnu as one of the multilib targets supported (via MULTILIB_ABIS).

However, because this is a dedicated compatibility gcc option and not an actual direct target, I do believe simply editing out the compatibility arch from the portage config, or simply omitting this check in crossdev, should allow the script to generate a proper cross compiler.  I could be wrong, though, because I haven't tried to create a gcc cross compiler with i686 target from x86-64 host myself.
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #9 on: April 12, 2024, 08:44:42 pm »
Code: [Select]
portageq envvar ABI = "amd64"
portageq envvar CHOST_amd64 = "x86_64-pc-linux-gnu"
portageq envvar MULTILIB_ABIS = "amd64 x86"
portageq envvar CHOST_amd64 = "x86_64-pc-linux-gnu"
portageq envvar CHOST_x86 = "i686-pc-linux-gnu"
portageq envvar DEFAULT_ABI = "amd64"
portageq envvar CHOST_amd64 = "x86_64-pc-linux-gnu"

Code: [Select]
grep -e i686-pc-linux-gnu /usr/portage/profiles/info_vars
<--- no result
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14893
  • Country: fr
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #10 on: April 12, 2024, 09:40:08 pm »

from the standard profile, it has been configured:
Quote
/var/tmp/portage/sys-devel/gcc-12.2.1_p20230121-r1/work/gcc-12-20230121/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/12 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/12/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/12/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/12/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --disable-libunwind-exceptions --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 12.2.1_p20230121-r1 p10' --with-gcc-major-version-only --disable-esp --enable-libstdcxx-time --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libssp --disable-libada --disable-cet --disable-systemtap --disable-valgrind-annotations --disable-vtable-verify --disable-libvtv --without-zstd --enable-lto --without-isl --enable-default-pie --enable-default-ssp

From what I can tell, it has been configured to support both 32-bit & 64-bit (--enable-multilib --with-multilib-list=m32,m64), so it should be usable to generate both 32-bit and 64-bit objects/executables.
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #11 on: April 13, 2024, 08:59:24 am »
From what I can tell, it has been configured to support both 32-bit & 64-bit (--enable-multilib --with-multilib-list=m32,m64), so it should be usable to generate both 32-bit and 64-bit objects/executables.

yup, Thanks for confirming that it can technically be done :-+

it took only 20 hours to complete on my two nodes mac-mini intel cluster, thanks to distcc + MPI.
This morning I got a new stage3, this time with separate toolchains
Code: [Select]
   [1] i686-pc-linux-gnu-13 <----------- it only generates 32bit (cross-compiler)
   [2] x86_64-pc-linux-gnu-13 <----------- it only generates 64bit (host-compiler)
(Host Portage ARCH: amd64)

Now I wonder:
A) keep it and make it stage4
B) use the default (gentoo) one, and make it stage4
that's the question  :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #12 on: April 13, 2024, 09:05:13 am »
ummm, look here

Code: [Select]
# ls -l bin
bin -> usr/bin
# ls -l sbin
sbin -> usr/bin
# ls -l lib
lib -> usr/lib
# ls -l lib64
lib64 -> usr/lib64

I hadn't noticed it before :o :o :o :o

{ bin, sbin, lib, lib64 } are links to usr/* :-//
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6514
  • Country: fi
    • My home page and email address
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #13 on: April 13, 2024, 09:12:39 am »
From what I can tell, it has been configured to support both 32-bit & 64-bit (--enable-multilib --with-multilib-list=m32,m64), so it should be usable to generate both 32-bit and 64-bit objects/executables.
Fully agreed.  In Portage, this shows up as MULTILIB_ABIS="amd64 x86", with CHOST_x86="i686_pc_linux_gnu" telling crossdev no cross compiler is needed for that target.

In practice, it means that when you use the -m32 gcc option, it will look for dynamic libraries under e.g. /lib/i?86-linux-gnu/ instead of /lib/x86_64-linux-gnu/.

I see two workable solutions for this dilemma.
One is to recompile the host gcc as non-multilib.
The other is to ensure -m32 -march=i686 -mtune=i686 or equivalent is passed to the host compiler when compiling for 32-bit targets.  Unfortunately, while you already have a wrapper script that does this, it does not change the gcc -v or gcc -dumpmachine outputs.

Edit: Ninja'd by DiTBho himself!  Yes, I'd use the non-multilib gcc x86_64/amd64 host, and cross-compiler for i686, that you just got compiled, and proceed forwards with those.  The 32/64-bit multilib is useful when you have precompiled 32-bit binaries or object files you want to run or link on the host; when you do not have such, you do not need a multilib compiler either.  (It is notable that the Linux kernel itself uses different mechanisms for x86 and amd64/x86_64 syscalls, so there is no "switch": both 32-bit and 64-bit intel/amd kernel syscall interfaces are available all the time for userspace applications.  You can verify this yourself if you want to, by writing a small inline extended assembly wrapper for say write syscall, using both x86 and amd64 syscall ABIs.)
« Last Edit: April 13, 2024, 09:19:17 am by Nominal Animal »
 
The following users thanked this post: DiTBho

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #14 on: April 13, 2024, 01:28:59 pm »
@Nominal Animal
do you use Gentoo, too?
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6514
  • Country: fi
    • My home page and email address
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #15 on: April 13, 2024, 02:04:20 pm »
@Nominal Animal
do you use Gentoo, too?
Nope.

I believe I did a test install well over a decade ago, but decided it wasn't for me; haven't used Gentoo since.
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #16 on: April 13, 2024, 02:55:34 pm »
I've been using Gentoo since pre-beta in 2004, for 20 years   :o :o :o :o
Many things have changed, now this crazy idea of throwing all the bin and sbin files into /usr ... bah ...  :o

Code: [Select]
macmini2-intel /mnt/disk3/src/machine/platform/x86/net5501/kernel/kernel-5.15.093-x86-net5501 # ./mybuild-2024 2
[step2] compiling
kernel-5.15.093(x86/net5501)
| experimental, vanilla + { my, OpenWRT } patches
toolchain(i686-pc-linux-gnu:2.39.0/13.2.0)
-----------------------------------------------
checking myhost as qualified_host ... (speculative) success
checking .config ... success
checking blobs ... success
-----------------------------------------------
gadget_to_do(build) ... kernel/build
cleaning .............. done
gadget_to_do(clean) ... kernel/clean
building kernel ...

This is the practical reason why it is so important on the new stage4 amd64  :o :o :o

The kernels and the various firmwares are compiled by a builder, which manages everything by profiles.
Therefore which machine can compile, with which toolchain, and C/as compiler version.
And this is used to keep track of the various work environments (toolchain and ecosystem) which have thus produced working results.

Working with several virtual machines and chroots, I've had bad surprises in the past and this is the only clean way to proceed

So, I have a variable in /etc/ that takes into account the new stage4 just produced, it will have a unique ID, which, if good, will be trusted as "qualified host".

For now I have just speculatively assumed that it "can produce" a working kernel (i.e. that both the compilers work and ecosystem { perl, python, ...} ).
Then I will verify the matter, and if it passes I will definitively add the new stage4 to the list of Qualified Hosts!

Although it uses an AMD Geode i686-compatible CPU, so although it's an x86 machine, I really like that net5501 router  ;D
« Last Edit: April 13, 2024, 03:09:41 pm by DiTBho »
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline DiTBhoTopic starter

  • Super Contributor
  • ***
  • Posts: 4019
  • Country: gb
Re: gcc: x86_64-pc-linux-gnu >= i686-pc-linux-gnu ?
« Reply #17 on: April 13, 2024, 03:03:45 pm »
the new 64bit version
Code: [Select]
# myhost
macmini2-intel/v19.5-2024-04-amd64
(will stay in a chroot until it is mature enough)


the old 32bit version
Code: [Select]
# myhost
macmini2-intel/v17.0-2020-08-i686
(will be replaced and archived)
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf