I'm trying to compile a project using CMake, but I'm getting undefined references to class functions that I have created. If I create a Makefile by hand, everything compiles fine. But when I use CMake, I'm getting undefined reference errors.
This is the directory structure:
.
├── build
├── CMakeLists.txt
├── info
│ ├── indexer.pdf
│ └── search.pdf
├── Makefile
├── sample
│ ├── 1
│ │ └── b.txt
│ ├── 2
│ │ └── c.txt
│ ├── 3
│ │ └── d.txt
│ └── a.txt
├── src
│ ├── cpp
│ │ ├── index.cpp
│ │ └── record.cpp
│ ├── h
│ │ ├── index.h
│ │ └── record.h
│ └── main.cpp
├── tests
│ └── a
└── todo.txt
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
# Project Name
PROJECT(indexer CXX)
# Binary dir
# Built in CMake variables:
# CMAKE_SOURCE_DIR: the directory where cmake was executed
# CMAKE_BINARY_DIR: where the output will go
# EXECUTABLE_OUTPUT_PATH: common place to put executables if you don't want it to be CMAKE_BINARY_DIR
# LIBRARY_OUTPUT_PATH: common place to put libraries if you don't want it to be CMAKE_BINARY_DIR
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/build)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
# Add additional compiler flags
# Built-ins:
# - CMAKE_CXX_FLAGS_DEBUG = -g
# - CMAKE_CXX_FLAGS_RELEASE = -O3 -NDEBUG
set(CMAKE_CXX_FLAGS "-std=c++0x -Wall")
include_directories("${PROJECT_SOURCE_DIR}/src/h")
# Aggregate the sources
file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/src/cpp")
add_executable(indexer "${PROJECT_SOURCE_DIR}/src/main.cpp" ${SOURCES})``
Error:
CMakeFiles/indexer.dir/src/main.cpp.o: In function `parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Index*)':
main.cpp:(.text+0x1b5): undefined reference to `Record::Record(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int)'
main.cpp:(.text+0x1ee): undefined reference to `Index::add(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Record)'
CMakeFiles/indexer.dir/src/main.cpp.o: In function `main':
main.cpp:(.text+0x77d): undefined reference to `Index::Index()'
main.cpp:(.text+0x84b): undefined reference to `Index::print()'
collect2: error: ld returned 1 exit status
CMakeFiles/indexer.dir/build.make:94: recipe for target 'indexer' failed
make[2]: *** [indexer] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/indexer.dir/all' failed
make[1]: *** [CMakeFiles/indexer.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
Can someone tell me what I'm doing wrong here?
Your issue is with the line
file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/src/cpp")
This will set the SOURCES variable to a file named cpp in the src directory. I think you meant something like
file(GLOB SOURCES "${PROJECT_SOURCE_DIR}/src/cpp/*.cpp")
This will catch all files that end with the extension .cpp, and put them into the SOURCES variable.
Note: I don't think you will need to pass "${PROJECT_SOURCE_DIR}/src/main.cpp" as an argument to create_executable, since your SOURCES variable should already contain the main.cpp.
Related
Installing nested libraries brings compilation errors.
I try to have a project called CROSP that contains multiple internal libraries, namely : StrainParameterisation, RodProperties, PolynomialRepresentation. These libraries are then linked to one base library : CROSP.
This one is the library that is then installed in my usr/local/...
The problem is that when I try to include the library from one external package, I get some errors saying that the compiler did not found the .so file for the internal libraries.
In the following I detail the topology of my project.
The layout of the project is the following:
.
├── cmake
│ ├── cmake_uninstall.cmake.in
│ ├── Config.cmake.in
│ └── installation_module.cmake
├── CMakeLists.txt
└── src
├── CMakeLists.txt
├── CROSP
│ └── cosserat_rod.cpp
├── include
│ └── CROSP
│ ├── CROSP
│ │ └── cosserat_rod.hpp
│ ├── polynomial_representation
│ │ └── polynomial_representation.hpp
│ ├── rod_properties
│ │ └── rod_properties.hpp
│ └── strain_parameterisation
│ └── strain_parameterisation.hpp
├── polynomial_representation
│ └── polynomial_representation.cpp
├── rod_properties
│ └── rod_properties.cpp
└── strain_parameterisation
└── strain_parameterisation.cpp
The CMakeLists are :
Top level CMakeLists
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(CROSP LANGUAGES CXX VERSION 2.0)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
find_package(Eigen3 3.4 NO_MODULE REQUIRED)
# External utilities to configure the package
include(GNUInstallDirs)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
# Give different names for debug and Release
set(CMAKE_RELEASE_POSTFIX "")
set(CMAKE_DEBUG_POSTFIX "-debug")
add_subdirectory(src)
# Install the library using the default routine
include(cmake/installation_module.cmake)
The installation_module.cmake
# Generates ${PROJECT_NAME}Config.cmake file to use our package in other projects
include(CMakePackageConfigHelpers)
configure_package_config_file(
cmake/Config.cmake.in # input template
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake # output config file
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake # where to put the config file during install
PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR # paths to be used
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
# Generates a config file to ensure that URL's version is checked when importing it
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
# When running make install, config files should be copied as well
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake
)
# Add the possibility tu run 'make uninstall' to remove files added via 'make install'
configure_file(
cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
IMMEDIATE #ONLY
)
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
The Config.cmake.in module :
#PACKAGE_INIT#
set(#PROJECT_NAME#_VERSION #PROJECT_VERSION#)
set_and_check(#PROJECT_NAME#_INCLUDE_DIRS #PACKAGE_INCLUDE_INSTALL_DIR#/#PROJECT_NAME#)
set_and_check(#PROJECT_NAME#_LIBRARY_DIR #PACKAGE_LIB_INSTALL_DIR#)
find_library(#PROJECT_NAME#_LIBRARIES NAMES #PROJECT_NAME# PATHS ${#PROJECT_NAME#_LIBRARY_DIR} NO_DEFAULT_PATH)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(#PROJECT_NAME# DEFAULT_MSG #PROJECT_NAME#_INCLUDE_DIRS #PROJECT_NAME#_LIBRARIES)
Then We have the CMakeLists in src
include_directories(include)
add_library(PolynomialRepresentation SHARED
include/${PROJECT_NAME}/polynomial_representation/polynomial_representation.hpp
polynomial_representation/polynomial_representation.cpp
)
target_link_libraries(PolynomialRepresentation
PRIVATE
Eigen3::Eigen
)
target_compile_options(PolynomialRepresentation
PRIVATE
-Wall
-Wextra
)
add_library(RodProperties SHARED
include/${PROJECT_NAME}/rod_properties/rod_properties.hpp
rod_properties/rod_properties.cpp
)
target_link_libraries(RodProperties
PRIVATE
Eigen3::Eigen
PolynomialRepresentation
)
target_compile_options(RodProperties
PRIVATE
-Wall
-Wextra
)
add_library(StrainParameterisation SHARED
include/${PROJECT_NAME}/strain_parameterisation/strain_parameterisation.hpp
strain_parameterisation/strain_parameterisation.cpp
)
target_link_libraries(StrainParameterisation
PRIVATE
Eigen3::Eigen
PolynomialRepresentation
)
target_compile_options(RodProperties
PRIVATE
-Wall
-Wextra
)
add_library(${PROJECT_NAME} SHARED
include/${PROJECT_NAME}/${PROJECT_NAME}/cosserat_rod.hpp
${PROJECT_NAME}/cosserat_rod.cpp
)
target_link_libraries(${PROJECT_NAME}
PRIVATE
Eigen3::Eigen
PUBLIC
StrainParameterisation
RodProperties
PolynomialRepresentation
)
target_compile_options(RodProperties
PRIVATE
-Werror
-Wall
-Wextra
)
add_executable(main main.cpp)
target_link_libraries(main ${PROJECT_NAME} Eigen3::Eigen)
install(
TARGETS
${PROJECT_NAME}
DESTINATION
${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY include/${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
I can run and install this library.
The following code compiles and runs fine.
#include "CROSP/CROSP/cosserat_rod.hpp"
int main(int argc, char *argv[])
{
::CROSP::polynomial_representation::PolynomialRepresentation poly(5);
::CROSP::rod_properties::MaterialProperties material(200, 100, 10);
::CROSP::CosseratRod rod(poly, material);
::CROSP::CosseratRod rod2(15);
::CROSP::CosseratRod rod3;
return 0;
}
The installation in my usr folder has the following layout
usr
└── local
├── include
│ └── CROSP
│ ├── CROSP
│ │ └── cosserat_rod.hpp
│ ├── polynomial_representation
│ │ └── polynomial_representation.hpp
│ ├── rod_properties
│ │ └── rod_properties.hpp
│ └── strain_parameterisation
│ └── strain_parameterisation.hpp
├── lib
│ ├── libCROSP-debug.so
│ └── libCROSP.so
└── share
└── CROSP
└── cmake
├── CROSPConfig.cmake
└── CROSPConfigVersion.cmake
From another project, I can include the library without problem.
Here there is an example
cmake_minimum_required(VERSION 3.5)
project(test_crosp_library LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(CROSP REQUIRED)
find_package(Eigen3 3.4 NO_MODULE REQUIRED)
add_executable(test_crosp_library main.cpp)
target_link_libraries(test_crosp_library
PUBLIC
CROSP
Eigen3::Eigen
)
And the main.cpp looks like this
#include "CROSP/CROSP/cosserat_rod.hpp"
int main()
{
::CROSP::CosseratRod rod; // errors
return 0;
}
I get the following errors
[ 50%] Linking CXX executable test_crosp_library
/usr/bin/ld: warning: libStrainParameterisation.so, needed by /usr/local/lib/libCROSP.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libRodProperties.so, needed by /usr/local/lib/libCROSP.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `LieAlgebra::SE3Pose::getRotationMatrix() const'
/usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::strain_parameterisation::StrainParameterisation::StrainParameterisation(CROSP::polynomial_representation::PolynomialRepresentation, unsigned int)'
/usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::strain_parameterisation::StrainParameterisation::StrainParameterisation(CROSP::polynomial_representation::PolynomialRepresentation, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, unsigned int)'
/usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::rod_properties::RodProperties::RodProperties(CROSP::polynomial_representation::PolynomialRepresentation)'
/usr/bin/ld: /usr/local/lib/libCROSP.so: undefined reference to `CROSP::strain_parameterisation::StrainParameterisation::updateStacks(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/test_crosp_library.dir/build.make:97: test_crosp_library] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/test_crosp_library.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Can you tell what is wrong ?
Moreover, I would like to know if I can use the INTERFACE functionality in order to install the internal libraries in my usr/local with namespaces.
So the CMakeLists.txt of a package using CROSP will be:
find_package(CROSP REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main
CROSP::MaterialProperties
CROSP::StrainParameterisation
)
I'm trying to create a CmakeLists.txt that uses ImGUI + SDL + SDLRenderer + OpenCv for my current class.
.
├── CMakeLists.txt
├── imgui
│ ├── imconfig.h
│ ├── imgui.cpp
│ ├── imgui_demo.cpp
│ ├── imgui_draw.cpp
│ ├── imgui.h
│ ├── imgui_impl_sdl.cpp
│ ├── imgui_impl_sdl.h
│ ├── imgui_impl_sdlrenderer.cpp
│ ├── imgui_impl_sdlrenderer.h
│ ├── imgui_internal.h
│ ├── imgui_tables.cpp
│ ├── imgui_widgets.cpp
│ ├── imstb_rectpack.h
│ ├── imstb_textedit.h
│ ├── imstb_truetype.h
│ └── LICENSE.txt
├── main.cpp
├── Makefile
└── testImages
└── test001.png
My current CMakeLists.
project(main)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
set(sources
imgui/imconfig.h
imgui/imgui.cpp
imgui/imgui.h
imgui/imgui_demo.cpp
imgui/imgui_draw.cpp
imgui/imgui_internal.h
imgui/imgui_widgets.cpp
imgui/imstb_rectpack.h
imgui/imstb_textedit.h
imgui/imstb_truetype.h
imgui/imgui_impl_sdlrenderer.cpp
imgui/imgui_impl_sdlrenderer.h
imgui/imgui_impl_sdl.cpp
imgui/imgui_impl_sdl.h
)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
find_package( OpenCV REQUIRED )
add_executable( main main.cpp ${sources} )
target_link_libraries( main ${OpenCV_LIBS} ${SDL2_LIBRARIES} )
But i get undefined references for all the ImGUI functions:
[ 12%] Linking CXX executable main
/usr/bin/ld: CMakeFiles/main.dir/imgui/imgui.cpp.o: in function `ImGuiListClipper_SeekCursorAndSetupPrevLine(float, float)':
imgui.cpp:(.text+0x60c6): undefined reference to `ImGui::TableEndRow(ImGuiTable*)'
/usr/bin/ld: CMakeFiles/main.dir/imgui/imgui.cpp.o: in function `ImGuiListClipper::Begin(int, float)':
imgui.cpp:(.text+0x62a3): undefined reference to `ImGui::TableEndRow(ImGuiTable*)'
/usr/bin/ld: CMakeFiles/main.dir/imgui/imgui.cpp.o: in function `ImGuiListClipper_StepInternal(ImGuiListClipper*)':
imgui.cpp:(.text+0x66d3): undefined reference to `ImGui::TableEndRow(ImGuiTable*)'
[...]
Currently i'm only trying to build this in linux, so I can think on the windows/ mac versions later.
What am I doing wrong?
Okay, so as said by drescherjm I missed one file imgui/imgui_tables.cpp. After I add this line to the set on the CMakeLists.txt it worked.
The project structure is as below
├── ast
│ ├── CMakeLists.txt
│ ├── expression
│ │ ├── CMakeLists.txt
│ │ ├── Expression.cpp
│ │ ├── Expression.hpp
│ │ ├── NumericExpression.cpp
│ │ └── NumericExpression.h
│ ├── Visitor.cpp
│ └── Visitor.hpp
├── callSlang
│ ├── CMakeLists.txt
│ └── main.cpp
├── CMakeLists.txt
├── contexts
│ ├── CMakeLists.txt
│ ├── Context.hpp
│ ├── Symbol.cpp
│ ├── Symbol.hpp
│ └── SymbolTable.hpp
├── frontend
│ ├── CMakeLists.txt
│ ├── Parser.cpp
│ └── Parser.hpp
├── Makefile
├── meta
│ ├── CMakeLists.txt
│ └── Meta.hpp
└── README.md
CMakeLists.txt
cmake_minimum_required(VERSION 3.16.3)
# set the project name
# https://stackoverflow.com/questions/71740678/cmake-error-in-findterminfo-with-clang-15-on-macos
project(slangLLvm VERSION 1.0 LANGUAGES C CXX)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_BUILD_TYPE "Debug")
set(LLVM_DIR /usr/lib/llvm-14/lib/cmake/llvm)
find_package(LLVM REQUIRED CONFIG
PATHS ${search_paths}
NO_DEFAULT_PATH)
add_subdirectory(meta)
add_subdirectory(contexts)
add_subdirectory(ast)
add_subdirectory(frontend)
add_subdirectory(callSlang)
callSlang/CMakeLists.txt
set(SOURCE_FILE main.cpp)
# add the files for creating executable
add_executable(slangLLVM ${SOURCE_FILE})
#link the libs
target_link_libraries(slangLLVM
PRIVATE
ast
frontend
)
ast/CMakeLists.txt
set(SOURCE_FILES Visitor.cpp)
add_library(ast ${SOURCE_FILES})
target_link_libraries(ast
PUBLIC
meta
contexts
LLVMSupport
expression
PRIVATE
frontend
)
# get the include dirs
target_include_directories(ast
INTERFACE
.
PUBLIC
${LLVM_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/meta
${PROJECT_SOURCE_DIR}/ast/expression
)
add_subdirectory(expression)
expression/CMakeLists.txt
set(SOURCE_FILES Expression.cpp NumericExpression.cpp)
add_library(experssion ${SOURCE_FILES})
target_link_libraries(experssion
PUBLIC
ast
)
# get the include dirs
target_include_directories(experssion
INTERFACE
.
PUBLIC
${LLVM_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/contexts
${PROJECT_SOURCE_DIR}/ast
${PROJECT_SOURCE_DIR}/meta
)
# INTERFACE tells to use includes to other libs but on the ast
frontend/CMakeLists.txt
set(SOURCE_FILES Parser.cpp)
add_library(frontend STATIC ${SOURCE_FILES})
target_link_libraries(frontend
PRIVATE
ast
)
# get the include dirs
target_include_directories(frontend
INTERFACE
.
PRIVATE
${PROJECT_BINARY_DIR}
${PROJECT_SOURCE_DIR}/ast
${PROJECT_SOURCE_DIR}/contexts
${PROJECT_SOURCE_DIR}/ast/expression
)
meta/CMakeLists.txt
add_library(meta INTERFACE)
# get the include dirs
target_include_directories(meta INTERFACE .)
This compiles without error but fails during linking with the following error
[100%] Linking CXX executable slangLLVM
/usr/bin/ld: cannot find -lexpression
collect2: error: ld returned 1 exit status
make[3]: *** [callSlang/CMakeFiles/slangLLVM.dir/build.make:93: callSlang/slangLLVM] Error 1
make[3]: Leaving directory '/home/nithin/learn/c-cpp/slang-llvm/build'
make[2]: *** [CMakeFiles/Makefile2:392: callSlang/CMakeFiles/slangLLVM.dir/all] Error 2
make[2]: Leaving directory '/home/nithin/learn/c-cpp/slang-llvm/build'
make[1]: *** [Makefile:84: all] Error 2
make[1]: Leaving directory '/home/nithin/learn/c-cpp/slang-llvm/build'
make: *** [Makefile:4: all] Error 2
CallSlang depends on ast, ast depends on the expression and vice versa.
I have tried the solution in the link but it not-working so far for me. I am really new to CMake. Is it caused by the circular call by ast and expression, if so how can correct the same?
The complete code can be found in this link
Could someone please tell me the possible cause and solution? If I've missed out anything, over- or under-emphasized a specific point, please let me know in the comments. Thank you so much in advance for your time.
I'm having a bit of trouble organizing my c++ project as a cmake project, which is something I'm new to. I'm trying to mimic the template given by this github repository. I think I'm almost there, but I'm getting a few linker errors when I try to compile with the following commands:
cd markets
rm -rf build/manual
mkdir build/manual
cd build/manual
cmake -G "Unix Makefiles" -D CMAKE_CXX_COMPILER=/usr/bin/g++-8 ../..
make
There's a lot of output, but here are the first few lines:
[100%] Linking CXX executable markets_tests
CMakeFiles/markets_tests.dir/src/test_data_handler.cpp.o: In function `Testtest_data_handler::RunImpl() const':
test_data_handler.cpp:(.text+0x12a): undefined reference to `Instrument::Instrument(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
test_data_handler.cpp:(.text+0x153): undefined reference to `Instrument::Instrument(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
test_data_handler.cpp:(.text+0x37f): undefined reference to `DataHandler::DataHandler(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, unsigned int const&, unsigned int const&)'
CMakeFiles/markets_tests.dir/src/test_data_reader.cpp.o: In function `Testtest_csv_reader::RunImpl() const':
test_data_reader.cpp:(.text+0xa9): undefined reference to `csv_reader(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int)'
I guess this must mean that something is wrong with my markets/test/CMakeLists.txt file, which I have now as:
cmake_minimum_required(VERSION 3.10)
project(markets_tests)
find_package(UnitTest++ REQUIRED)
find_package(Eigen3 3.3 REQUIRED NO_MODULE)
SET(GCC_COVERAGE_COMPILE_FLAGS "-no-pie")
SET(CMAKE_CXX_FLAGS "${GCC_COVERAGE_COMPILE_FLAGS}")
include_directories(${MARKETS_HEADERS_DIR})
include_directories(${UTPP_INCLUDE_DIRS})
set(SOURCE_FILES main.cpp
src/test_data_handler.cpp
src/test_data_reader.cpp
src/test_exec_handler.cpp
src/test_fill.cpp
src/test_instrument.cpp
src/test_market_bar.cpp
src/test_market_snapshot.cpp
src/test_order.cpp
src/test_pnl_calculator.cpp
src/test_portfolio.cpp
src/test_position_summary.cpp)
add_executable(markets_tests ${SOURCE_FILES})
target_link_libraries(markets_tests markets Eigen3::Eigen UnitTest++) # added Eigen
install(TARGETS markets_tests DESTINATION bin)
Any ideas? Other questions seem to suggest that I could be linking things in the wrong order, but this project structure isn't that complicated (just an executable, a library, and some unit tests). This was compiling with my old makefile, so I doubt it's because I haven't defined some of the header definitions.
Here is the tree of my markets/ root directory if it helps:
.
├── bin
├── build
│ └── manual
├── CMakeLists.txt
├── docs
├── lib
├── README.md
├── src
│ ├── CMakeLists.txt
│ ├── main.cpp
│ └── markets
│ ├── CMakeLists.txt
│ ├── data_handlers.cpp
│ ├── data_handlers.h
│ ├── data_readers.cpp
│ ├── data_readers.h
│ ├── execution_handler.cpp
│ ├── execution_handler.h
│ ├── fill.cpp
│ ├── fill.h
│ ├── instrument.cpp
│ ├── instrument.h
│ ├── market_bar.cpp
│ ├── market_bar.h
│ ├── market_snapshot.cpp
│ ├── market_snapshot.h
│ ├── order.cpp
│ ├── order.h
│ ├── pnl_calculator.cpp
│ ├── pnl_calculator.h
│ ├── portfolio.cpp
│ ├── portfolio.h
│ ├── position_summary.cpp
│ └── position_summary.h
└── test
├── CMakeLists.txt
├── main.cpp
├── src
│ ├── test_data_handler.cpp
│ ├── test_data_reader.cpp
│ ├── test_exec_handler.cpp
│ ├── test_fill.cpp
│ ├── test_instrument.cpp
│ ├── test_market_bar.cpp
│ ├── test_market_snapshot.cpp
│ ├── test_order.cpp
│ ├── test_pnl_calculator.cpp
│ ├── test_portfolio.cpp
│ └── test_position_summary.cpp
└── test_data
├── QLD.csv
└── SPY.csv
Edit:
Here is src/markets/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(markets)### C CXX)
set(SOURCE_FILES
data_handlers.h
data_handlers.cpp
data_readers.h
data_readers.cpp
execution_handler.h
execution_handler.cpp
fill.h
fill.cpp
instrument.h
instrument.cpp
market_bar.h
market_bar.cpp
market_snapshot.h
market_snapshot.cpp
order.h
order.cpp
pnl_calculator.h
pnl_calculator.cpp
portfolio.h
portfolio.cpp
position_summary.h
position_summary.cpp
)
find_package (Eigen3 3.3 REQUIRED NO_MODULE)
add_library(markets SHARED STATIC ${SOURCE_FILES})
target_link_libraries(markets Eigen3::Eigen stdc++fs) #added this
install(TARGETS markets DESTINATION ${MARKETS_INSTALL_LIB_DIR})
install(FILES markets.h DESTINATION ${MARKETS_INSTALL_INCLUDE_DIR})
RT~ ps: cmake version 3.9.2
My codebase just like this.
suzanwen#n224-004-133:~/repos/C++/ttt:)$ tree -L 2
.
├── build
│ ├── bin
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── lib
│ ├── Makefile
│ ├── test
│ └── thirdparty
├── build.sh
├── CMakeLists.txt
├── Makefile
├── test
│ ├── CMakeLists.txt
│ └── main.cc
└── thirdparty
├── CMakeLists.txt
├── gflags
└── hellolib
10 directories, 9 files
my thirdparty/hellolib/CMakeLists.txt is
PROJECT(hello)
SET(LIBHELLO_SRC hello.cc)
MESSAGE(STATUS "LIBRARY PATH=" ${LIBRARY_OUTPUT_PATH})
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
SET_TARGET_PROPERTIES(hello_static PROPERTIES ARCHIVE_OUTPUT_NAME "hello")
my test/CMakeLists.txt is
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/thirdparty/hellolib
${PROJECT_SOURCE_DIR}/thirdparty/gflags/include)
IF(LIBRARY_OUTPUT_PATH)
LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH})
ENDIF(LIBRARY_OUTPUT_PATH)
ADD_EXECUTABLE(main main.cc)
TARGET_LINK_LIBRARIES(main hello)
# TARGET_LINK_LIBRARIES(main hello_static)
when I build my top-level project, an error occurs like this.
/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cc.o -o ../bin/main -L/home/suzanwen/repos/C++/ttt/build/lib -Wl,-rpath,/home/suzanwen/repos/C++/ttt/build/lib -lhello
/usr/bin/ld: cannot find -lhello
But when I comment the line # SET_TARGET_PROPERTIES(hello_static PROPERTIES ARCHIVE_OUTPUT_NAME "hello") and TARGET_LINK_LIBRARIES with hello_static, everything goes fine.
It seems that TARGET_LINK_LIBRARIES cannot find renamed lib target. Could anyone explain it? thanks in advance.
It seems that TARGET_LINK_LIBRARIES cannot find renamed lib target.
Setting ARCHIVE_OUTPUT_NAME property renames not a target, but an output file. So linking with a target still works:
TARGET_LINK_LIBRARIES(main hello_static)
One cannot rename the target once it is created, but it is possible to create ALIAS for a target:
ADD_LIBRARY(hello ALIAS hello_static)
After that it is possible to link with the alias:
TARGET_LINK_LIBRARIES(main hello)