我的项目中有很多库,还有很多个人应用程序。我的一些库有依赖库,其中一些是外部库,我想让应用程序CMakeList.txt文件更简单。我希望使用宏来简化。
以下是一个大大减少的测试用例。例如,在我的项目中,包括我的一个库也需要include_directories,link_directories和target_link_libraries for ImageMagick,pugixml,jsoncpp,liboauthcpp等...而且,这些第三方库中的一些需要编译器标志。我的项目版本的_LIB()宏将会更长......
问题:有没有办法让下面的_LIB()宏自动向调用宏的target_link_libraries添加内容?
我不知道该怎么做,因为target_link_libraries参数1是目标名称,每个应用程序都会更改。
〜/ codeTest /的CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(codeTest)
macro(_LIB)
include_directories(~/codeTest/lib)
link_directories(~/codeTest/lib)
endmacro()
add_subdirectory(lib)
add_subdirectory(app)
〜/ codeTest / LIB /的CMakeLists.txt
include_directories(~/codeTest/lib)
add_library(lib lib.cpp)
〜/ codeTest / LIB / lib.h
#ifndef __LIB__
#define __LIB__
namespace LIB {
unsigned long libFunc(unsigned long inValue);
}
#endif
〜/ codeTest / LIB / lib.cpp
#include <lib.h>
namespace LIB {
unsigned long libFunc(unsigned long inValue) {
return inValue+1;
}
}
〜/ codeTest /应用程序/的CMakeLists.txt
_LIB()
add_executable(app app.cpp)
target_link_libraries(app lib)
〜/ codeTest /应用程序/ app.cpp
#include <lib.h>
using namespace LIB;
int main() {
unsigned long x = 1;
unsigned long y = libFunc(x);
}
答案 0 :(得分:1)
随着项目复杂性的增长,您很快就会发现,在宏中收集的多个{link,include}_directories
指令是不灵活的解决方案,应该明确指定它们。
我建议您考虑模块的概念(/usr/share/cmake/Modules/
):对于每个外部依赖项,使用可以在cmake modules目录中找到的Find*.cmake
文件(参见上文)或包装的一个(如果其作者编写了相应的模块)。或者你可以自己写。
这些模块通常会定义一些变量(例如Boost_INCLUDE_DIRS
,Boost_LIBRARY_DIRS
),您只会在那些真正需要的子项目中使用这些变量。
因此,对于每个子项目,您指定include_...
/ link_...
指令显式引用模块或其他子项目中定义的变量(对于内部依赖项)。
此外,cmake中的宏和函数对于用户来说实际上是非常不可预测的,期望它们在众所周知的编程语言(C
,Java
,Ruby
中表现得像传统函数, ...)当你开始向他们添加参数时;阅读有关字符串和列表之间的变量缓存,作用域和转换的信息。
答案 1 :(得分:1)
考虑将使用要求编码到目标本身而不是使用宏。
这将是&#39;现代cmake&#39;:
http://www.cmake.org/cmake/help/git-next/manual/cmake-buildsystem.7.html
http://www.kdab.com/modern-cmake-with-qt-and-boost/
http://www.steveire.com/WhatWhyHowCMake.pdf
http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html
答案 2 :(得分:0)
如果您可以通过这种方式将一些依赖项分组为1个目标,我建议您创建一个INTERFACE
库。
例如,
add_library(ImageMagick ...)
#...etc gather all library targets however is conviennt
add_library(CoreDependencies INTERFACE)
target_link_libraries(CoreDependencies PUBLIC ImageMagick ...)
然后在您的应用中,您可以
target_link_libraries(MyApp PRIVATE CoreDependencies)
这会带来你需要的一切。如果你真的有这么多不同的用例,你可以创建几个库的子集。
值得注意的是,这种方法需要CMake 3。 https://cmake.org/cmake/help/v3.0/manual/cmake-buildsystem.7.html#interface-libraries