Using CMake to generate GNU/Makefile as an example, I would like to be able to run different install rules, say make install and make install-doc.
Is there a way to tell CMake to generate this ?
You can add a custom target which invokes the cmake_install.cmake script in the outermost binary directory. This script is also invoked when you run the default install target.
add_custom_target(install-doc
COMMAND "${CMAKE_COMMAND}" "-DBUILD_TYPE=$<CONFIGURATION>"
"-DCOMPONENT=doc" "-P" "${CMAKE_BINARY_DIR}/cmake_install.cmake"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
The desired installation component has to be passed as the CMake variable COMPONENT. The build configuration can be set with the variable BUILD_TYPE. $<CONFIGURATION> is a generator expression which will be replaced by the currently active build configuration.
Related
I have a project where "installing" the code is not quite as simple as just copying some files. With a traditional Makefile, I would just create a make install target that runs a series of shell commands to do what I need.
But googling around has resulting in no examples of this (some things close, but not quite... i think). So basically, I want a custom command, that depends on the target executables, but produces nothing and runs a script that need not be portable to accomplish the "install"
Anyone have any examples of something like this?
CMake's install command allows for custom scripts. See the official documentation: install - Custom Installation Logic:
install([[SCRIPT <file>] [CODE <code>]]
[COMPONENT <component>] [...])
The SCRIPT form will invoke the given CMake script files during installation. If the script file name is a relative path it will be interpreted with respect to the current source directory. The CODE form will invoke the given CMake code during installation. Code is specified as a single argument inside a double-quoted string. For example, the code
install(CODE "MESSAGE(\"Sample install message.\")")
will print a message during installation.
To run custom shell script (or whatever program), combine install(CODE ...) with execute_process:
install(CODE "execute_process(COMMAND my_script.sh)")
This worked for me: use add_custom_target, then add the main target as a dependency to the custom target target.
# create custom target for setcap to be executed
add_custom_target(setcap ALL
WORKING_DIRECTORY ${OUTPUT_DIR}/bin
COMMAND ${CMAKE_COMMAND} -E 'sudo setcap cap_net_raw,cap_net_admin+eip ${}/bin/<executable name>)
# create a dependency on the custom target for main target, setcap depends on ${proj_name}
add_dependencies(setcap ${proj_name})
What I wanted to do is call
add_subdirectory(ext/oglplus)
and be done with it. Unfortunately it is not that simple. There is a huge buildscript which detects various opengl settings. So I tried the following
ExternalProject_Add(liboglplus
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/oglplus
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ext/oglplus/configure.py --use-glew
BUILD_COMMAND ${MAKE})
The problem that I have is don't really want to build it like that. It also doesn't build correctly because for some reason it wants to install the library and because there is no install target it will abort the compilation.
But the build script is calling cmake under the hood.
So what I want to do is to tell cmake to use "cofigure.py" instead of "cmake .." and then use it like any other cmake library.
Is this possible?
I used to call Linux Kernel KBuild from CMake using
ADD_CUSTOM_COMMAND() and ADD_CUSTOM_TARGET()
This way you can run arbitrary commands (like your config.py) and use the output.
First setup the command with all command-line options as CMake-variables, in tou case this would be calling the config.py script ${CMAKE_CURRENT_SOURCE_DIR}/ext/oglplus/.
Instead of encoding the Path to your script in the command (adding ext/oglplus) I think it may be better adding WORKING_DIRECTORY to the custom command:
add_custom_command
SET(KBUILD_CMD ${CMAKE_MAKE_PROGRAM}
-C ${KERNEL_BUILD_DIR}
CROSS_COMPILE=${CROSS_COMPILE} ARCH=${ARCH}
EXTRA_CFLAGS=${KBUILD_EXTRA_CFLAGS}
INSTALL_MOD_PATH=${INSTALL_MOD_PATH}
M=${CMAKE_CURRENT_SOURCE_DIR}
KBUILD_EXTRA_SYMBOLS=${depends_module_ksyms}
)
Add a custom command that calls your build-script and creates a file in the CMAKE_CURRENT_BINARY_DIRECTORY (note the second COMMAND to touch a file)
ADD_CUSTOM_COMMAND(
OUTPUT ${module_name}.built
COMMAND ${KBUILD_CMD} modules
COMMAND cmake -E touch ${module_name}.built
COMMENT "Kernel make modules ${module_name}"
VERBATIM
)
Add a custom target, its always out of date, but if you want it to be called automatically add ALL otherwise you have to explicityly call make module_build, I guess this is what you want.
ADD_CUSTOM_TARGET("${module_name}_build" ALL
DEPENDS ${depends_module_ksyms}
${CMAKE_CURRENT_BINARY_DIR}/${module_name}.built
COMMENT "Building Kernel Module ${module_name}"
)
I'm trying to include an external library in a build environment that uses CMake. I'm not trying to install it on the local system (in fact I'd rather not do that, I don't want /usr/local clogged up with all kinds of libraries); I'd just like to have the resulting libxml2.a available for linking with my executable. I can build it fine with the following in CMakeLists.txt:
set (LIBXML_PATH ${MY_SOURCE_DIR}/libxml2-2.9.1)
add_custom_target (build_libxml ALL
COMMENT "Building libxml"
COMMAND ./configure --prefix=/tmp
COMMAND make
WORKING_DIRECTORY ${LIBXML_PATH}
)
But I'm still having trouble with the following:
1) Is this the right approach in the first place, for the general purpose of getting libraries built with configure and make into a CMake environment?
2) How do I get the resulting library (i.e. libxml2.a) under my build output directory?
3) How can I link to that library for my executable builds?
I tried a fiddly solution with
ADD_LIBRARY( xml2 STATIC libxml2.a )
but it seems like there must be a better way than hauling a whole library's contents into… a library.
Thanks.
You need to make it clearer to CMake what is going on here. All it can see now is that you have some custom command that it will run every time. Instead of using add_custom_target with COMMAND, I've found it better to use add_custom_command.
Something like this:
set (LIBXML_PATH ${MY_SOURCE_DIR}/libxml2-2.9.1)
add_custom_command(
OUTPUT libxml2.a
COMMENT "Building libxml"
COMMAND ./configure --prefix=/tmp
COMMAND make
WORKING_DIRECTORY ${LIBXML_PATH}
)
target_link_libraries(your-program libxml2.a)
By doing it this way, CMake can understand that your custom command's essential product is libxml2.a, and when CMake sees something depending on that, it will run the command (if the library doesn't exist already).
I use cmake-gui to configure OpenCV, and I want to use same configure on some other computer.
Cause I use ssh without X forwarding, so I can't use cmake-gui to configure again.
I don't kown how to use cmake to complete my configure, so I wonder that cmake-gui can generate the command use for cmake?
Is there anyway to do this?
There is an option called: Tools-> Show my Changes which displays exactly what you have configured relating to the original configuration. One version are the copy&paste command line parameters and the other version is nicely human readable.
By default you cannot do what you want because that path is stored in CMAKE_COMMAND which is an INTERNAL variable so it is not visible in the GUI. You can manually read it from the cache using a command like grep CMAKE_COMMAND CMakeCache.txt | cut -d = -f 2. Alternatively you can update your CMakeLists.txt to put the value of CMAKE_COMMAND in the cache so that you can read it using the GUI. For example:
set(USED_CMAKE_PATH ${CMAKE_COMMAND} CACHE FILEPATH
"The path to the CMake executable used to configure this project" FORCE)
Additionally if you are using the "Unix Makefiles" generator there are two targets provided for this:
rebuild_cace which is equivalent to cmake .
edit_cache which is equivalent to ccmake . or cmake-gui . depending upon your install.
Note: I used CMake version 2.8.10.2 to test this, but I expect it to work with any version.
In CMake I currently have a simple Python script to generate a header, but if I update the script itself CMake won't re-run the script. Is there a way I can get CMake to do this?
It seems you are directly invoking your code generation script when cmake is run. While it is possible solution but it is definitely not a right way to use code generators with cmake.
I recommend you to use add_custom_command for your case:
add_custom_command(
OUTPUT generated.h
COMMAND ${PYTHON_EXECUTABLE} generator.py
DEPENDS generator.py
)
And next you can simple put your header to the list of source files passed to add_library/add_executable commands. cmake will automatically track all the dependencies and invoke your script.
Term DEPENDS generator.py informs cmake that it should regenerate header if script is changed.
With this approach file generated.h will be generated only at build time (when you run make or execute a build command in IDE). In contrast if you are running your script at cmake time (with execute_process command) then you have to rerun cmake to regenerate your file. Which is possible but you need to use some tricks to introduce a non-standard dependency.