- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
关闭。这个问题需要更多focused .它目前不接受答案。
想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .
4年前关闭。
Improve this question
众所周知,初学者很难获得有关 CMake 的任何有用信息。到目前为止,我已经看过一些关于如何设置一些非常基本的项目或其他项目的教程。然而,这些都没有解释其中显示的任何内容背后的推理,总是留下许多漏洞需要填补。
在 CMakeLists 上调用 CMake 是什么意思?每个构建树应该调用一次还是什么?如果每个构建都使用来自同一源的相同 CMakeLists.txt 文件,我该如何为每个构建使用不同的设置?
为什么每个子目录都需要自己的 CMakeLists 文件?在 CMakeLists.txt 而非项目根目录的 CMakeLists.txt 上使用 CMake 是否有意义?如果是,在什么情况下?
指定如何从它们自己的子目录中的 CMakeLists 文件构建可执行文件或库与在所有源的根目录下的 CMakeLists 文件中执行有什么区别?
我可以为 Eclipse 制作一个项目,为 Visual Studio 制作另一个项目吗,只需更改 -G
调用 CMake 时的选项?甚至是这样使用的吗?
到目前为止,我所看到的教程、文档页面或问题/答案都没有提供任何有用的见解来理解如何使用 CMake。这些例子并不彻底。无论我阅读什么教程,我都觉得我错过了一些重要的东西。
像我这样的 CMake 新手提出的许多问题并没有明确提出这一点,但显而易见的是,作为新手,我们不知道如何处理 CMake 或如何处理它。
最佳答案
CMake 有什么用?
根据维基百科:
CMake is [...] software for managing the build process of software using a compiler-independent method. It is designed to support directory hierarchies and applications that depend on multiple libraries. It is used in conjunction with native build environments such as make, Apple's Xcode, and Microsoft Visual Studio.
Makefile
s。此后您需要做的就是在每次完成代码编辑后在控制台的根文件夹中键入“make”,然后生成一个编译和链接的可执行文件。
simple/
CMakeLists.txt
src/
tutorial.cxx
CMakeLists.txt
lib/
TestLib.cxx
TestLib.h
CMakeLists.txt
build/
CMakeLists.txt
设置您的项目您的项目,并在您执行的任何目录中执行此操作
cmake
从控制台。从不是项目根目录的文件夹执行此操作会产生所谓的源外构建,这意味着编译期间创建的文件(obj 文件、lib 文件、可执行文件,您知道)将放置在所述文件夹中,与实际代码分开保存。它有助于减少困惑,并且由于其他原因也是首选,我不会讨论。
cmake
会发生什么在除根之外的任何地方
CMakeLists.txt
.
build/
中文件夹,首先我必须导航到那里,然后通过 CMake 根目录
CMakeLists.txt
居住。
cd build
cmake ..
simple/build/
CMakeCache.txt
cmake_install.cmake
Makefile
CMakeFiles/
(...)
src/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
lib/
CMakeFiles/
(...)
cmake_install.cmake
Makefile
src/
和
lib/
文件夹。创建这些是因为
simple/CMakeLists.txt
使用命令
add_subdirectory(<folder>)
指向它们.此命令告诉 CMake 在所述文件夹中查找另一个
CMakeLists.txt
文件并执行该脚本,因此以这种方式添加的每个子目录都必须有一个
CMakeLists.txt
文件内。在这个项目中,
simple/src/CMakeLists.txt
描述了如何构建实际的可执行文件和
simple/lib/CMakeLists.txt
描述如何构建库。每一个目标是一个
CMakeLists.txt
描述将默认放置在构建树中的子目录中。所以,在快速
make
build/
,添加了一些文件:
simple/build/
(...)
lib/
libTestLib.a
(...)
src/
Tutorial
(...)
simple/CMakeLists.txt
:
cmake_minimum_required(VERSION 2.6)
project(Tutorial)
# Add all subdirectories in this project
add_subdirectory(lib)
add_subdirectory(src)
add_subdirectory()
向项目添加一个文件夹,这意味着 CMake 期望它有一个
CMakeLists.txt
内,然后它将在继续之前运行。顺便说一句,如果你碰巧定义了一个 CMake 函数,你可以从其他
CMakeLists.txt
使用它。 s 在子目录中,但您必须在使用
add_subdirectory()
之前定义它否则它不会找到它。不过,CMake 在库方面更聪明,因此这可能是您遇到此类问题的唯一一次。
simple/lib/CMakeLists.txt
:
add_library(TestLib TestLib.cxx)
foo.cxx
,要编译,你应该写
add_library(TestLib TestLib.cxx foo.cxx)
.这也适用于其他目录中的文件,例如
add_library(TestLib TestLib.cxx ${CMAKE_SOURCE_DIR}/foo.cxx)
.稍后将详细介绍 CMAKE_SOURCE_DIR 变量。
add_library(TestLib SHARED TestLib.cxx)
.不要害怕,这是 CMake 开始让您的生活更轻松的地方。无论是否共享,现在使用以这种方式创建的库所需要做的就是在此处为其指定名称。这个库的名称现在是 TestLib,您可以从项目的任何地方引用它。 CMake 会找到它。
simple/lib/TestLib.cxx
:
#include <stdio.h>
void test() {
printf("testing...\n");
}
simple/lib/TestLib.h
:
#ifndef TestLib
#define TestLib
void test();
#endif
simple/src/CMakeLists.txt
:
# Name the executable and all resources it depends on directly
add_executable(Tutorial tutorial.cxx)
# Link to needed libraries
target_link_libraries(Tutorial TestLib)
# Tell CMake where to look for the .h files
target_include_directories(Tutorial PUBLIC ${CMAKE_SOURCE_DIR}/lib)
add_executable()
与
add_library()
的工作原理完全相同,当然,除了它会生成一个可执行文件。这个可执行文件现在可以作为诸如
target_link_libraries()
之类的目标被引用。 .由于 tutorial.cxx 使用在 TestLib 库中找到的代码,因此您将其指出给 CMake,如图所示。
add_executable()
中由任何来源 #included 的任何 .h 文件与源不在同一目录中的必须以某种方式添加。如果不是
target_include_directories()
命令,
lib/TestLib.h
编译Tutorial 时找不到,所以整个
lib/
文件夹被添加到要搜索#includes 的包含目录中。您可能还会看到命令
include_directories()
它以类似的方式运行,不同之处在于它不需要您指定目标,因为它完全为所有可执行文件全局设置了它。稍后我将再次解释 CMAKE_SOURCE_DIR。
simple/src/tutorial.cxx
:
#include <stdio.h>
#include "TestLib.h"
int main (int argc, char *argv[])
{
test();
fprintf(stdout, "Main\n");
return 0;
}
target_include_directories()
,CMake 会在幕后处理所有这些工作。 .
CMakeLists.txt
下
lib/
和
src/
并添加类似
add_executable(Tutorial src/tutorial.cxx)
的内容至
simple/CMakeLists.txt
.这取决于您和您的项目的需求。
CMakeCache.txt
文件)。记得要
c
完成更改后进行配置,然后
g
使用更新的配置生成 makefile。
set(<variable name> value)
更改或创建变量。
${<variable name>}
使用它。
CMAKE_SOURCE_DIR
: 源码的根目录。在前面的例子中,这总是等于 /simple
CMAKE_BINARY_DIR
: 构建的根目录。在前面的例子中,这等于 simple/build/
,但如果你运行 cmake simple/
来自文件夹,例如 foo/bar/etc/
,然后所有对 CMAKE_BINARY_DIR
的引用在那个构建树中将成为 /foo/bar/etc
. CMAKE_CURRENT_SOURCE_DIR
: 当前CMakeLists.txt
所在的目录是在。这意味着它在整个过程中都发生了变化:从 simple/CMakeLists.txt
打印此内容 yield /simple
,并从 simple/src/CMakeLists.txt
打印它 yield /simple/src
. CMAKE_CURRENT_BINARY_DIR
: 你懂的。此路径不仅取决于构建所在的文件夹,还取决于当前 CMakeLists.txt
脚本的位置。 target_include_directories(Tutorial PUBLIC ../lib)
在前面的例子中,那个路径是相对于构建树的,也就是说它就像写
${CMAKE_BINARY_DIR}/lib
,这将查看内部
simple/build/lib/
.那里没有 .h 文件;最多你会找到
libTestLib.a
.你要
${CMAKE_SOURCE_DIR}/lib
相反。
CMAKE_CXX_FLAGS
: 传递给编译器的标志,在本例中是 C++ 编译器。另外值得注意的是CMAKE_CXX_FLAGS_DEBUG
如果 CMAKE_BUILD_TYPE
将被使用设置为调试。还有更多这样的;退房 the CMake wiki . CMAKE_RUNTIME_OUTPUT_DIRECTORY
: 告诉 CMake 在构建时将所有可执行文件放在哪里。这是一个全局设置。例如,您可以将其设置为 bin/
并把所有东西都整齐地放在那里。 EXECUTABLE_OUTPUT_PATH
类似,但已弃用,以防您偶然发现它。 CMAKE_LIBRARY_OUTPUT_DIRECTORY
: 同样,一个全局设置告诉 CMake 把所有库文件放在哪里。 set_target_properties()
。
FILE(GLOB <variable name> <directory>/*.cxx)
.
CMAKE_CXX_FLAGS_DEBUG
的默认值。 ,例如。
CMakeLists.txt
中设置您的构建类型。文件通过
set(CMAKE_BUILD_TYPE <type>)
或者通过使用适当的标志从控制台调用 CMake,例如
cmake -DCMAKE_BUILD_TYPE=Debug
.
simple/CMakeLists.txt
:
project (Tutorial)
# Setting variables
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 1)
# Configure_file(<input> <output>)
# Copies a file <input> to file <output> and substitutes variable values referenced in the file content.
# So you can pass some CMake variables to the source code (in this case version numbers)
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_SOURCE_DIR}/src/TutorialConfig.h"
)
simple/TutorialConfig.h.in
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
simple/src/TutorialConfig.h
:
// Configured options and settings
#define Tutorial_VERSION_MAJOR 1
#define Tutorial_VERSION_MINOR 1
关于cmake - CMake是如何使用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26007566/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!