我最近从 Autotools 切换到 CMake,因为 CMake 似乎更适合跨平台开发,我注意到当我构建我的 C++ 代码的静态库时,里面的所有文件都有一个后缀 .cpp.o
ar -t PA8/libgenericTZR.a
genericTZR.cpp.o
Run Code Online (Sandbox Code Playgroud)
我看过其他工具构建的其他库,但他们没有这样做。我不确定这是否真的是一件坏事,但是,如何在没有 .cpp 添加文件扩展名的情况下让 CMake 构建静态库?
这是我的 CMake 文件
add_executable(PA8 ISP_Charges.cpp genericTZR.cpp genericTZR.h)
set(LIBSRC genericTZR.c genericTZR.h)
add_library(genericTZR SHARED ${LIBSRC})
add_library(genericTZR SHARED $<TARGET_OBJECTS:myObjects>)
add_library(genericTZR-static STATIC ${LIBSRC})
set_target_properties(genericTZR-static PROPERTIES OUTPUT_NAME $
install (TARGETS PA8 DESTINATION bin)
install (TARGETS genericTZR genericTZR-static DESTINATION lib)
install (FILES "${PROJECT_BINARY_DIR}/PA8/genericTZR.h" DESTINA$
Run Code Online (Sandbox Code Playgroud)
谢谢
我正在尝试编译一个我最近开始工作的项目,并被要求在 clang 而不是 gcc 中编译代码。该项目有一个 CMake 文件,我尝试使用
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ../src
Run Code Online (Sandbox Code Playgroud)
但是抛出了一个错误,我认为这是因为 clang 没有 Fortran 编译器,并且项目的一部分有 Fortran 代码。有没有办法让它在编译 Fortran 代码时使用 gfortran(以前在使用 gcc 时使用),其余部分使用 clang/clang++?
我认为相关的 cmake 文件部分是:
enable_language(Fortran)
string(REGEX MATCH gfortran HAVE_GFORTRAN ${CMAKE_Fortran_COMPILER})
string(REGEX MATCH xlf HAVE_XLF ${CMAKE_Fortran_COMPILER})
string(REGEX MATCH pg77 HAVE_PG77 ${CMAKE_Fortran_COMPILER})
string(REGEX MATCH g77 HAVE_G77 ${CMAKE_Fortran_COMPILER})
string(REGEX MATCH ifort HAVE_ifORT ${CMAKE_Fortran_COMPILER})
string(REGEX MATCH f77 HAVE_F77 ${CMAKE_Fortran_COMPILER})
if(HAVE_GFORTRAN)
set(F_LIBRARY gfortran CACHE string "fortran library")
find_library(F_LIBRARY NAMES gfortran)
set(FORTRAN_UNDERSCORE end CACHE string "What type of fortran underscore style - linux,end,none") …Run Code Online (Sandbox Code Playgroud) 我正在用 cmake 构建一个项目。项目使用外部库plplot;我已将 cmake 配置为库和标头,并将其缓存在 variables 中${PLPLOT_LIBRARY}, ${PLPLOT_LIB_PATH} and ${PLPLOT_INCLUDE_PATH}。在 plplot 库中,一个函数已更改名称:plwid -> plwidth我想检测它。我写了一个小try_compile()测试:
try_compile(HAVE_PLWID ${CMAKE_BINARY_DIR} cmake/tests/test_plwid.c)
Run Code Online (Sandbox Code Playgroud)
但是这个测试总是会失败,因为我必须将头和库信息传递给try_compile进程。gcc像这样手动调用:
gcc -I${PLPLOT_INCLUDE_PATH} cmake/tests/test_plwid.c -L${PLPLOT_LIB_PATH} -l${PLPLOT_LIBRARY}
Run Code Online (Sandbox Code Playgroud)
作品。但是我不明白如何将必要的标志传递给try_compile命令:我试过:
try_compile(HAVE_PLWID ${CMAKE_BINARY_DIR} cmake/tests/test_plwid.c
INCLUDE_DIRECTORIES ${PLPLOT_INCLUDE_PATH}
LINK_DIRECTORIES ${PLPLOT_LIB_PATH}
LINK_LIBRARIES ${PLPLOT_LIBRARY})
Run Code Online (Sandbox Code Playgroud)
然后我得到了 cmake 配置错误:
Attempt at a recursive or nested TRY_COMPILE in directory
/path/to/build
Run Code Online (Sandbox Code Playgroud)
我非常有信心这些${PLPLOT_XXX}变量是正确的,至少基于这些变量,构建的其余部分可以正常工作。
更新:如果我cmake使用--debug_trycompile命令调用并转到build/CMakeFiles/CMakeTmp目录并cmake手动调用:
cmake . -DINCLUDE_DIRECTORIES=/path/plplot/include -DLINK_DIRECTORIES=/path/to/plplot/lib -DLINK_LIBRARIES=plplotd
Run Code Online (Sandbox Code Playgroud)
测试程序将正确构建和链接;所以似乎挑战是将这些选项正确传递给try_compile() cmake命令调用?
我现在正在使用 cmake 在多个平台上编译和构建 C++ 项目。每次调用 cmake 脚本时,构建文件夹中的所有内容都会被删除。比如我用下面的shell命令来说明cmake的调用方式:
rm -rf build_folder
mkdir build_folder
cd build_folder
cmake ..
Run Code Online (Sandbox Code Playgroud)
通过这样做,我们确保项目生成的库或二进制文件在源代码方面得到了更新。但是,每次camke都会调用编译器从头开始构建项目,这可能需要时间。原因在于我们担心如果我们不删除构建文件夹中的所有内容,cmake 可能会保留之前构建的一些中间结果。所以我的问题是:我们的担忧是否合理,如果只调用cmake ..之前的构建文件夹而不删除文件夹中的任何内容,我们会有什么样的危险?
我对 C++ 和 CMake 非常陌生。
在我的项目中,我使用jsoncpp库,我的 IDE(CLion) 看到它没有任何问题。但是,当我尝试编译它时,我收到此错误消息:
ld: library not found for -ljsoncpp
这是我的项目结构:
/
|-jsoncpp/ /*Here contains source code, not compiled library*/
|
|-work_7/
| |-main.cpp
|
|-CMakeList.txt
Run Code Online (Sandbox Code Playgroud)
这是CMakeList.txt配置:
cmake_minimum_required(VERSION 2.8.4)
project(programming_practice)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES work_7/main.cpp)
add_executable(programming_practice ${SOURCE_FILES})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp/include)
add_subdirectory(jsoncpp)
target_link_libraries(programming_practice jsoncpp)
Run Code Online (Sandbox Code Playgroud)
那我做错了什么?请帮我。
我的 CMake 项目中的大多数消息都是彩色的。在 Windows 中,颜色仅显示用户是否已ansicon.exe下载,否则打印一个奇怪的字符。因此,我想ansicon在尝试为消息着色之前检查该命令是否存在。
我试图这样做,希望WIN_COLOR能告诉我命令是否存在:
execute_process(
COMMAND "ansicon"
RESULT_VARIABLE WIN_COLOR
)
Run Code Online (Sandbox Code Playgroud)
它确实如此,但它实际上运行 ansicon.exe,它运行命令提示符的新实例,有效地停止配置过程。
有没有更好的办法?我必须最终查看目录吗?
我使用 CMake 来配置、构建和安装 C++ 代码。我已经定义了一些用户选项。我添加了一个选项,让 CMake 下载外部依赖项。等等等等。
目前,有关 CMake 的所有内容都写在单个文件 CMakeLists.txt 中。还有一个配置文件“config.cmake”,它允许用户定义各种参数,例如详细级别、库路径、编译器标志等。
什么是 CMake 的良好文件组织?CMakeLists.txt 文件是否应该分成子文件?
非常感谢您的帮助!
我想要一个具有两个配置构建和测试的 cmake 项目。
BUILD 将不在 test 子目录中的所有源代码编译到共享库中。TEST 将所有源代码(包括 test 子目录(包括 main.cpp)中的源代码)编译为运行测试的可执行文件。我不希望 TEST 构建共享库。我不希望 BUILD 构建测试可执行文件。
我目前在磁盘上有它:
project/
test/
test_foo.cpp
main.cpp
bar.hpp
widget.hpp
bar.cpp
widget.cpp
...
Run Code Online (Sandbox Code Playgroud)
如果它更容易,我可以移动东西。我在 CMakeLists.txt 文件中放了什么?
到目前为止,这是我启动 Cmake 构建的命令行:
cmake .. --build .. -DCMAKE_BUILD_TYPE:STRING=release
Run Code Online (Sandbox Code Playgroud)
这很好并且有效,并且它产生了
Project.sln
Run Code Online (Sandbox Code Playgroud)
和
tests/ProjectTests.sln
Run Code Online (Sandbox Code Playgroud)
解决方案文件。
我可以使用 Visual Studio 打开解决方案文件并构建它们并从 Visual Studio 运行测试,但是我从 Continuos 集成服务器运行脚本,因此我还需要启动构建并从命令行运行测试:我怎样才能去做?
我需要
CTest从位于的同一文件夹中调用Tests.exe)直到现在我尝试使用命令构建
msbuild Infectorpp2.sln
Run Code Online (Sandbox Code Playgroud)
但那是失败的(错误日志只是很长才能发布),如果这可以帮助这里是github上的脚本。主要问题是我无法最终生成Tests.exe文件,一旦完成调用 CTest 就很简单了。提前致谢。
我正在遵循另一篇文章中的示例从std::cin中读取密码,您可以在其中抓取标准输入的句柄,获取当前控制台模式,将模式更改为抑制输入的回声。出于某种原因,当我调用 GetStdHandle() 时它返回一个有效的句柄,但是当我调用 GetConsoleMode() 时它失败并返回错误代码 6。我在 cmake 项目中使用它。我应该设置任何调试标志以使其按预期工作吗?其他人遇到过这个吗?
void set_stdin_echo(bool enable) {
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
if (hStdin == INVALID_HANDLE_VALUE) {
std::cout << "invalid handle " << GetLastError() << std::endl;
return;
}
else if (hStdin == NULL) {
std::cout << "no handle associated" << std::endl;
return;
}
DWORD mode = 0;
if (GetConsoleMode(hStdin, &mode) == 0) {
std::cout << "Could not get console mode" << GetLastError() << std::endl;
}
std::cout << mode << std::endl;
if (!enable) …Run Code Online (Sandbox Code Playgroud)