Change default g++ architecture on Mac OS X? - c++

With Mac OS X 10.6 Apple changed the default target of g++ so it produces 64-bit rather than 32-bit code. I know I can specify "-arch i386" on the command line but is there any way to globally change the default architecture by means of an environment variable or similar? (I keep getting linking errors because I'm having real problems finding all the places I need to specify the architecture on the project I'm porting.)

Not that I know of. Depending on the configuration & build system you’re using, setting the CXXFLAGS, CFLAGS, and LDFLAGS environmental variables to include -arch i386 can help. However, some configuration & build system are tricky and it might not be sufficient to set those variables.
Another option is to provide a g++ (and friends as needed) bash script in a PATH location that precedes /usr/bin and invokes the actual command with -arch i386 along with the command-line arguments passed to the script.
An alternative to the solution described in the previous paragraph is to use arch(1) in one of its various forms. For instance, the shell script described above could invoke arch -i386 /usr/bin/g++. You can also set the ARCHPREFERENCE environmental variable to something like g++:/usr/bin/g++:i386,x86_64 and invoke arch /usr/bin/g++. However, note that you must use arch to invoke /usr/bin/g++.

Option 1
You could set your path so that it searches your private bin directory first.
In this bin directory place a g++ script that explicitly invokes the correct g++ compiler will the appropriate flags.
Option 2
Set a g++ alias. This will then be used in preference to a command. Set the alias to run the command with the appropriate flags.
Note: Both of these assume you are building from the command line as XCode probably explicitly executes the g++ binary.

Related

In CMake, how do you change default compiler flags for a build type on a per-user basis? [duplicate]

This question already has answers here:
Change default value of CMAKE_CXX_FLAGS_DEBUG and friends in CMake
(2 answers)
Closed 5 years ago.
In cmake, the default release compiler flags for gcc are -O2 -DNDEBUG. I want them to be -Ofast -NDEBUG. And I want that to be true for every project I do things with in cmake without imposing that choice on any other consumers of my project.
How do I do that?
I could edit them into that project's CMakeLists.txt file. But then I'm forcing other people to agree with my choice. Also, I have to be really careful about how I do it to make sure that I only affect compilers for which that is a valid set of flags to use.
I could use ccmake on every project every time I check out a new tree or create a new build environment. But that's a huge hassle when I want to set the flags to the same thing every time.
Is there a way to set it up so that for me, personally, the default compiler flags for clang and gcc for the various build types are what I want them to be?
Similarly, it's noticing I have ccache and gcc. And that's fine. But it might be nice to force a different default choice for compiler as well, but just for me personally, not for anybody else who chooses to use my project.
Is this possible?
I normally set compiler flags in cmakelists.txt by adding an environment variable into my build script, then referencing that in cmakelists.txt.
#build.sh
export MY_CXXFLAGS="-std=gnu++11 -Ofast -NDEBUG -Wall -Wno-unused-function -Wno-unknown-pragmas"
cmake `pwd` -Dtest=ON
make -j9
Then in my CMakeLists.txt, I'll have the following line:
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{MY_CXXFLAGS}")
It's simple then to pass arguments to build.sh, which is just a bash script, to change the content of MY_CXXFLAGS, based on the users needs. (E.g. build.sh -b DEVELOP|DEBUG|RELEASE etc).
My current answer to this question is to create a global ~/.config/Kitware/default.cmake file that contains initial cache settings and to use cmake -C <path to default.cmake> ... remainder of cmake options ... to run cmake.
In the process of figuring this out I initally named the file ~/.config/Kitware/CMakeCache.txt and found something quite odd that appears to be a bug in cmake. I posted this question about it: Why does this cmake initial cache file result in such strange errors?

linux correct syntax to pass custom directory for libstdc++.so.6 via config

I have a custom compiled gcc 5.4.0 with the following folder structure /home/gccprefix/lib64/libstdc++.so.6.
So far compiling has been going well passing extra flags via configure such as CC=/home/gccprfix/bin/gcc CFLAGS=-fPIC CFLAGS=-Wfatal-errors CFLAGS=-I/home/gccprefix/header/tr1.
But now I have it a problem compiling cairo with /home/gccprefix/bin/ragel. To compile I have a bash script with the flags allocated as a variable, such as
MYFLAGS="CC=/home/gccprfix/bin/gcc CFLAGS=-fPIC CFLAGS=-Wfatal-errors CFLAGS=-I/home/gccprefix/header/tr1"
.../configure ${MYFLAGS}
Ragel was compiled with the /home/gccprefix/bin/gcc as above with no errors.
However during make for cairo, I get
ragel: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ragel)
This is due to gcc finding the default /usr/lib64/libstdc++.so.6. So following several threads on SO I believe I need to extend the flags passed to configure.
What is the correct syntax
`CFLAGS=-Wl,-rpath,/home/gccprefix/lib64`
or do I drop the CFLAGS=
`-Wl,-rpath,/home/gccprefix/lib64`
Using the first option with CFLAGS= the new libstdc++.so.6 is not passed and the same error occurs, using the send without a CFLAGS just gives an error
configure: error: unrecognized option: `--Wl,-rpath,/home/gccprefix/lib64'
So what prefix do I use?
The correct syntax would be
./configure ... LDFLAGS=-Wl,-rpath=/home/gccprefix/lib64
Looking at the generated Makefiles, you could probably get away with CXXFLAGS but not with CFLAGS which are not used at all for a C++-only project.
Note CFLAGS=-fPIC CFLAGS=-Wfatal-errors CFLAGS=-I... is pointless, only -I... will be passed to the compiler, and only to a C compiler. Try CXXFLAGS="-fPIC -Wfatal-errors -I..." instead, making sure configure gets that as a single argument. Passing it via MYFLAGS probably won't work.

how scons pass sysroot to g++

I had set sysroot in CXXFLAGS
and when compile object file I can see sysroot in cmd line
but when build elf I cann't find the sysroot in cmd line, so build failed
so how can I pass sysroot in scons rightly?
SCons has a variety of flags that can be set for the different tasks, and you can always add your own if you need. As you correctly figured out, CXXFLAGS is used when compiling files...but not for linking. You'll have to add your flag to LINKFLAGS...a rather complete list of all available variables and their meaning can be found in the UserGuide ( http://www.scons.org/doc/production/HTML/scons-user.html ). Also note that there is a second set of flags/variables for shared objects (SHCXXFLAGS/SHLINKFLAGS).

How to define where libs are loaded from

I am trying to compile omniORB on AIX 6.1 with gcc 4.2.0.
The initialization does not work as it is picking up the non pthreaded library.
If I set LIBPATH to /opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/ omniNames will not work, as the streams interface gives an exception.
Setting the LIBPATH to /opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/pthread seems to work, but other non pthreaded programs will pick up the pthreaded lib which may cause problems...
The link looks like this:
g++ -o omniNames -O2 -Wall -Wno-unused -fexceptions -Wl,-brtl -Wl,-blibpath:/lib:/usr/lib:/opt/dbx/omniORB-4/lib -L../../../lib -L../../../../lib omniNames.o NamingContext_i.o log.o omniNamesWin.o -lomniORB4-ar -lomnithread34 -lpthreads
How do I resolve this ??
Note that I have tried to change libpath using configure arguments but without success.
Launching via a wrapper script which set LIBPATH correctly is probably the easiest.
Then there is the RUNPATH/RPATH feature of ELF which allows to embded a search path for dynamic libraries in the executable; but I don't know if AIX implement it. It it does and is set with the same argument as for Linux and Solaris, -Wl,--enable-new-dtags -Wl,-R$(RUNPATH) for DT_RUNPATH, -Wl,--disable-new-dtags -Wl,-R$(RPATH) for DT_RPATH; you may want to test also simply -Wl,-R$(RPATH) (which will probably set the DT_RPATH).
Each OS uses its own unique set of environment variables to decide where to search for shared libraries.
Most UNIX like systems use LD_LIBRARY_PATH (but it varies).
I found that the most effective way to find which environment variable to use is to look at the man page for dlopen() on the platform you are building for.
Edited: also note that these variables act like the PATH environment variables, in that they are a list of paths that are ':' separated. So could you not set the environment like this:
# Using tcsh syntax for setting environment. Your shell may very.
setenv LIBPATH "/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/:/opt/freeware/lib/gcc/powerpc-ibm-aix6.1.0.0/4.2.0/pthread"
The AIX ld man page states:
Note: If you specify a shared object, or an archive file containing a
shared object, with an absolute or relative path name, instead of with
the -lName flag, the path name is included in the import file ID string
in the loader section of the output file. You can override this
behavior with the -bnoipath option.
So, just specifying /my/path/to/libfoo.so instead of -lfoo should give you the behaviour you want.

How to Use CCache with CMake?

I would like to do the following: If CCache is present in PATH, use "ccache g++" for compilation, else use g++. I tried writing a small my-cmake script containing
CC="ccache gcc" CXX="ccache g++" cmake $*
but it does not seem to work (running make still does not use ccache; I checked this using CMAKE_VERBOSE_MAKEFILE on).
Update:
As per this link I tried changing my script to
cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
but cmake bails out complaining that a test failed on using the compiler ccache (which can be expected).
As of CMAKE 3.4 you can do:
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
It is now possible to specify ccache as a launcher for compile commands and link commands (since cmake 2.8.0). That works for Makefile and Ninja generator. To do this, just set the following properties :
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) # Less useful to do it for linking, see edit2
endif(CCACHE_FOUND)
It is also possible to set these properties only for specific directories or targets.
For Ninja, this is possible since version 3.4.
For XCode, Craig Scott gives a workaround in his answer.
Edit : Thanks to uprego and Lekensteyn's comment, I edited the answer to check if ccache is available before using it as launcher and for which generators is it possible to use a compile launcher.
Edit2: #Emilio Cobos recommended to avoid doing that for the linking part as ccache doesn't improve linking speed and can mess with other types of cache like sccache
I personally have /usr/lib/ccache in my $PATH. This directory contains loads of symlinks for every possible name the compiler could be called from (like gcc and gcc-4.3), all pointing to ccache.
And I didn't even create the symlinks. That directory comes pre-filled when I install ccache on Debian.
From CMake 3.1, it is possible to use ccache with the Xcode generator and Ninja is supported from CMake 3.4 onwards. Ninja will honour RULE_LAUNCH_COMPILE just like the Unix Makefiles generator (so #Babcool's answer gets you there for Ninja too), but getting ccache working for the Xcode generator takes a little more work. The following article explains the method in detail, focussing on a general implementation which works for all three CMake generators and making no assumptions about setting up ccache symlinks or the underlying compiler used (it still lets CMake decide the compiler):
https://crascit.com/2016/04/09/using-ccache-with-cmake/
The general gist of the article is as follows. The start of your CMakeLists.txt file should be set up something like this:
cmake_minimum_required(VERSION 2.8)
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Support Unix Makefiles and Ninja
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()
project(SomeProject)
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
if(RULE_LAUNCH_COMPILE AND CMAKE_GENERATOR STREQUAL "Xcode")
# Set up wrapper scripts
configure_file(launch-c.in launch-c)
configure_file(launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_BINARY_DIR}/launch-c"
"${CMAKE_BINARY_DIR}/launch-cxx")
# Set Xcode project attributes to route compilation through our scripts
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
endif()
The two script template files launch-c.in and launch-cxx.in look like this (they should be in the same directory as the CMakeLists.txt file):
launch-c.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$#"
launch-cxx.in:
#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$#"
The above uses RULE_LAUNCH_COMPILE alone for Unix Makefiles and Ninja, but for the Xcode generator it relies on help from CMake's CMAKE_XCODE_ATTRIBUTE_... variables support. The setting of the CC and CXX user-defined Xcode attributes to control the compiler command and LD and LDPLUSPLUS for the linker command is not, as far as I can tell, a documented feature of Xcode projects, but it does seem to work. If anyone can confirm it is officially supported by Apple, I'll update the linked article and this answer accordingly.
I didn't like to set a symlink from g++ to ccache. And CXX="ccache g++" didn't work for me as some cmake test case wanted to have just the compiler program without attributes.
So I used a small bash script instead:
#!/bin/bash
ccache g++ "$#"
and saved it as an executable in /usr/bin/ccache-g++.
Then C configured cmake to use /usr/bin/ccache-g++ as C++ compiler.
This way it passes the cmake test cases and I feel more comfortable than having symlinks that I might forget about in 2 or 3 weeks and then maybe wonder if something doesn't work...
I verified the following works (source: this link):
CC="gcc" CXX="g++" cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*
Update: I later realized that even this does not work. Strangely it works every alternate time (the other times cmake complains).
Let me add one important item that was not mentioned here before.
While bootstrapping a minimalistic build system from the ubuntu:18.04 docker image, I've found that order of installation makes a difference.
In my case ccache worked fine when calling gcc, but failed to catch invocations of the same compiler by the other names: cc and c++.
To fully install ccache, you need to make sure all compilers are installed first, or add a call to update-ccache symlinks to be safe.
sudo /usr/sbin/update-ccache-symlinks
export PATH="/usr/lib/ccache/:$PATH"```
... and then (due to updated symlinks) also calls to cc and c++ get caught!
In my opinion the best way is to symlink gcc,g++ to ccache, but if you would like to use within cmake, try this:
export CC="ccache gcc" CXX="ccache g++" cmake ...
Here are 2 methods I think are clean/robust, and also don't pollute your CMake code.
1.) Set environment variables
This method is nice since you don't have to individually set it up for each CMake project. The con is you may not want ccache for each CMake project.
# Requires CMake 3.17 (https://cmake.org/cmake/help/latest/envvar/CMAKE_LANG_COMPILER_LAUNCHER.html)
export CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache
export CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache
2.) Pass in cache variables during project configuration
Con a bit annoying to do for each project. This can be negated by your IDE though.
# Requires CMake 3.4
$ cmake ... -D CMAKE_CXX_COMPILER_LAUNCHER=/usr/bin/ccache \
-D CMAKE_C_COMPILER_LAUNCHER=/usr/bin/ccache
NOTE: It isn't really necessary to specify the full path.
If ccache is in your path you can just specify ccache instead.
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
export CMAKE_C_COMPILER_LAUNCHER=ccache
It is extending #Nicolas answer.
Add following line to your cmake file:
list(PREPEND CMAKE_PROGRAM_PATH /usr/lib/ccache)
Or add it as argument to cmake configuration step:
cmake -DCMAKE_PROGRAM_PATH=/usr/lib/ccache