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})
Related
I am developing a module, which depends on another library(wasmtime). I put files into:
modules/mod_wasm/src/include - header files, and
modules/mod_mine/src/lib/libwasmtime.a - the compiled library.
The problem which I faced is that when I compile the acore server with
./acore.sh compiler all
it gives me the error:
[100%] Linking CXX executable worldserver
/usr/bin/ld: ../../../modules/libmodules.a(ModWasm.cpp.o): in function `readWasmFile(char const*)':
ModWasm.cpp:(.text+0x63): undefined reference to `wasm_byte_vec_new_uninitialized'
/usr/bin/ld: ModWasm.cpp:(.text+0xce): undefined reference to `wasm_byte_vec_delete'
The question is it required somehow add to a config that library? If yes, then how to do that?
I was testing my code in simple main.cpp file and it was working with options like "-L${workspaceFolder}/lib" and "-lwasmtime".
Maybe, these options are also required for my module?
Here is a link to azerothcore project which I use.
my module locates in modules/mod-wasm folder
azerothcore-wotlk/modules ‹master*› » tree -L 3 mod-wasm
mod-wasm
├── CMakeLists.txt
├── LICENSE
├── Makefile
├── README.md
├── conf
│ ├── conf.sh.dist
│ └── wasm.conf.dist
├── include.sh
├── mod-wasm.cmake
├── setup_git_commit_template.sh
├── src
│ ├── ModWasm.cpp
│ ├── include
│ │ ├── doc-wasm.h
│ │ ├── wasi.h
│ │ ├── wasm.h
│ │ ├── wasmtime
│ │ ├── wasmtime.h
│ │ └── wasmtime.hh
│ ├── lib
│ │ ├── libwasmtime.a
│ │ └── libwasmtime.so
│ └── wasm_loader.cpp
└── wasm_modules
└── rust_wasm_app.wasm
As I understood from the logs what I see and because CMakeList.txt exists in modules folder, the project considers the folder as module. Which in its turn scans subdirs for *.cmake files and configures the project.
The question now is how to properly configure my module to show that it contains the compiled library wasmtime inside src/lib folder?
As I understood, I could use target_link_libraries, but it requires a target name, and I have no idea what it should be and where I can take it.
At the end, I was able to find an answer with try and catch.
Azerothcore modules supports modname.cmake file to be run when configure libmodules.a which contains all extra modules(if I understood it correctly.
this is part of modules/CMakeFiles.txt
# Enables Devs to Include a cmake file in their module that will get run inline with the config.
foreach(SOURCE_MODULE ${MODULES_MODULE_LIST})
message("SOURCE_MODULE: ${SOURCE_MODULE}")
include("${CMAKE_SOURCE_DIR}/modules/${SOURCE_MODULE}/${SOURCE_MODULE}.cmake" OPTIONAL)
endforeach()
here I have my dirty cmake file which allow me to compile the server
set(WASM_MODULE_DIR ${CMAKE_SOURCE_DIR}/modules/${SOURCE_MODULE})
set(WASM_MODULE_SRC_DIR ${WASM_MODULE_DIR}/src)
message("--------------------->>>>> APPLICATION_NAME : ${APPLICATION_NAME}")
message("--------------------->>>>> APP_PROJECT_NAME : ${APP_PROJECT_NAME}")
message("--------------------->>>>> SOURCE_MODULE : ${SOURCE_MODULE}")
message("--------------------->>>>> WASM_MODULE_DIR : ${WASM_MODULE_DIR}")
message("--------------------->>>>> WASM_MODULE_SRC_DIR : ${WASM_MODULE_SRC_DIR}")
# include wasmtime
target_include_directories(modules PUBLIC ${WASM_MODULE_SRC_DIR}/include)
target_link_directories(modules PUBLIC ${WASM_MODULE_SRC_DIR}/lib)
find_library(LIBWASMTIME_TO_INCLUDE NAMES wasmtime PATHS ${WASM_MODULE_SRC_DIR}/lib REQUIRED)
message("--------------------->>>>>>>>> LIBWASMTIME_TO_INCLUDE: ${LIBWASMTIME_TO_INCLUDE}")
target_link_libraries(modules PUBLIC wasmtime)
So, it compiles now.
But I have next problem, which I am trying to resolve. but this is another story.
Thank you all for the help
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.
This is an example of a tuigraphics library I'm working on, what would be the best approach into creating it's public interface accessible via a single header file?
├── CMakeLists.txt
├── include
│ ├── Cell.hpp
│ ├── Grid.hpp
│ ├── math.hpp
│ ├── Node.hpp
│ ├── Renderer.hpp
│ ├── shape
│ │ ├── CircleShape.hpp
│ │ ├── RectangleShape.hpp
│ │ └── Shape.hpp
│ └── types.hpp
└── src
└── Node.cpp
I would like to access the library like so:
#include <tuigraphics.hpp>
int main(void)
{
Node node(CircleShape(10), Vector2(10, 10));
return EXIT_SUCCESS;
}
I have thought about putting a header file tuigraphics.hpp including all header files, but I'm not quite sure about it. I have never built a static library, and i would like some advice on how to proceed. Also here the CMake configuration:
project(libex)
cmake_minimum_required(VERSION 3.16)
add_library(tuigraphics STATIC)
target_include_directories(tuigraphics PRIVATE ./include)
target_sources(tuigraphics PRIVATE src/Node.cpp
include/Node.hpp
include/types.hpp
include/math.hpp
include/Cell.hpp
include/shape/CircleShape.hpp
include/shape/Shape.hpp
include/shape/RectangleShape.hpp
include/Renderer.hpp)
target_include_directories(tuigraphics PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
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.
I'm new to C++ , i have installed the lib Com++ for network programming
but when i just include the header file
#include <iostream>
#include <ComPP/ComPlusPlus>
using namespace std;
int main(int argc ,char *argv[]){
cout << "Hello World" << endl;
return 0;
}
i get the error
main.cpp:2:29: fatal error: ComPP/ComPlusPlus: No such file or directory
using fedora linux
i used this command to compile as mentioned in the manual
g++ -I ./ -L./ -o server main.cpp -lCommPP -lsys -lpthread -lrt
the directory /usr/include/ComPP/ is exist with all the header files
ComPP
├── ComPlusPlus
│ ├── AClnt.h
│ ├── ASrvContext.h
│ ├── ASrv.h
│ ├── ASrvProperties.h
│ ├── Clone.h
│ ├── Comm.h
│ ├── ComPlusPlus
│ ├── Context.h
│ ├── Daemon.h
│ ├── Directory.h
│ ├── DirEntry.h
│ ├── File.h
│ ├── Launch.h
│ ├── Mutex.h
│ ├── Poll.h
│ ├── Process.h
│ ├── SClnt.h
│ ├── Sem.h
│ ├── ShMem.h
│ ├── Signalling.h
│ ├── Socket.h
│ ├── SocketTcp.h
│ ├── SocketUdp.h
│ ├── SocketUnix.h
│ ├── SrvProperties.h
│ ├── SSrvContext.h
│ ├── SSrv.h
│ ├── SSrvProperties.h
│ └── Thread.h
└── SysPlusPlus
├── ComException.h
├── config.h
├── GenCfg.h
├── Logger.h
├── syscall.h
├── syslib.h
├── SysPlusPlus
└── Tools.h
You do not include a header file. #include <ComPP/ComPlusPlus> this is a directory. From what you posted you need to add another ComPlusPlus. #include <ComPP/ComPlusPlus/ComPlusPlus> but it very uncommon to use headers without the .h ending. So you better check the spelling of directories and files.
After carefully reading the cplusplus.com site. The error is indeed something else.
They assume that you set the include path of your compiler to ComPP. E.g as Ahmed already commented with a -I /usr/include/ComPP.
So you can either fully qualify your include in the cpp file as /usr/include/ is a standard search path for gcc or you add another path.
Nevertheless I find it very irritating to use a header without a .h ending.
When you download the comPP library there is a ProgrammersGuide.pdf in the Documentation folder. There you can find what libs are needed. The file is not 100% accurate. I got it working using this format:
g++ -I/usr/include/ComPP -lComPP -lSysPP -lpthread -lrt ExampleClient.cpp -o ExampleClient
This will only work if you have these includes:
#include <SysPlusPlus/SysPlusPlus>
#include <ComPlusPlus/ComPlusPlus>
Kind Regards,
Maarten