In my Makefile I have
CC=g++
When I do mgrep gcc, I have several versions listed like:
gnu/gcc/4.2.1
gnu/gcc/4.7.3
etc
I can do a module load to change my gcc version.
Now suppose I want to use multiple versions simultaneously in different makefiles, how do I do it?
The module system is basically just setting up a path to the requested module. If you want a particular compiler in a particular makefile, then you can do three things:
Expect the user of the makefile to load the correct version before calling Make. Possibly combined with some condition based on gcc -v|grep ${GCC_VERSION} to check that it's the right version.
Perform module load gnu/gcc/${GCC_VERSION} inside your makefile.
Use CC=/somewhere/path-to-gcc-version/bin/g++ instead of CC=g++.
Personally, I prefer 1 or 3. You can find out what the path is by doing module load ... and then which g++.
[By the way, I would use CXX=g++ and CC=gcc - assuming you are not compiling files called *.c as C++-code]
Related
I have a simple makefile with a variable for the compiler flags, it also contains some targets that modify that variable and append some flags.
My point with it is to be able to run, for example:
make debug perf
that would in turn add to the variable the flags required to build under that configuration. The problem is that if I run it, it does compile the executable with the debug info, and then tries to compile with the performance tools, and obviously does nothing. Can make only execute the compilation step after both targets run?
Makefile:
CFLAGS = -std=c11 -Wall -pedantic -D_GNU_SOURCE
executable: gcc $(CFLAGS) main.c -o exe
debug: CFLAGS += -g
debug: executable
perf: CFLAGS += -D__PERF__
perf: executable
Make version 4.2.1
One approach is to have different executable files for different flag combinations, ie
executable # default to release build
executable.dbg # with -g
executable.perf # with -D__PERF__
executable.dbgperf # with both
The two advantages are
you're never unsure how some executable file was built, and you never accidentally test the wrong thing / waste time trying to debug something with no debug symbols, etc.
Make's file dependency logic actually works correctly
This does assume you have a manageable number of flag combinations. If there are too many, the profusion of targets may make your Makefile impractical.
I exactly have the same requirements! :-) As this, I compile my executables with all the options in the filename like: myprog-debug-coverage and so on. All the object files goes to a directory like build-myprog-debug-coverage as example. All this has the advantage that there is no need to recompile all if you need it once for debug, do a change and compile for coverage and after next change for debug again.
The first thing you must do is to filter out all non-targets which are needed for the options like debug with:
debug:
#:
to simply do nothing.
In addition, you filter out the non-targets with something like:
export FOUND_ACTIONS=$(filter $(ACTIONS), $(MAKECMDGOALS))
and process these variables later on into the flags you need for compilation like:
$(eval $(call CHECK_FOR_CMDGOAL,debug,export LCXXFLAGS+= -DDEBUG -DGDB_HELPER -g,build_dir_ext=$(build_dir_ext)-debug))
and after that you can write your standard recipes with the found flags from the variables.
I can't give you a ready to use Makefile here as my one is a bit larger while processing a lot of flags like different compilers, memory debug libraries as efence, build for coverage and much more.
I'm in hope that you can catch the idea how to process the pseudo targets for flags and the real targets and how a Makefile can split both.
And yes, that is not how a Makefile works typically. But I believe it is really convenient at the end of the day. Giving manual CXXFLAGS and so on did not the job, as you as a user have a complete list of flags, libs and options on the comand line, which is a nightmare.
This makes no sense to me. Why would you want to compile file(s) as debug, generating a program executable that is built with debug, then in the same make command recompile the same file(s) with optimization, generating a program executable that is built with optimization.
In a single directory there can be only one file named executable, so how can you build the same file twice and have two different versions at the same time? How do you intend to run the debug executable versus the perf executable?
You either need to build different files, or you need to build them into different directories (one for debug and one for perf). I recommend the latter.
But to answer your specific question: it is not possible in make to build the same target multiple different times in the same invocation of make. Once a single make invocation tries to build a target named foo, it will never try to build that target again no matter how many other targets might list it as a prerequisite. If you re-run make again, it will try again to build foo (one time).
I'm working with a third-party-modified version of clang 7.0.0 that has hijacked the -c option, replacing it with a flag -ccdsp for... reasons...
This has created two problems for CMake:
The -ccdsp option seems to be required to be the very first option to clang, before anything else, including -D... and -I... parameters. There is a BEFORE modifier for target_compile_options that I can use to make sure it appears at the start of the option list, but I don't seem to have any control over the ordering of non-options like definitions and include-paths, which results in -ccdsp occurring later in the overall set of parameters. I haven't been able to find a way to ensure that this is the very first option using modern CMake methods. Instead I have had to resort to setting CMAKE_CXX_FLAGS explicitly.
Now that the -c option to specify a source file is no longer available, I need to find a way to get CMake to omit it. It turns out that, as far as I can tell, this flag isn't really required, as clang -c foo.cpp -o foo.o and clang foo.cpp -o foo.o appear to do much the same thing. So I need a way to get CMake to drop the -c option.
I realise that this is an unusual question and it's a situation entirely created by the organisation that provided the modified version of clang. Unfortunately my support requests to them remain (to date) unanswered.
Does anyone know of a way I can work around this issue? Can I create a custom compiler handler in CMake, based on clang, where I add -ccdsp and remove -c somehow?
In CMake a compiler's command line is specified in CMAKE_<LANG>_COMPILE_OBJECT variable.
You may set this variable in a separate file:
my_clang_override.cmake:
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> -ccdsp <FLAGS> -o <OBJECT>")
and include this file into the project's CMakeLists.txt by specifying CMAKE_USER_MAKE_RULES_OVERRIDE variable with either of two ways:
Specify the variable in the CMakeLists.txt itself, before the project() call:
CMakeLists.txt:
# Assume file 'my_clang_override.cmake' to be in the project's source directory.
set(CMAKE_USER_MAKE_RULES_OVERRIDE "my_clang_override.cmake")
Pass the variable's setting to cmake when configure the project:
cmake -DCMAKE_USER_MAKE_RULES_OVERRIDE=<path/to/my_clang_override.cmake> <other-parameters>
I would like to add some compiler and linker flags to the default C++ toolchain, so that all the targets I build (local or imported) share them.
I know that can define my own toolchain, but I don't want to do that as it's very complicated and easy to get wrong.
Ideally I would like something like this:
cc_toolchain = cc_default_toolchain()
cc_toolchain.copts = [...]
cc_toolchain.linkopts = [...]
Also, I don't want to set global flags in the .bashrc file, as it's hard to configure per platform and it's not easy to share among different repositories.
Thanks!
You could set --cxxopt and --linkopt in a shared .bazelrc file that you reference from the different projects (as sub-module or similar) or import in the workspace's local .bazelrc file.
I think you have to copy the default generated toolchain into your project and make modifications in it.
You'd run bazel info to locate your output_base directory, and find the toolchain files there.
Source: https://groups.google.com/g/bazel-discuss/c/N1qvsGMJoAE
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?
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.