如何在编译时在由CMake生成的Makefile中运行命令? [英] How to run a command at compile time within Makefile generated by CMake?

查看:1362
本文介绍了如何在编译时在由CMake生成的Makefile中运行命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过一些选项到编译器。
该选项必须在编译时计算 - 每次调用'make'时,而不是'cmake'时,因此execute_process命令不会剪切它。 (是吗?)



例如将日期传递给g ++编译器:

  g ++ prog.cpp -o prog -DDATETIME =17:09:2009,14:25


b $ b

但是在编译时计算DATETIME。



有什么想法如何在CMake中做?



赏金编辑



接受最少的解决方案。



请注意,我希望能够在编译时执行任意命令,而不仅仅是'date'。



编辑2: / p>

它必须在Linux,Windows(VS),Mingw,Cygwin和OS X上工作。
你不能假设Ruby,Perl或Python非标准。
您可以假设BOOST,但我想它没有用。



目标是强制cmake生成Makefile(在Linux的情况下)执行,将做这项工作。



创建自定义* .h文件是确定的,但它必须由Makefile(或其他操作系统上的等效文件)通过make启动。 * .h的创建不必(不应该)使用cmake。

解决方案

省略了一些信息,例如哪些平台需要
来运行此操作,如果有任何其他工具可以使用。如果
你可以使用Ruby,Perl,Python,事情变得更简单。我会
假设你想运行在Unix和Windows pqlatform和
,没有额外的工具可用。



如果你想在预处理器符号中的命令的输出,
最简单的方法是生成头文件,而不是用命令行参数约束
。记住,CMake有一个脚本模式
(-P),它只处理文件中的脚本命令,所以你可以
做这样的:



CMakeLists.txt:

  project(foo)
cmake_minimum_required(VERSION 2.6)
add_executable foo main.c custom.h)
include_directories($ {CMAKE_CURRENT_BINARY_DIR})
add_custom_command(OUTPUT custom.h
COMMAND $ {CMAKE_COMMAND} -P $ {CMAKE_CURRENT_SOURCE_DIR} /custom.cmake)

文件custom.h在编译时由命令cmake
- P custom.cmake。 custom.cmake看起来像这样:

  execute_process(COMMAND uname -a 
OUTPUT_VARIABLE _output OUTPUT_STRIP_TRAILING_WHITESPACE)
文件(WRITE custom.h#define COMPILE_TIME_VALUE \$ {_ output} \)

它执行命令(在这种情况下为uname -a,您将用您想要的任何命令替换
),并将输出放在变量
_output中,然后将其写入自定义。 H。注意,这将只有
工作,如果命令输出一行。 (如果你需要多行
输出,你必须编写一个更复杂的custom.cmake,这取决于
如何将多行数据加入你的程序。)



主程序如下所示:

  #include< stdio.h> 
#includecustom.h
int main()
{
printf(COMPILE_TIME_VALUE:%s\\\
,COMPILE_TIME_VALUE);
return 0;
}



如果你真的想在编译时计算编译器选项,
事情变得更加棘手。对于Bourne-shell生成器,您只需
将命令插入反引号。如果你在找出
引用时感到疯狂,请在shell脚本中移动你的命令的所有逻辑,所以
你只需要把 mycommand.sh

  if(UNIX)
add_definitions(`$ {CMAKE_CURRENT_SOURCE_DIR} / custom-options .sh')
endif()

对于基于Windows批处理文件的生成器,和I
没有好的解决方案。问题是 PRE_BUILD 命令
不作为与实际编译器
调用相同的批处理文件的一部分执行(研究BuildLog.htm细节),所以我的初始想法
没有工作(生成一个custom.bat在 PRE_BUILD 步骤然后做
调用custom.bat在它上面得到一个变量集,后来可以在编译器命令行中引用
)。如果在批处理文件中有等价的
反引号,那么这将解决问题。



希望这提供了一些想法和起点。



(现在的不可避免的反问:你真的
试图做什么?)



编辑:我不知道你为什么不想让CMake生成头文件。使用$ {CMAKE_COMMAND}将扩展到CMake用于生成Makefiles / .vcproj文件,并且由于CMake不真正支持便携式Makefile / .vcproj文件,您将需要在目标计算机上重新运行CMake。



CMake还有一些实用命令(对于列表,运行cmake -E)。你可以例如做

  add_custom_command(OUTPUT custom.h COMMAND $ {CMAKE_COMMAND} -E copy file1.h file2.h) 

将file1.h复制到file2.h。



无论如何,如果你不想使用CMake生成头文件,你需要调用单独的.bat / .sh脚本来生成头文件,或者使用echo:

  add_custom_command(OUTPUT custom.h COMMAND echo #define SOMETHING 1> custom.h)
/ pre>

根据需要调整引用。


I would like to pass some options to a compiler. The option would have to be calculated at compile time - everytime when 'make' is invoked, not when 'cmake', so execute_process command does not cut it. (does it?)

For instance passing a date to a g++ compiler like that:

g++ prog.cpp -o prog -DDATETIME="17:09:2009,14:25"

But with DATETIME calculated at compile time.

Any idea how to do it in CMake?

Bounty edit:

A least hackish solution will be accepted.

Please note that I want to be able to exectue an arbitrary command at compile time, not only 'date'.

Edit 2:

It have to work on Linux, Windows (VS), Mingw, Cygwin and OS X. You can't assume Ruby, Perl or Python as they are non standard on Windows. You can assume BOOST, but I guess it's no use.

The goal is to force cmake to generate Makefile (in case of Linux) that when make is executed, will do the job.

Creating custom *.h file is ok, but it has to be initiated by a Makefile (or equivalent on other OS) by make. The creation of *.h doesn't have to (and shouldn't have to) use cmake.

解决方案

You're leaving out some information, such as which platforms you need to run this on and if there are any additional tools you can use. If you can use Ruby, Perl, of Python, things become much simpler. I'll assume that you want to run on both Unix and Windows pqlatform and that there are no extra tools available.

If you want the output from the command in a preprocessor symbol, the easiest way is to generate a header file instead of fiddling around with command line parameters. Remember that CMake has a script-mode (-P) where it only processes script commands in the file, so you can do something like this:

CMakeLists.txt:

project(foo)  
cmake_minimum_required(VERSION 2.6)
add_executable(foo main.c custom.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})  
add_custom_command(OUTPUT custom.h 
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/custom.cmake)

The file "custom.h" is generated at compile time by the command "cmake -P custom.cmake". custom.cmake looks like this:

execute_process(COMMAND uname -a 
    OUTPUT_VARIABLE _output OUTPUT_STRIP_TRAILING_WHITESPACE)
file(WRITE custom.h "#define COMPILE_TIME_VALUE \"${_output}\"")

It executes the command (in this case "uname -a", you'll replace it with whatever command you wish), and puts the output in the variable _output, which it then writes to custom.h. Note that this will only work if the command outputs a single line. (If you need multiline output, you'll have to write a more complex custom.cmake, depending on how you want the multiline data into your program.)

The main program looks like this:

#include <stdio.h>
#include "custom.h"
int main()
{
  printf("COMPILE_TIME_VALUE: %s\n", COMPILE_TIME_VALUE);
  return 0;
}

If you actually want to to calculate compiler options at compile time, things become much trickier. For Bourne-shell generators you can just insert the command inside backticks. If you get mad while figuring out quoting, move all the logic of your command inside a shell-script so you only need to put mycommand.sh in your add_definitions():

if(UNIX)
  add_definitions(`${CMAKE_CURRENT_SOURCE_DIR}/custom-options.sh`)
endif()

For Windows batch file based generators things are much tricker, and I don't have a good solution. The problem is that the PRE_BUILD commands are not executed as part of the same batch file as the actual compiler invocation (study the BuildLog.htm for details), so my initial idea did not work (generating a custom.bat in a PRE_BUILD step and then do "call custom.bat" on it to get a variable set which can later be referenced in the compiler command line). If there is an equivalent of backticks in batch files, that would solve the problem.

Hope this gives some ideas and starting points.

(Now to the inevitable counter-question: what are you really trying to do?)

EDIT: I'm not sure why you don't want to let CMake be used to generate the header-file. Using ${CMAKE_COMMAND} will expand to the CMake used to generate the Makefiles/.vcproj-files, and since CMake doesn't really support portable Makefiles/.vcproj-files you will need to rerun CMake on the target machines.

CMake also has a bunch of utility commands (Run "cmake -E" for a list) for this explicit reason. You can for example do

add_custom_command(OUTPUT custom.h COMMAND ${CMAKE_COMMAND} -E copy file1.h file2.h)

to copy file1.h to file2.h.

Anyway, if you don't want to generate the header-files using CMake, you will either need to invoke separate .bat/.sh scripts to generate the header file, or do it using echo:

add_custom_command(OUTPUT custom.h COMMAND echo #define SOMETHING 1 > custom.h)

Adjust quoting as needed.

这篇关于如何在编译时在由CMake生成的Makefile中运行命令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆