I have an issue where pybind11 cannot find the cmake command python3_add_library, see source here. So I tried to look it up in the CMake source, see line 493 in FindPython3.cmake:
if (COMMAND __Python3_add_library)
macro (Python3_add_library)
__Python3_add_library (Python3 ${ARGV})
endmacro()
endif()
But for some reason I am not able to find the source of the command __Python3_add_library() that is used by this macro. I did a grep for it in the CMake installation directory but to no avail. Where can I find this command?
Related
I am using cmake version 3.14.0-rc3 to make my codes. When I target any code written in C or C++ in my CMakelist.txt as follows, it works pretty and makes the executable file.
cmake_minimum_required(VERSION 3.3)
PROJECT (HELLO)
ADD_EXECUTABLE(hello hello_world.cpp)
but while I am trying to make this code with Tcl scripts, it fails and I receive the following fatal error:
Fatal error while making a tcl script with cmake
Can anyone help me to overcome this issue? It seems that cmake is not normally able to compile Tcl scripts.
Thank in advance for your kind replies and helps.
Bests,
Daryon
You have to watch out for a different path, e.g., running custom commands or adding custom targets to your CMake project. You seem to confuse the nature of libraries, executables, and external commands in the context of CMake, I am afraid.
I think there should be a way to execute Tcl scripts with CMake as
well.
You might want to attempt the following: In CMakeLists.txt, you define a custom target MyTarget that calls out to a TCLSH executable, if available:
CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
PROJECT (HELLO)
find_program (TCLSH tclsh)
if (TCLSH)
add_custom_target(
MyTarget ALL
COMMAND TCLSH myScript.tcl
)
endif (TCLSH)
(1) find_program and if/endif will make the custom target only available under the condition that an executable called tclsh was found.
(2) myScript.tcl is a Tcl script in your project directory.
(3) Running cmake . && make will call out to effectively to: tclsh myScript.tcl, producing:
$cmake . && make
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/hello
This is a message written by Tcl scripts
Built target MyTarget
This is just to get you started, you will have to read more about adding commands, targets, or executing sub-processes from within CMake.
I'm working with a code generator that produces C++ and a CMakeLists.txt file, unfortunately I cannot use this in my main CMakeLists.txt file for testing purposes.
For example you have the following CMakeLists.txt file:
project(SomeProject CXX C)
add_custom_command(OUTPUT ${SRCS}
COMMAND ${CODEGEN_CLI_PATH} -i "${INPUT}" -o "${OUT}"
COMMENT "Generating sources"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM
)
add_custom_target(CODEGEN
DEPENDS
${SRCS}
)
# Needs to be executed after the custom command
add_subdirectory(${GENERATED_CMAKE_LISTS_LOCATION})
Is it possible to use functions such as add_subdirectory only after you execute custom commands for a particular target, such as CODEGEN?
I've already tried to execute it by adding an extra line to the existing custom command:
COMMAND ${CMAKE_COMMAND} -D DIR=${GENERATED_CMAKE_LISTS_LOCATION} -P add_subdirectories.cmake
Unfortuantly this doesn't work because it isn't allowed to execute functions like add_subdirectory in script mode.
Neither I can manage to call custom made functions (that are executing add_subdirectory) from add_custom_command that are located in the same file.
Nope, it is not possible. The add_subdirectory command is run during configuration step, while CODEGEN is a target that runs during build.
You seem to be doing something wrong, so the only advice I can give you is to use execute_process command to run commands you need. The execute_process command is executed during configuration stage, so it will be able to generate files you need before add_subdirectory.
But again, please describe your problem, why do you want CMake to do that.
I have a huge fixed unsigned char array that I compiled into a static library. The way I work around it is by:
if(NOT EXISTS ${PATH_TO_FOLDER}/smeagol.a)
add_subdirectory(smeagol)
endif()
I'm still looking for a nicer kung-fu way to do it using cmake. I feel that its out there, and I will update this answer once i find it.
I am working on a project on c++ and need to execute a CMakeLists.txt file to run it. I installed cmake, doxygen, cmake-curses-gui and make using sudo. Then I tried running the file.
The following is a part of the cmake code -
if (BUILD_DOC)
find_package(Doxygen)
configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
${PROJECT_SOURCE_DIR}/doc/Doxyfile #ONLY)
add_custom_target(${PROJECT_NAME}_doc ALL ${DOXYGEN_EXECUTABLE}
${PROJECT_SOURCE_DIR}/doc/Doxyfile)
endif ()
Here, it gave me an error message saying that
CMake Error at CMakeLists.txt:77 (configure_file): configure_file
Problem configuring file
Just so that you know, line 77 is configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in .
If I add AND DOXYGEN_FOUND to the if condition, it doesn't execute anything at all which means that it couldn't find a doxygen executable. But as I already told, I already installed doxygen.
I am new to cmake. So, could anyone please help me with this
Edit:
The OS I am using is Ubuntu 16.04
After I put if(DOXYGEN_FOUND) after the command find_package(doxygen) it executed, but I got the same cmake error in line 78 instead of line 77
Also, now since I got enough information from the comments, I just realized that my problem is more towards finding where the Doxyfile.in file lies than configuring the file. Could anyonee help me with it?
The error is clear
configure_file Problem configuring file
CMake's configure_file(<input> <output>) command is used to copy input file to ouput and replacing #VARIABLES# in input by the corresponding value.
configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in ${PROJECT_SOURCE_DIR}/doc/Doxyfile #ONLY)
You have to find why this process failed:
Make sure ${PROJECT_SOURCE_DIR} contains the correct path to your project, and make sure the file Doxyfile.in is is the right folder (<project dir>/doc)
Make sure content of Doxyfile.in does not contains any syntax error, in particular with #VARIABLES# that needs to be replaced by their CMake value.
Note that this error has nothing to do with Doxygen on your system, and the fact that CMake actually found it or not.
I'm attempting to debug a command line CMake failure. The same CMake file works in Qt Creator, with the arguments in the Qt Creator window matching what I have entered on the command line.
This makes me think Qt Creator is adding some extra arguments, which makes sense since the generator drop down has several options that specify architecture and CMake version.
Is there a way to get the CMake command that Qt Creator executed to produce the desired result, specifically the arguments passed to the CMake executable?
I found one post that talks about viewing the CMakeCache files to do some forensics, but this only proves there are differences, it doesn't quickly show me what arguments to change.
Try adding the following block to the end of your CMakeLists.txt and running CMake from Qt Creator again. The CMake output should list all variables that have been passed via the -D command line argument.
get_cmake_property(CacheVars CACHE_VARIABLES)
foreach(CacheVar ${CacheVars})
get_property(CacheVarHelpString CACHE ${CacheVar} PROPERTY HELPSTRING)
if(CacheVarHelpString STREQUAL "No help, variable specified on the command line.")
get_property(CacheVarType CACHE ${CacheVar} PROPERTY TYPE)
if(CacheVarType STREQUAL "UNINITIALIZED")
set(CacheVarType)
else()
set(CacheVarType :${CacheVarType})
endif()
set(CMakeArgs "${CMakeArgs} -D${CacheVar}${CacheVarType}=\"${${CacheVar}}\"")
endif()
endforeach()
message("CMakeArgs: ${CMakeArgs}")
For more info, see this answer.
This won't show what generator was selected (if any) via the -G arg. To find that, you need to look for CMAKE_GENERATOR:INTERNAL=... in your CMakeCache.txt
If this doesn't help you identify the overall problem, you should probably heed #arrowdodger's advice and post more details about the errors you're getting and your two build environments. For example, an error could be caused simply by running CMake from a subdirectory of the source tree.
I have a command line tool that should be run after CMake created my .sln-file. Is there any way to do that using CMake?
Using execute_process(COMMAND ..) at the end of the CMakeLists.txt does not help because this is executed after the Configure step, however, the .sln-file is created in the generation step.
Thanks a lot!
A rather horrifying way to do it is by calling cmake from cmake and doing the post-generate stuff on the way out of the parent script.
option(RECURSIVE_GENERATE "Recursive call to cmake" OFF)
if(NOT RECURSIVE_GENERATE)
message(STATUS "Recursive generate started")
execute_process(COMMAND ${CMAKE_COMMAND}
-G "${CMAKE_GENERATOR}"
-T "${CMAKE_GENERATOR_TOOLSET}"
-A "${CMAKE_GENERATOR_PLATFORM}"
-DRECURSIVE_GENERATE:BOOL=ON
${CMAKE_SOURCE_DIR})
message(STATUS "Recursive generate done")
# your post-generate steps here
# exit without doing anything else, since it already happened
return()
endif()
# The rest of the script is only processed by the executed cmake, as it
# sees RECURSIVE_GENERATE true
# all your normal configuration, targets, etc go here
This method doesn't work well if you need to invoke cmake with various combinations of command line options like "-DTHIS -DTHAT", but is probably acceptable for many projects. It works fine with the persistently cached variables, including all the cmake compiler detection when they're initially generated.
From the following links, it seems like there is no such command to specify execution after CMake generated .sln files.
https://cmake.org/pipermail/cmake/2010-May/037128.html
https://cmake.org/pipermail/cmake/2013-April/054317.html
https://cmake.org/Bug/view.php?id=15725
An alternative is to write a wrapper script as described in one of the above links.
cmake ..
DoWhatYouWant.exe
Yes, add_custom_command paired with add_custom_target got this covered
http://cmake.org/cmake/help/cmake-2-8-docs.html#command:add_custom_command
http://cmake.org/cmake/help/cmake-2-8-docs.html#command:add_custom_target
For an example take a look at my answer to another question
cmake add_custom_command