# Default to GCC for Port Building



## dantavious (Dec 21, 2012)

I am having problems with building ports with CLANG, how do you default to GCC?
                            V/r
                          Derrick

       FreeBSD 10.0-CURRENT #0: Tue Dec 18 11:40:52 EST 2012


----------



## Beeblebrox (Dec 21, 2012)

If you want a version > gcc42 (like lang/gcc47), then install it from ports and in /etc/make.conf:

```
.if !empty(.CURDIR:M/usr/ports/*) && exists(/usr/local/bin/gcc47)
CC=gcc47
CXX=g++47
CPP=cpp47
.endif
```
Other adjustments needed, details here: http://www.freebsd.org/doc/en/articles/custom-gcc/article.html
If you just want to use gcc42 (from world) replace the number accordingly (42 instead of 47). Since clang is the default compiler for world in HEAD (10), I suspect you do not have gcc42 enabled for buildworld (you have no reason to). Since your default compiler is clang, it's better to install a higher version of gcc from ports.


----------



## kpa (Dec 22, 2012)

This setting in make.conf(5) could also do it:


```
USE_GCC=any
```

Do yourself a favor and don't drop the old GCC4.2 yet from your world build, especially on 10-CURRENT where things might break any day. You can set WITH_CLANG_IS_CC in src.conf(5) to make clang(1) the default cc (already on in 10-CURRENT by default).


----------



## m6tt (Dec 22, 2012)

I use this in make.conf. If you create a empty (or full) file in a port's dir named 'basecc', it will always use the default cc, otherwise it will use gcc47 if installed. You could replace that with gcc instead of gcc47 etc for the old base gcc. 

It also turns on stack smashing protection for all ports, which doesn't seem to cause build issues for me. 

It supports setting workdir to /usr/ports/build (I use a tmpfs there). It should work without doing that. You can probably see where the sed-like path replacement occurs to determine the ports native directory and change it if you'd like.

Of course you should read this http://www.freebsd.org/doc/en/articles/custom-gcc/article.html and understand how to fix issues. There are occasionally issues, and it's still something I've been testing, but many sharp edges are rounded out now.

The reason I do this is so that most ports use gcc47, but the handful that don't can "remember" that they need to use clang or old gcc during large port upgrades. I was tired of ending up with a system built by gcc4.2.1 and losing performance for some programs due to ancient cputypes. This is less of an issue with clang.

Note to replace or remove the CFLAGS and CPUTYPE variables if you don't need them. I removed my host-specific optimizations.


```
.if !empty(.CURDIR:M/usr/ports/*)
CCTESTPATH=     ${.CURDIR:S/\/usr\/ports\/build//g}/basecc
PPTESTPATH=     ${.CURDIR:S/\/usr\/ports\/build//g}/nopropolice
.endif

VPATH+=/

.if !exists(${PPTESTPATH}) && !empty(.CURDIR:M/usr/ports/*) && empty(.CURDIR:M*/work/*)
CFLAGS+=        -fstack-protector-all
.endif

.if !exists(${CCTESTPATH}) && !empty(.CURDIR:M/usr/ports/*) && empty(.CURDIR:M*/work/*)
#.warning make thinks that ${CCTESTPATH} does not exist.
CPUTYPE=<replace with modern cputype for gcc47>
CFLAGS+=<replace with gcc47 specific cflags>
CC=gcc47
CPP=cpp47
CXX=g++47
.endif
```


----------



## dantavious (Dec 22, 2012)

All,
Thanks for the replies. By reading the suggested article via the handbook, I now better understand the process of port building and the options available. Awesome support! Thanks.

Derrick


----------



## MNIHKLOM (Dec 22, 2012)

Beeblebrox said:
			
		

> If you want a version > gcc42 (like lang/gcc47), then install it from ports and in /etc/make.conf:
> 
> ```
> .if !empty(.CURDIR:M/usr/ports/*) && exists(/usr/local/bin/gcc44)
> ...



Hi,

Thank you indeed.  Your hints/suggestions help me in making databases/grass which made me headache for a few days.

Once again, I thank you indeed.

With best regards,
MNIHKLOM


----------



## kpa (Dec 22, 2012)

kpa said:
			
		

> This setting in make.conf(5) could also do it:
> 
> 
> ```
> ...



Actually this is wrong, it overrides the USE_GCC setting unconditionally for all ports. Better use this form:


```
USE_GCC?=any
```


----------



## Beeblebrox (Dec 22, 2012)

@MINIKHOLM: Glad to help. I overlooked a small typo in my first post, but you have figured that out already. Should be:

```
&& exists(/usr/local/bin/gcc4[B][color="Red"]7[/color][/B])
```
@m6tt: There are some simpler ways of getting what you want done in FreeBSD.


> it will always use the default cc, otherwise it will use gcc47 if installed


Have a look at /usr/local/etc/buildflags.conf from sysutils/bsdadminscripts. There is also devel/pkgconf which aims to do the same thing: Per-port settings & preferences for variables to be passed to the build environment. I prefer to use buildflags.conf, but that's just me - so whatever floats your boat. Some example entries from that file:

```
# ---< general ports settings >-------------
/usr/ports | /usr/ports/*{
# Clustering
        FORCE_MAKE_JOBS
        MAKE_JOBS_NUMBER=       6
        WITH_CPUFLAGS
        BUILD_OPTIMIZED
#       USE_DISTCC
        USE_CCACHE
        BUILDFLAGS_GCC=         4.6+
        GCC_DEFAULT_VERSION=    4.6+
#       USE_GCC=                4.6+  # breaks distcc
# Common settings that are applied to all ports in hope to do some good.
        PERL_VERSION= 5.16
        PERL_DEFAULT_VERSION= 5.16
        PERL_PORT= perl5.16
        WITHOUT_IPV6
        WITH_GTK2
        MYSQL_VERSION= 55
        MYSQL_DEFAULT_VERSION= 55
        JAVA_OS=                native
        JAVA_VENDOR=            openjdk
        JAVA_VERSION=           1.7+
        OVERRIDE_JAVA_VERSION=  1.7+
        JAVA_PREFERRED_PORTS=   JAVA_PORT_NATIVE_OPENJDK_JDK_1_7
        OVERRIDE_JAVA_PORT=     java/openjdk7

# ---< per-port settings >-------------
        GNUSTEP_WITH_GCC46=     yes
        */some/port1		{!FORCE_MAKE_JOBS !USE_DISTCC !USE_CCACHE}
        */someother/port        {BUILDFLAGS_GCC= 42}  # If world has gcc42 compiled
        */yetother/port         {BUILDFLAGS_GCC= CC}  # If world uses clang AND has gcc42 disabled
```
A lot more settings also available. This way there is no need to create separate files in each port's folder. What are you going to do with all those files you created when you upgrade your version one day (say from 9 to 10) and you have to dump your old /usr/ports because you have to bring in the ports tree of the new version?


> setting workdir to /usr/ports/build


Is as simple as placing in /etc/make.conf:

```
WRKDIRPREFIX= /pathto/dir
```

@kpa: USE_GCC=any.  Won't this cause a problem if there is lang/gcc47 from ports but gcc42 from world has not been disabled? I believe you meant that would work under the condition of a clang-only world?

WITH_CLANG_IS_CC is a must for anyone who plans / tries to build a clang-only world. AFAIK, that option does not build gcc42 but certain elements of the legacy gcc to interface with clang. A short discussion about this here for anyone interested.

Regards.


----------



## m6tt (Dec 24, 2012)

Beeblebrox said:
			
		

> @MINIKHOLM: Glad to help. I overlooked a small typo in my first post, but you have figured that out already. Should be:
> 
> ```
> && exists(/usr/local/bin/gcc4[B][color="Red"]7[/color][/B])
> ...



I use WRKDIRPREFIX, the make.conf parts mentioned actually remove the WRKDIR from the .CURDIR so the script can check the port's directory, not the work directory. There's probably a better way! 

Regarding the files, I run CURRENT, but that is desired behavior. Since I default to gcc47, I want my ports tree to remember which ports can't use it. Also, removal (if desired) would be as simple as 

```
find /usr/ports -name 'basecc' -exec rm {} \;
```

Pkgconf and buildflags look neat...I just started with the article on using newer versions of GCC and went hacking away .


----------

