Is there any shortcut or something like this to add, e.g. documentation of a function or class (similar to "///" in Visual Studio and C#)?
Thanks!
You can use /** <Enter>.
I have found a way to do it. I personally use Doxygen for documentation.
CLion plans to integrate it.
You have to write all of it at this time. But when you have documented your code, you can build it with CMake (and then it appears in your build target on CLion).
Here's an example:
cmake_minimum_required(VERSION 3.2)
project(doxygen_test)
find_package(Doxygen)
set(SOURCE_FILES main.cc)
if(DOXYGEN_FOUND)
set(DOXYGEN_INPUT ${SOURCE_FILES})
set(DOXYGEN_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
add_custom_command(
OUTPUT ${DOXYGEN_OUTPUT}
COMMAND ${CMAKE_COMMAND} -E echo_append "Building API Documentation..."
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT}
COMMAND ${CMAKE_COMMAND} -E echo "Done."
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${DOXYGEN_INPUT}
)
add_custom_target(apidoc ALL DEPENDS ${DOXYGEN_OUTPUT})
add_custom_target(apidoc_forced
COMMAND ${CMAKE_COMMAND} -E echo_append "Building API Documentation..."
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT}
COMMAND ${CMAKE_COMMAND} -E echo "Done."
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
endif(DOXYGEN_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_executable(doxygen_test ${SOURCE_FILES})
Sources:
http://www.cmake.org/pipermail/cmake/2007-February/012796.html
https://www.tty1.net/blog/2014/cmake-doxygen_en.html
https://mementocodex.wordpress.com/2013/01/19/how-to-generate-code-documentation-with-doxygen-and-cmake-a-slightly-improved-approach/
https://majewsky.wordpress.com/2010/08/14/tip-of-the-day-cmake-and-doxygen/
Starting from 2016.2 EAP CLion supports Doxygen (http://blog.jetbrains.com/clion/2016/05/keep-your-code-documented/). Start with typing “/**” or “/*!” and then press Enter. In case your function has parameters, returns a value or throws an exception, you’ll get a stub to fill with the documentation text
Related
I have a python script that parses all of the C++ source files in the project's directory, looks for some stuff in the files, and then generates a file. This python script works fine, but I want it to automatically run before building my C++ project.
So basically, I want this python script to run before every build, so if any .h or .cpp files have been changed. I'd also like it to run if the python script itself has been changed. I have the python script in question, genenums.py, in the same directory as my C++ source files such as main.cpp, etc.
I've tried experimenting with add_custom_command based on documentation, but I can't get cmake to ever run this python script in any instance. I'm not sure how to make this work right, as I'm new to cmake.
Here's my current cmake file:
cmake_minimum_required(VERSION 3.9)
project(enum_test)
set(CMAKE_CXX_STANDARD 17)
include_directories(include)
find_package( PythonInterp 2.7 REQUIRED )
find_package( PythonLibs 2.7 REQUIRED )
add_custom_command(
COMMAND ${PYTHON_EXECUTABLE} genenums.py
DEPENDS genenums.py $(CMAKE_CURRENT_BINARY_DIR)
OUTPUT enums.h
WORKING_DIRECTORY $(CMAKE_CURRENT_BINARY_DIR)
COMMENT "Generating enums"
)
add_executable(enum_test main.cpp test.h test.cpp)
Ok, I have a foolproof, non-ugly way to have cmake run any kind of commands right before a build to build a dependency, waiting until the commands are done before doing the build.
add_custom_target(
run ALL
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genenums.py ${CMAKE_CURRENT_SOURCE_DIR}
BYPRODUCTS enums.h
COMMENT "Generating enums"
)
add_dependencies(enum_test run)
The two key parts are the add_custom_target and add_dependencies, both are required to make this work. Place both after the add_executable in CMakeLists.txt. enum_test refers to the target created by add_executable (the first name in its list), so you'd set that to your project's name.
You can name the custom target to whatever you like (I used run here) by changing the run in both add_custom_target and add_dependencies to something else.
There's one additional catch with add_custom_target... WORKING_DIRECTORY in that did nothing for my python script. Even when I tried to set the WORKING_DIRECTORY to ${CMAKE_CURRENT_SOURCE_DIR}, the script executed in the default ${CMAKE_CURRENT_BINARY_DIR} anyway.
So for this one catch, whatever commands you're using need to be able to take a command line argument of ${CMAKE_CURRENT_SOURCE_DIR} and use that to operate in the source directory properly (assuming that's your goal). That's why I have ${CMAKE_CURRENT_SOURCE_DIR} at the end of this line:
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genenums.py ${CMAKE_CURRENT_SOURCE_DIR}
Here's the full CMakeLists.txt with the working setup, should be fairly easy to adapt to any particular project's CMakeLists.txt.
cmake_minimum_required(VERSION 3.9)
project(enum_test)
set(CMAKE_CXX_STANDARD 17)
include_directories(include)
find_package( PythonInterp 2.7 REQUIRED )
add_executable(enum_test enums.h main.cpp test.h test.cpp)
add_custom_target(
run ALL
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genenums.py ${CMAKE_CURRENT_SOURCE_DIR}
BYPRODUCTS enums.h
COMMENT "Generating enums"
)
add_dependencies(enum_test run)
I have a cmake build system gone wild. Before supporting IDEs, everything was ok.
I need to copy files (shaders in this case) to the build directory. They need to be copied when they've changed, regardless of whether the main target is built or not.
I had success before, as I could add a custom command with ${CMAKE_CURRENT_BINARY_DIR}, add dependencies later and everything was fine.
The problem is, when using a generator expression for the command output, it creates a dependency from my custom command to the main target. This means adding a dependency backwards (which is needed to trigger the copy) throws an error because of cyclic dependencies.
This is what I have so far, which doesn't work because the custom target (thus custom command) is not triggered when the main target doesn't need rebuilding.
set(SHADER_IN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/shaders)
file(GLOB_RECURSE SHADERS "${SHADER_IN_DIR}/*.glsl")
add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/shaders/)
set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/.stamps)
add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${STAMP_DIR})
set(STAMP_FILES "")
foreach(SHADER ${SHADERS})
get_filename_component(SHADER_FILENAME ${SHADER} NAME)
set(STAMP_FILE ${STAMP_DIR}/${SHADER_FILENAME}.stamp)
add_custom_command(
OUTPUT ${STAMP_FILE}
COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_FILE}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SHADER} $<TARGET_FILE_DIR:${PROJECT_NAME}>/shaders/${SHADER_FILENAME}
DEPENDS ${SHADER}
)
list(APPEND STAMP_FILES ${STAMP_FILE})
endforeach()
add_custom_target(Shaders
SOURCES ${SHADERS}
DEPENDS ${STAMP_FILES})
# Need to add dependency here! But I can't :(
So, is there any other way to get what output directory will be used in an IDE? All "solutions" I've read to force building a target have failed (they pretty much all rely on add_dependencies).
Thank you for saving my sanity.
In the end, instead of trying to find out where the IDE is going to output the binary, I forced output in a predictable bin/ dir.
set(BINARY_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BINARY_OUT_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BINARY_OUT_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BINARY_OUT_DIR})
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BINARY_OUT_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BINARY_OUT_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${BINARY_OUT_DIR})
endforeach(OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES)
I am invoking a software from CMAKE to generate required files for build.Is it possible to print the version of software invoked in the build window..?
As said in the comments, the exact way to output the version will depend on the executable itself.
Lets assume it is <executable> --version.
Then it CMake it will look like:
find_program(EXECUTABLE_RUNTIME <executable>)
if ("${EXECUTABLE_RUNTIME}" STREQUAL "EXECUTABLE_RUNTIME-NOTFOUND")
message(FATAL_ERROR "<executable> runtime could not be found!")
else()
execute_process(COMMAND "${EXECUTABLE_RUNTIME}" --version
OUTPUT_VARIABLE EXECUTABLE_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Found <executable> runtime at ${EXECUTABLE_VERSION}, version ${EXECUTABLE_VERSION}")
endif()
A possible footgun is to include the command arguments in the quotes (e.g. "${EXECUTABLE_RUNTIME} --version", if you do this the output variable will be empty.
OUTPUT_STRIP_TRAILING_WHITESPACE will remove the new line which is very often present after the version.
I am converting my build system from configure/make to a cmake system
The system has some autogenerated files, from bison/flex. The original makefile commands are:
bison --defines=tokens.h --output=parser.cpp parser.y
flex --outfile=scanner.cpp scanner.l
I came across this ancient link which seems to explain how to do it, but when i run cmake with the following custom commands, nothing appears to happen (no error messages, no file generation)
FIND_PACKAGE(BISON REQUIRED)
IF(BISON_FOUND)
ADD_CUSTOM_COMMAND(
SOURCE ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.y
COMMAND ${BISON_EXECUTABLE}
ARGS --defines=${CMAKE_SOURCE_DIR}/src/rcdgen/tokens.h
-o ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp
${CMAKE_SOURCE_DIR}/src/rcdgen/parser.y
COMMENT "Generating parser.cpp"
OUTPUT ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp
)
ENDIF(BISON_FOUND)
FIND_PACKAGE(FLEX REQUIRED)
IF(FLEX_FOUND)
ADD_CUSTOM_COMMAND(
SOURCE ${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.l
COMMAND ${FLEX_EXECUTABLE}
ARGS -o${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp
${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.l
COMMENT "Generating scanner.cpp"
OUTPUT ${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.cpp
)
ENDIF(FLEX_FOUND)
I am new to cmake, so it's a bit confusing to me. Does anyone have any idea what a working custom_command would be?
The new hotness for bison usage is actually documented in FindBison So for a simple parser project:
find_package(BISON)
BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp
DEFINES_FILE ${CMAKE_CURRENT_BINARY_DIR}/parser.h)
add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
is what you'd do. Likewise for Flex.
The format of your add_custom_commands is not quite right, but they appear to be almost correct. There are two versions of add_custom_command, and the one you want is the one which produces an output file (the parts inside square brackets are optional):
add_custom_command(OUTPUT output1 [output2 ...]
COMMAND command1 [ARGS] [args1...]
[COMMAND command2 [ARGS] [args2...] ...]
[MAIN_DEPENDENCY depend]
[DEPENDS [depends...]]
[IMPLICIT_DEPENDS <lang1> depend1
[<lang2> depend2] ...]
[WORKING_DIRECTORY dir]
[COMMENT comment] [VERBATIM] [APPEND])
The idea is that the custom command only executes if the file specified as the OUTPUT of this command is used as an input elsewhere in the same CMakeLists.txt (e.g. in an add_library or add_executable call).
The custom command therefore will only run at build time (i.e. when you run make), not at configure time (when you run CMake), and only if you're building a target which directly or indirectly needs the OUTPUT file.
To fix your commands, I think the following should work (untested):
FIND_PACKAGE(BISON REQUIRED)
SET(BisonOutput ${CMAKE_SOURCE_DIR}/src/rcdgen/parser.cpp)
IF(BISON_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${BisonOutput}
COMMAND ${BISON_EXECUTABLE}
--defines=${CMAKE_SOURCE_DIR}/src/rcdgen/tokens.h
--output=${BisonOutput}
${CMAKE_SOURCE_DIR}/src/rcdgen/parser.y
COMMENT "Generating parser.cpp"
)
ENDIF()
FIND_PACKAGE(FLEX REQUIRED)
SET(FlexOutput ${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.cpp)
IF(FLEX_FOUND)
ADD_CUSTOM_COMMAND(
OUTPUT ${FlexOutput}
COMMAND ${FLEX_EXECUTABLE}
--outfile=${FlexOutput}
${CMAKE_SOURCE_DIR}/src/rcdgen/scanner.l
COMMENT "Generating scanner.cpp"
)
ENDIF()
ADD_LIBRARY(MyLib ${BisonOutput} ${FlexOutput})
I'd basically like to achieve the same as http://blog.alexrp.com/2013/09/26/clangs-static-analyzer-and-automake, but with CMake.
analyze_srcs = foo.c
analyze_plists = $(analyze_srcs:%.c=%.plist)
CLEANFILES = $(analyze_plists)
$(analyze_plists): %.plist: %.c
#echo " CCSA " $#
#$(COMPILE) --analyze $< -o $#
analyze: $(analyze_plists)
.PHONY: analyze
So you can run
make analyze
make clean
I guess I need to use add_custom_command/add_custom_target and somehow change the "object file" extension just for that target.
Afterwards get a list of the generated files to perhaps pass them to a script for combining them into 1 output file.
Can anyone point me in the right direction?
You can use scan-build when running cmake.
scan-build cmake /path/to/source
scan-build make
scan-build sets the CC and CXX environment variables which are picked up by cmake.
I found a way:
function(add_clang_static_analysis target)
get_target_property(SRCs ${target} SOURCES)
add_library(${target}_analyze OBJECT EXCLUDE_FROM_ALL ${SRCs})
set_target_properties(${target}_analyze PROPERTIES
COMPILE_OPTIONS "--analyze"
EXCLUDE_FROM_DEFAULT_BUILD true)
endfunction()
Combining clang's plist files (which get extension .o this way) into a report is still open ($<TARGET_OBJECTS:objlibtarget>?).
The following solution has the drawback of compiling and analyzing the entire project, not the specific targets.
set(on_side_build_path ${CMAKE_BINARY_DIR}/clang_static_analysis)
set(scan_build_path scan-build)
set(reports_path ${CMAKE_BINARY_DIR}/clang_static_analysis_reports)
# Creates clean directory where the analysis will be built.
add_custom_target(clang_static_analysis_prepare
COMMAND ${CMAKE_COMMAND} -E rm -rf ${on_side_build_path}
COMMAND ${CMAKE_COMMAND} -E make_directory ${on_side_build_path}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
# Runs the analysis from the path created specifically for that task. Use 'my own' project source directory as the source directory.
add_custom_target(clang_static_analysis
# scan-build wants Debug build, for better analysis.
COMMAND ${scan_build_path} ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DCMAKE_BUILD_TYPE=Debug
COMMAND ${scan_build_path}
-v -v -o ${reports_path}
${CMAKE_COMMAND} --build .
WORKING_DIRECTORY ${on_side_build_path}
)
# Run the *_prepare target always before the analysis
add_dependencies(clang_static_analysis clang_static_analysis_prepare)
Invoke it with:
cmake --build . --target clang_static_analysis
Bonus #1: Allowing custom toolchains to work
scan-build injects the CC and CXX environment variables to specify the replaced compilers, which are ccc-analyzer and c++-analyzer. When defining CMAKE_C_COMPILER and CMAKE_CXX_COMPILER the CC and CXX variables will be ignored. What you need to do to support scan-build is to point CMAKE_C*_COMPILER variables to use the one from environment, if defined. So having that in your toolchain file:
set(CMAKE_C_COMPILER some/path/to/c_compiler)
set(CMAKE_Cxx_COMPILER some/path/to/cxx_compiler)
Replace it with:
if(DEFINED ENV{CC})
set(CMAKE_C_COMPILER $ENV{CC})
else()
set(CMAKE_C_COMPILER some/path/to/c_compiler)
endif()
if(DEFINED ENV{CXX})
set(CMAKE_CXX_COMPILER $ENV{CXX})
else()
set(CMAKE_CXX_COMPILER some/path/to/cxx_compiler)
endif()
Bonus #2: Using scan-build from the LLVM toolchain
If your custom toolchain is LLVM, then most probably you want to use the scan-build command from the toolchain. To enable it, simply define the path to toolchain path using cmake's cache variables:
set(LLVM_TOOLCHAIN_PATH "some/path/here" CACHE PATH "Path to the LLVM toolchain")
or from the command line:
cmake -DLLVM_TOOLCHAIN_PATH=some/path/here ...
and then reuse the path from the custom target:
set(scan_build_path ${LLVM_TOOLCHAIN_PATH}/bin/scan-build)
Bonus #3: Adding test command
Note: enable_testing shall be called before add_test. enable_testing() must be called from the project's top level CMakeLists.txt for ctest to resolve paths to tests.
add_test(
NAME clang_static_analysis
COMMAND ${CMAKE_COMMAND} --build . --target clang_static_analysis
)
Run it like that:
# Fire configure and generate stages
cmake ../source/dir
ctest -R clang_static_analysis --verbose