I have option subdir-objects set in configure.ac:
AM_INIT_AUTOMAKE([subdir-objects])
Is there any possibility to conditionally disable it in particular Makefiles (Makefile.am)?
Thanks.
According to the list of automake options, no. What you can do instead is remove subdir-objects from the call to AM_INIT_AUTOMAKE and add it to the Makefile.am files where you actually want it. You do that by putting the line AUTOMAKE_OPTIONS = subdir-objects at the top of any relevant Makefile.am. (There's no no-subdir-objects option, apparently.)
Related
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 am trying to add a custom target with CMake that executes one command for each given .cpp file. The command should only be re-executed when the source file itself or one of the included source files changes. AFAIK to achieve this I need a list of all the included files and add them to the DEPENDS option of the add_custom_command() calls that belong to my custom target.
So is there a built-in way to get that list of included files?
I know about the IMPLICIT_DEPENDS option of the add_custom_command() function but it only works for Makefile generators. I would like to make this work for all generators.
Thank you for your time
Edit:
As requested I will post some cmake code to show what I want to achieve.
I want to add a custom target, that runs clang-tidy on all the given .cpp files. When incrementally building the custom target the clang-tidy commands should be re-run whenever a .cpp file or one of its directly or indirectly included header files is changed. Just like re-runs of the compiler are handled.
# ----------------------------------------------------------------------------------------
# mainTargetName The name of the target that shall be analyzed
# files A list of all the main targets .cpp files
#
function( addStaticAnalysisTarget mainTargetName files )
set(targetName runStaticAnalysis_${mainTargetName})
set(command "clang-tidy-4.0 -checks=* -p ${CMAKE_BINARY_DIR}")
foreach( file ${files} )
get_filename_component( baseName ${file} NAME_WE)
set(stampFile ${CMAKE_CURRENT_BINARY_DIR}/analyze_${baseName}.stamp )
set(fullFile ${CMAKE_CURRENT_SOURCE_DIR}/${file})
set(commandWithFile "${command} ${fullFile}")
separate_arguments_for_platform( commandList ${commandWithFile})
add_custom_command(
OUTPUT ${stampFile}
DEPENDS "${fullFile}"
IMPLICIT_DEPENDS CXX "${fullFile}"
COMMAND ${commandList}
COMMAND cmake -E touch "${stampFile}" # without creating a file as a touch-stone the command will always be re-run.
WORKING_DIRECTORY ${CPPCODEBASE_ROOT_DIR}
COMMENT "${commandWithFile}"
VERBATIM
)
list(APPEND stampFiles ${stampFile})
endforeach()
set_source_files_properties(${stampFiles} PROPERTIES GENERATED TRUE) # make the stamp files known to cmake as generated files.
add_custom_target(
${targetName}
DEPENDS ${stampFiles}
)
endfunction()
The problem with that is, that it does not seem to work. When I change included files clang-tidy is not re-run for the affected files.
I used the "Unix Makefile" generator for this example so it should work at least with make. Any hints why it doesn't?
My hopes where that I could achieve the desired behavior for all generators by somehow getting the file-dependencies at cmake time and then adding them to the ''''DEPENDS'''' list. But the dependency scanning must be done each time the command is run, so it can not be done at cmake time. This means that the scanning must be implemented by cmake which it currently is not.
A guy with similar problems:
https://gitlab.kitware.com/cmake/cmake/issues/16830
Edit 2:
I think the problem that the IMPLICIT_DEPENDS option was not working was because I did not use correct filenames. I changed that in the code snipped, but I have not yet tested if it works in the project.
I think the answer to my question is ...
No, you can not use cmakes dependency scanner in the cmake code.
That makes sense, because this problem can not be solved at cmake time, because the dependencies of a .cpp file may change without cmake being re-run.
The problem must be solved within cmake itself at make time. This is done when using the IMPLICIT_DEPENDS option.
Also, I tried to solve a Problem that I did not really have, because at this point I can only run clang-tidy on linux anyways. However, clang-tidy may become available on windows as well and then I may have the problem again.
To sum the comments up:
Tambre stated that CMake is not a compiler and therefore can not do that.
I think this is wrong. According to this article, CMake can parse cpp include dependencies because make has no such dependency searcher itself. That was news to me, but I mostly live on Windows so I am not that familiar with make. It could also be possible that in the meantime make was extended to do its own dependency searching. Also this explains why the IMPLICIT_DEPENDS option is only available for make.
Florian pointed out that it is not necessary to create an own custom target for running clang-tidy. Instead, one can use the CXX_CLANG_TIDY target property to run clang-tidy for each file after compiling it. This means however, that static-analysis can not be separated from the build which could lead to inacceptable buildtimes.
There is the cmake -E cmake_depends command line, that could be used to retrieve dependencies at cmake time. But as stated above, I erroneously thought that I needed the dependencies at cmake time, while I needed them at runtime.
The IMPLICIT_DEPENDS options did not work because I had an error in my cmake code.
I want to pass result of the getconf PAGESIZE command output as preprocessor define to my program in form of -DPAGESIZE=`getconf PAGESIZE` for [[gnu::assume_aligned(PAGESIZE)]] in custom allocator declaration.
I tried the following:
add_definitions(-DPAGESIZE=`getconf PAGESIZE`)
But it expanded exactly as -DPAGESIZE="\`getconf" ... PAGESIZE`, where ... is contents of other CMAKE_CXX_FLAGS*. I.e. there is an issue with escaping of backticks in CMakeLists.txt files.
How to properly pass such an arguments to compiler/linker in CMakeLists.txt files? Maybe is there another way to achieve desired?
Also I tried add_definitions(-DPAGESIZE="$$(getconf PAGESIZE)") ($$ expanded as $ by cmake), but -DPAGESIZE and the rest part are splitted by cmake. add_definitions("-DPAGESIZE=$$(getconf PAGESIZE)") makes cmake to escape every dollar sign though.
According to documentation for add_definitions command, preprocessor definitions, passed to this command, are appended to COMPILE_DEFINITIONS property:
Flags beginning in -D or /D that look like preprocessor definitions are automatically added to the COMPILE_DEFINITIONS directory property for the current directory.
And content of COMPILE_DEFINITIONS property, according to its documentation is always escaped by CMake, so you cannot preserve special meaning of backticks in the build command:
CMake will automatically escape the value correctly for the native build system
Your may modify CMAKE_CXX_FLAGS manually, as you show in your comment.
The better way is to use execute_process command for run needed command at configuration stage, and use its output for add_definitions command. (Or use this output for create additional header file with configure_file).
I am having trouble understanding how assignments in the command line work.
when I run:
qmake-qt4 -project -o project.pro
qmake-qt4 -o qMakeFile "CFLAGS += -std=c++11"
make -f qMakeFile
and after the qMakeFile is make, CFLAGS is unchanged.
I'm sure it's something obvious I am missing.
You have a couple of issues in here:
You are trying to set a C++ option for the CFLAGS variable as opposed to CXXFLAGS.
if I were, I would pass the "CFLAGS+=-std=c++11" to the first qmake run when the project file is created because the variable will be put into the generated qmake file, then, rather than just into the Makefile with your current approach.
This would useful in the sense that when you re-run qmake for some reason, you do not need to pass the CFLAGS explicitly all the time to make sure it will be in your Makefile.
Furthermore, you should consider using the QMAKE_CXX_FLAGS variable instead of raw CXXFLAGS in a qmake project file.
Even furthermore, qmake has better support for c++11 through the CONFIG1 variable.
Another thing is that I would personally remove the needless extra spaces around the appending assignment. If you check out, this generates needless extra spaces in the Makefile, which then need to be escaped and so on.
Also, I am not sure why you need to generate custom Makefile name.
I would personally just write something like this:
qmake -project "QMAKE_CXXFLAGS+=-std=c++11" # only executed once
or this is even more recommended:
qmake -project "CONFIG+=c++11" # only executed once
qmake && make
Please make sure you have a recent enough compiler version that supports this option and C++11 in general. Sometimes, people fall into the trap that they do not notice they would be using an old version that did not support it for the time.
I'm working on a big, old, project that is using autotools. I would like to switch one part of the project to C++ (from C).
How can I switch the compiler used for a part of the project? I don't like the idea of completely splitting the project into two parts. The directory has only Makefile.am and I suppose I should register this somehow in configure.ac.
You must define output variable CXX in configure.ac (the simplest way is by using AC_PROG_CXX macro), then all files with appropriate suffixes (.cc, .cpp) will be compiled by C++ compiler.
In your source root, you mut have a configure.ac and Makefile.am with all the compiler options. So, you can create a subdirectory with a new configure.ac and Makefile.am with other options.
You only need to add this line in the parent configure.ac
AC_CONFIG_SUBDIRS([subdir_name])
And add the new subdirectory in the parent Makefile.am
SUBDIRS= subdir_name
Hope can help.