jpo*_*o38 5 c++ cmake visual-studio-2015
我有一个基于 CMake 3.11.4 和 Python 3.7 的软件环境。
我的库/程序有一个config.txt文件,以我指定的格式描述它们的依赖关系。然后,我有一个 Python 脚本 ( scripts/configure.py),它会动态生成CMakeLists.txt,然后调用 CMake 来生成可由 Visual Studio 2015 构建的解决方案。
我希望 Pythonconfig.txt在用户编辑时自动再次运行。
所以我让我的 Python 脚本在生成的CMakeLists.txt. 以下是名为“myproject”的项目的外观,其中包括两个库“lib1”和“lib2”。
${SDE_ROOT_DIR}/build/myproject/CMakeLists.txt 包含:
# Automatically re-run configure project when an input file changes:
set( PROJECT_DEPENDENCIES )
list( APPEND PROJECT_DEPENDENCIES "${SDE_ROOT_DIR}/lib/lib1/config.txt" )
list( APPEND PROJECT_DEPENDENCIES "${SDE_ROOT_DIR}/lib/lib2/config.txt" )
ADD_CUSTOM_COMMAND( OUTPUT ${SDE_ROOT_DIR}/build/myproject/CMakeLists.txt COMMAND tools/python/Python370/python.exe scripts/configure.py myproject WORKING_DIRECTORY ${SDE_ROOT_DIR} DEPENDS ${PROJECT_DEPENDENCIES} )
Run Code Online (Sandbox Code Playgroud)
这是我所做的:
scripts/configure.py myproject) 来CMakeLists.txt生成 Visual Studio 解决方案。Generating CMakeLists.txt并且我看到我的脚本scripts/configure.py被调用。这不是预期的!config.txt,下次构建时我会看到Generating CMakeLists.txt并看到我的脚本scripts/configure.py被调用。那挺好的。除了第一次编译项目时我的脚本运行之外,这几乎是我的预期。由于CMakeLists.txt刚刚生成并且绝对比 更新config.txt,我不明白为什么它需要CMakeLists.txt再次生成。
知道我可能做错了什么吗?是否有任何额外的命令我应该添加到CMakeLists.txt使这个自定义命令的输出默认为“最新”?
这是一个 MCVE(config.txt被替换为prgname.txt):
prg/main.cpp:
#include <iostream>
int main( int argc, char* argv[] )
{
std::cout << "Hello World!" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
prg/prgname.txt:
myprogram
Run Code Online (Sandbox Code Playgroud)
scripts/configure.py:
import sys
import subprocess
import argparse
import os
from contextlib import contextmanager
@contextmanager
def pushd(newDir):
previousDir = os.getcwd()
os.chdir(newDir)
yield
os.chdir(previousDir)
def configure_project():
# check configuration args
parser = argparse.ArgumentParser(description="CMakeLists generator.")
parser.add_argument('project', metavar='project', type=str, help='project name')
args = parser.parse_args()
working_directory = os.getcwd()
project = args.project
buildfolder = os.path.normpath(os.path.join( os.path.dirname(os.path.abspath(__file__)), os.pardir, "build", project ))
if not os.path.isdir(buildfolder):
os.makedirs(buildfolder)
prgsourcefolder = os.path.normpath(os.path.join( os.path.dirname(os.path.abspath(__file__)), os.pardir, "prg" ))
prgbuildfolder = os.path.join( buildfolder, "prg" )
if not os.path.isdir(prgbuildfolder):
os.makedirs(prgbuildfolder)
prgnamepath = os.path.join( prgsourcefolder, "prgname.txt" )
with open( prgnamepath, "r" ) as prgnamefile:
prgname = prgnamefile.read()
with open( os.path.join( prgbuildfolder, "CMakeLists.txt" ), "w" ) as cmakelists:
cmakelists.write( "add_executable(" + prgname + " " + os.path.join(prgsourcefolder,"main.cpp").replace("\\","/") + ")\n" )
cmakelistspath = os.path.join( buildfolder, "CMakeLists.txt" )
with open( cmakelistspath, "w" ) as maincmakelists:
maincmakelists.write( "cmake_minimum_required(VERSION 3.11)\n" )
maincmakelists.write( "project(" + project + ")\n" )
maincmakelists.write( "add_subdirectory(prg)\n" )
maincmakelists.write( "add_custom_command( OUTPUT " + cmakelistspath.replace("\\","/") + " COMMAND python " + " ".join( [ x.replace("\\","/") for x in sys.argv] ) + " WORKING_DIRECTORY " + working_directory.replace("\\","/") + " DEPENDS " + prgnamepath.replace("\\","/") + ")\n" )
# Run CMake:
with pushd( buildfolder ):
cmd = ['cmake.exe', '-G', 'Visual Studio 14 2015 Win64', buildfolder]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
out = proc.stdout.read(1)
if proc.poll() != None:
break
sys.stdout.write(out.decode())
sys.stdout.flush()
proc.wait()
if __name__ == "__main__":
import sys
sys.exit( configure_project() )
Run Code Online (Sandbox Code Playgroud)
PATHpython configure.py myprojectbuild/myproject/myproject.slnGenerating CMakeLists.txt在日志中看到意外消息add_custom_command创建一个没有目标依赖的命令。因此,它不会被执行。我不知道为什么 Visual Studio 第一次运行它,但在 Linux 上 Python 脚本永远不会运行。
为了使其正常工作,您还需要一个目标。在这种情况下,您可以使用add_custom_target选项ALL并将自定义命令的输出指定为其依赖项。这样,自定义目标将在需要时运行该命令。
只需添加一行,例如
maincmakelists.write( "add_custom_target( Configure ALL DEPENDS " + cmakelistspath.replace("\\","/") + " )\n" )
Run Code Online (Sandbox Code Playgroud)
在你写的地方之后add_custom_command,它应该可以工作。它对我有用。
请注意,自定义目标将始终运行,但自定义命令仅在修改prgname.txt文件时才会运行。
| 归档时间: |
|
| 查看次数: |
1323 次 |
| 最近记录: |