在 CMake 中将静态库与测试应用程序一起使用时出现链接器错误
Linker error when using static library with test applications in CMake
我的静态库的项目结构和this question中定义的一模一样,我的CMakeList.txt完全一样:
cmake_minimum_required (VERSION 2.8)
project (project_name)
add_subdirectory (src)
add_subdirectory (test)
我想在我的静态库之后建立测试文件夹。我还添加了 add_test()
但只有 问题 是我的测试目录不包含单元测试,但实际测试应用程序如下代码:
#include <iostream>
main() {
/*
this code uses static library functions in it. There is not Unit Test defined in it.
*/
}
add_test()
没有帮助我,我仍然收到 cannot find -ldal
错误。 dal
是我的静态库名称,我已将其作为 target_link_library
添加到我的测试应用程序中。
libdal/src/CMakeList.txt
cmake_minimum_required(VERSION 3.12)
project(dal)
# Flags Variables
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
# Include Directeries
include_directories(${CPP_KAFKA_INC})
include_directories(${CPP_MYSQL_INC})
include_directories(${CPP_ALTIBASE_INC})
include_directories(${AFN_STATE_INC})
include_directories(${AFN_DAL_INC})
include_directories(${AFN_COMMONS_INC})
include_directories(${AFN_CONFIG_INC})
include_directories(${SQL_ODBC_INC})
# Executable Target(s)
file(GLOB SOURCES *.cpp)
add_library(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME}
${AFN_LIB}
"-lafinit_state"
"-luuid"
"-lz"
"-lpthread"
${PQXX_LIB}
${PQ_LIB}
"-lmysqlcppconn"
${libmscpp}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
)
# Installation
install(CODE "MESSAGE(\"Installing ${PROJECT_NAME} \")")
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
libdal/test/CMakeList.txt
cmake_minimum_required(VERSION 3.12)
project(testdal)
# Flags Variables
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" )
option(DAL_PUSH_TESTER "enable DAL push tester" ON)
# Include Directeries
include_directories(${CPP_KAFKA_INC})
include_directories(${AFN_DAL_INC})
include_directories(${CPP_MYSQL_INC})
include_directories(${AFN_STATE_INC})
include_directories(${AFN_CONFIG_INC})
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
${AFN_LIB}
"-lmysqlcppconn"
"-luuid"
"-lz"
${libmscpp}
"-ldal"
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
"-lafinit_state"
"-luuid"
"-lpthread"
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
${AFN_LICENSE_LIB} "-laf_license_manager"
)
# Installation
install(CODE "MESSAGE(\"Installing ${PROJECT_NAME} \")")
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin/tests
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
if (DAL_PUSH_TESTER)
add_executable(dal_push_tester dal_push_tester.cpp)
target_link_libraries(dal_push_tester
${AFN_LIB}
"-lmysqlcppconn"
"-luuid"
"-lz"
${libmscpp}
"-ldal"
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
"-lafinit_state"
"-luuid"
"-lpthread"
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
${AFN_LICENSE_LIB} "-laf_license_manager"
)
# Installation
install(CODE "MESSAGE(\"Installing dal_push_tester \")")
install(TARGETS dal_push_tester
RUNTIME DESTINATION bin/tests
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
endif ()
该问题已在网站上多次提出,但您的 CMake 文件还有一些其他问题需要解释。
问题是 linker 不知道在哪里可以找到 dal
库,因为你只提供了 "-ldal"
,没有库的完整路径或任何东西。您可以通过在 target_link_libraries()
中简单地使用 CMake 库 target 名称 (dal
) 来解决这个问题,因为它是在同一个 CMake 调用中定义的。
target_link_libraries(${PROJECT_NAME}
${AFN_LIB}
"-lmysqlcppconn"
"-luuid"
"-lz"
${libmscpp}
dal # <------ Note the change on this line.
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
"-lafinit_state"
"-luuid"
"-lpthread"
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
${AFN_LICENSE_LIB} "-laf_license_manager"
)
此外,target_link_libraries
不需要添加明确的 -l
link 标志;它会自动添加这个。此外,您应该 始终 为这个和其他 target_*
调用指定范围参数(例如 PRIVATE
、PUBLIC
等)。另外,还有,你 linked uuid
两次 ,所以你可能可以删除其中之一:
target_link_libraries(${PROJECT_NAME} PRIVATE
${AFN_LIB}
mysqlcppconn
uuid
z
${libmscpp}
dal
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
afinit_state
pthread
afiniti_config $<$<CONFIG:DEBUG>:gcov>
${AFN_LICENSE_LIB} af_license_manager
)
另外,手动修改CMAKE_CXX_FLAGS
这一行:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
非常气馁。要设置 C++ 标准,您应该使用:
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
或本文 中讨论的其他更现代的方法之一。
我鼓励您浏览一些关于 modern CMake practices 的内容。
我的静态库的项目结构和this question中定义的一模一样,我的CMakeList.txt完全一样:
cmake_minimum_required (VERSION 2.8)
project (project_name)
add_subdirectory (src)
add_subdirectory (test)
我想在我的静态库之后建立测试文件夹。我还添加了 add_test()
但只有 问题 是我的测试目录不包含单元测试,但实际测试应用程序如下代码:
#include <iostream>
main() {
/*
this code uses static library functions in it. There is not Unit Test defined in it.
*/
}
add_test()
没有帮助我,我仍然收到 cannot find -ldal
错误。 dal
是我的静态库名称,我已将其作为 target_link_library
添加到我的测试应用程序中。
libdal/src/CMakeList.txt
cmake_minimum_required(VERSION 3.12)
project(dal)
# Flags Variables
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
# Include Directeries
include_directories(${CPP_KAFKA_INC})
include_directories(${CPP_MYSQL_INC})
include_directories(${CPP_ALTIBASE_INC})
include_directories(${AFN_STATE_INC})
include_directories(${AFN_DAL_INC})
include_directories(${AFN_COMMONS_INC})
include_directories(${AFN_CONFIG_INC})
include_directories(${SQL_ODBC_INC})
# Executable Target(s)
file(GLOB SOURCES *.cpp)
add_library(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME}
${AFN_LIB}
"-lafinit_state"
"-luuid"
"-lz"
"-lpthread"
${PQXX_LIB}
${PQ_LIB}
"-lmysqlcppconn"
${libmscpp}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
)
# Installation
install(CODE "MESSAGE(\"Installing ${PROJECT_NAME} \")")
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
libdal/test/CMakeList.txt
cmake_minimum_required(VERSION 3.12)
project(testdal)
# Flags Variables
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" )
option(DAL_PUSH_TESTER "enable DAL push tester" ON)
# Include Directeries
include_directories(${CPP_KAFKA_INC})
include_directories(${AFN_DAL_INC})
include_directories(${CPP_MYSQL_INC})
include_directories(${AFN_STATE_INC})
include_directories(${AFN_CONFIG_INC})
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
${AFN_LIB}
"-lmysqlcppconn"
"-luuid"
"-lz"
${libmscpp}
"-ldal"
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
"-lafinit_state"
"-luuid"
"-lpthread"
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
${AFN_LICENSE_LIB} "-laf_license_manager"
)
# Installation
install(CODE "MESSAGE(\"Installing ${PROJECT_NAME} \")")
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin/tests
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
if (DAL_PUSH_TESTER)
add_executable(dal_push_tester dal_push_tester.cpp)
target_link_libraries(dal_push_tester
${AFN_LIB}
"-lmysqlcppconn"
"-luuid"
"-lz"
${libmscpp}
"-ldal"
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
"-lafinit_state"
"-luuid"
"-lpthread"
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
${AFN_LICENSE_LIB} "-laf_license_manager"
)
# Installation
install(CODE "MESSAGE(\"Installing dal_push_tester \")")
install(TARGETS dal_push_tester
RUNTIME DESTINATION bin/tests
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
endif ()
该问题已在网站上多次提出,但您的 CMake 文件还有一些其他问题需要解释。
问题是 linker 不知道在哪里可以找到 dal
库,因为你只提供了 "-ldal"
,没有库的完整路径或任何东西。您可以通过在 target_link_libraries()
中简单地使用 CMake 库 target 名称 (dal
) 来解决这个问题,因为它是在同一个 CMake 调用中定义的。
target_link_libraries(${PROJECT_NAME}
${AFN_LIB}
"-lmysqlcppconn"
"-luuid"
"-lz"
${libmscpp}
dal # <------ Note the change on this line.
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
"-lafinit_state"
"-luuid"
"-lpthread"
afiniti_config $<$<CONFIG:DEBUG>:-lgcov>
${AFN_LICENSE_LIB} "-laf_license_manager"
)
此外,target_link_libraries
不需要添加明确的 -l
link 标志;它会自动添加这个。此外,您应该 始终 为这个和其他 target_*
调用指定范围参数(例如 PRIVATE
、PUBLIC
等)。另外,还有,你 linked uuid
两次 ,所以你可能可以删除其中之一:
target_link_libraries(${PROJECT_NAME} PRIVATE
${AFN_LIB}
mysqlcppconn
uuid
z
${libmscpp}
dal
${PQXX_LIB}
${PQ_LIB}
${kafkacpplib}
${rdkafkalib}
${rdkafkacpplib}
afinit_state
pthread
afiniti_config $<$<CONFIG:DEBUG>:gcov>
${AFN_LICENSE_LIB} af_license_manager
)
另外,手动修改CMAKE_CXX_FLAGS
这一行:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
非常气馁。要设置 C++ 标准,您应该使用:
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
或本文
我鼓励您浏览一些关于 modern CMake practices 的内容。