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>
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).
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 try to set a preprocessor macro in the command line of CMake. I've tried:
set generator="Visual Studio 8 2005"
set params=-D MY_MACRO=1
cmake.exe -G %generator% %params% ..\some_project
but it's neither defined when I compile nor can I find the name MY_MACRO in the files generated by CMake at all, except for CMakeCache.txt where it's present in the form:
MY_MACRO:UNINITIALIZED=1
How can I do it?
A good alternative would be to define a cmake option:
OPTION(DEFINE_MACRO "Option description" ON) # Enabled by default
Followed by a condition:
IF(DEFINE_MACRO)
ADD_DEFINITIONS(-DMACRO)
ENDIF(DEFINE_MACRO)
Then you can turn that option ON/OFF via command line with cmake using the -D flag. Example:
cmake -DDEFINE_MACRO=OFF ..
To make sure the compiler is receiving the definition right, you can call make in verbose mode and check for the macro being defined or not:
make VERBOSE=1
This is a good solution also because make will recompile your code when any of cmake options changes.
Try this: -D CMAKE_CXX_FLAGS=/DMY_MACRO=1
The motivation behind the question was to batch build 3rd party libraries, which is why I wanted to avoid modifying CMakeLists. So years later, even though I don't need that anymore, I figured out that it's easily achievable by means external to CMake:
Invoke CMake as usual, no special flags.
Then:
With MSVC: The compiler reads the CL environment variable to get extra command line arguments. So
set CL=/DMY_MACRO=1 %CL%
then invoke MSBuild to do its job.
With Makefiles: The generated makefiles use the CFLAGS and CXX_FLAGS variables as makefiles are expected to do. So the build can be started by
make CXX_FLAGS=-DMY_MACRO=1
or by setting the corresponding environment variables.
Unless you have a good reason not to, you should use ADD_DEFINITIONS(<name>=<value>[, ...]).
Just add the following line to your CMakeLists.txt:
ADD_DEFINITIONS("MY_MACRO=1")
CMake will take care of the syntax of the switches (be it -D<name>=<value>, or /D<name>=<value>).
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.
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]