I have a project in Clion using CMake and C++14. The project compiles but all standard library includes are marked as:
"Cannot find string", "Cannot find stdexcept", etc.
Additionally the symbols from the dll I included are not being detected. So they are all marked as:
"Cannot resolve ..."
I've included the header and cmakelist.txt. This is only happening in this project and I have almost identical cmakelist.txt files for all my projects. I have tried restarting CLion's cache. I also tried moving all the files to a new project which worked momentarily but with an hour CLion was flagging these lines again.
cmakelists.txt
cmake_minimum_required(VERSION 3.6)
project(BCI)
set(CMAKE_CXX_STANDARD 14)
#create dlls and executables in the root directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
include_directories(
${CMAKE_SOURCE_DIR}
)
set(SOURCE_FILES
NeuralInterface.hpp
)
add_library(BCI SHARED ${SOURCE_FILES})
set_target_properties(BCI PROPERTIES LINKER_LANGUAGE CXX)
NeuralInterface.hpp
#ifndef NEURALINTERFACE_HPP
#define NEURALINTERFACE_HPP
//c++ includes
#include <stdexcept> //these are the includes which cannnot be resolved
#include <string>
//project includes
#include "okFrontPanelDLL.h"
extern std::string IntanAcquire; //this says cannot resolve container std
...
#endif
What else can I do to CMake so it finds these headers?
Related
As stated in the title, I have configured CMake to link GLEW with my project, and have #include <GL/glew.h> in a .hpp file with no issue. The issue arises when trying to use GLEW functions in the declaration (.cpp) file associated with the header file, which gives me the error identifier "xxx" is undefined with xxx being the variety of functions I am trying to use.
Furthermore, I have also linked SDL2 in a similar manner, and have run into no issues in using its functions in the same declaration file. I believe the issue must be in my CMakeLists.txt configuration:
CMakeLists.txt
cmake_minimum_required (VERSION 3.8)
set(PROJECT GUI_Engine)
add_executable (${PROJECT} "./src/driver/main.cpp")
set(HEADER_FILES ./src/include)
set(DEC_FILES ./src/lib)
set(PKGPATH C:/dev/vcpkg/packages)
add_library(engine ${DEC_FILES}/engine.cpp ${HEADER_FILES}/engine.hpp)
list(APPEND CMAKE_PREFIX_PATH ${PKGPATH}/sdl2_x64-windows)
find_package(SDL2 CONFIG REQUIRED)
target_link_libraries(${PROJECT} PRIVATE engine SDL2::SDL2main)
target_link_libraries(engine PUBLIC SDL2::SDL2)
list(APPEND CMAKE_PREFIX_PATH ${PKGPATH}/glew_x64-windows)
find_package(GLEW REQUIRED)
target_link_libraries(engine PUBLIC GLEW::GLEW)
For reference, engine is the label associated with the .hpp and .cpp files I have been referencing.
For further testing, I have tried to #include <GL/glew.h> in my .cpp file, and receive the error cannot open source file "GL/glew.h". Also, when using any GLEW function in my .hpp file, no error arises.
UPDATE
My IDE came out with an update today, as well as the associated build tools, with this update, I no longer am having this issue!
I'm struggling to use a DLL generated using CMAKE and C++. I'm able to build the library, include it and build the target project, the problem is that when I run the target build it crashes immediately.
My code is super easy and I don't know what I'm missing.
The DLL is built using CMAKE in a separate project. Here's the code
DLL PROJECT:
CMakeLists
cmake_minimum_required(VERSION 3.5)
project(LibProj LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_definitions("-DBUILD_LIB")
file(GLOB
INCLUDE_FILES
baselibraryclass.h
)
file(GLOB
SOURCE_FILES
baselibraryclass.cpp
)
add_library(yourlib SHARED ${INCLUDE_FILES} ${SOURCE_FILES} )
baselibraryclass.h
#ifndef BASELIBRARYCLASS_H
#define BASELIBRARYCLASS_H
#ifdef BUILD_LIB
#define EXT_DLL __declspec(dllexport)
#else
#define EXT_DLL __declspec(dllimport)
#endif
#include <string>
class EXT_DLL BaseLibraryClass
{
public:
BaseLibraryClass();
};
#endif // BASELIBRARYCLASS_H
baselibraryclass.cpp
#include "baselibraryclass.h"
#include <iostream>
EXT_DLL BaseLibraryClass::BaseLibraryClass()
{
std::cout << "Hi from the library Class Object " << std::endl;
}
Target project
CMakeLists
cmake_minimum_required(VERSION 3.5)
project(TargetProject LANGUAGES CXX)
#Including the path of the library header
include_directories(D:/TestingDLLNativeCpp/Library/include)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(TargetProject main.cpp)
#The path of the built library is D:/TestingDLLNativeCpp/Library/Debug/yourlib.lib
target_link_libraries(TargetProject PRIVATE D:/TestingDLLNativeCpp/Library/Debug/yourlib.lib)
Target project main.cpp
#include <iostream>
#include <baselibraryclass.h>
using namespace std;
int main()
{
BaseLibraryClass testObk;
return 0;
}
As I wrote above, cmake configures properly and the compiler is able to build for both projects, however the target executables crashes immediately.
What am I doing wrong o.O??
Thanks for the attention
The issue of the dll not being included in the build directory might be solved by setting the CMAKE_RUNTIME_OUTPUT_DIRECTORY. However, a better practice would be to set the output directory of the .dll on a target basis. This will ensure that you have no unwanted side-effects in the long run.
set_target_property(yourlib PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
I have simple program as follow:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR})
add_executable(test main.cpp)
target_include_directories(test PRIVATE ${PROJECT_SOURCE_DIR})
target_link_libraries(test PRIVATE power.dll)
main.cpp:
#include <iostream>
#include "power.h"
using namespace std;
int main()
{
cout << "Hello World!" << endl;
power(4.);
return 0;
}
power.h:
#ifndef POWER_H
#define POWER_H
double power(double number) noexcept;
#endif // POWER_H
Implementation of power.h is in a .dll named power.dll.
If I compile this project with MinGW 7.3.0 X64 says:
error: undefined reference to `power(double)'
If I compile it with MSVC 2017 X64 says:
error: LNK1104: cannot open file 'power.lib'
both errors show that power.dll can't detect by the linker.
I did many searches but none of solutions worked for me!
Can anyone help about this?
Thanks in advance!
Your modelling of the dynamic library is incorrect, both on CMake and on the source level.
As a starting point, try building the dll as part of the same CMake project as the consuming executable:
cmake_minimum_required(VERSION 3.5)
project(test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(GenerateExportHeader)
add_library(power SHARED power_sources.cpp power.h)
generate_export_header(power)
target_include_directories(power PUBLIC ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR})
add_executable(test main.cpp)
target_link_libraries(test PRIVATE power)
Note the use of the generate_export_header function, which instructs CMake to generate macros for exporting functions on shared library interfaces in a portable way. Since generated files go to the binary directory tree, we have to adjust the include directories for the library accordingly.
To make sure the function gets properly exported, change your header as follows:
#ifndef POWER_H
#define POWER_H
#include <power_export.h>
POWER_EXPORT double power(double number) noexcept;
#endif // POWER_H
Note that generare_export_header allows you to customize the generated export header extensively.
Be sure you get the project to build and run from this baseline.
If you want to build the dll externally (which is not strictly necessary, but since that's what your question is about...), we have to modify the CMake file to something like:
cmake_minimum_required(VERSION 3.5)
project(test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(power)
add_executable(test main.cpp)
target_link_libraries(test PRIVATE power)
With all the magic here happening in the find_package call. That call is now responsible for providing all the information that was previously handled by the lines for building the library:
Providing of an imported target power for consumption by the target_link_libraries call
Association of the library name of the import library (the power.lib file) via that imported target
Exposure of the public include directories for both power.h and power_export.h via that imported target
You can either construct such an imported target manually in the find script, or have CMake do it for you. In the first case, create a FindPower.cmake script file, make sure it's location is part of the CMAKE_MODULE_PATH and write the code for finding the library and header files and constructing the imported target in there. Note that getting this right in a portable way can be very tricky and goes far beyond the scope of a StackOverflow question. In the second case, have the CMake script that builds the power library perform an install step during which a config file package will get generated, which can then be consumed by your test project. Note that this approach is not viable if the power library is not itself being built with CMake, so in that case you will have to stick with the first option.
Dynamic linking in Windows requires that externally visible symbols are declared with the keyword __declspec. Your header "power.h" should be modified:
#ifndef POWER_H
#define POWER_H
#if defined(__WIN32__) && !defined(__CYGWIN__)
# if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_DLL)
# define POWERAPI __declspec(dllexport)
# elif (defined(_MSC_VER) || defined(__MINGW32__))
# define POWERAPI __declspec(dllimport)
# endif
#endif
POWERAPI double power(double number) noexcept;
#endif // POWER_H
In the project building the DLL power.dll with CMake, you should define the symbol BUILD_DLL:
add_definitions(-DBUILD_DLL)
then it should generate a power.lib file when the MSVC compiler and a power.a when using MINGW. Don't define BUILD_DLL in the project using the DLL, and it should work.
I've created a shared library with library.h and library.cpp. Then wrote a CMakeLists.txt file to build it as a shared library.
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(test_pro)
set(CMAKE_CXX_STANDARD 11)
add_library(test_pro SHARED library.cpp library.h)
after building the library, I was able to get a .so file as /home/user/projects/test_lib/bin/libtest_pro.so
Then I tried linking the created library to another project in /home/user/projects/testproject
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(testproject)
set(CMAKE_CXX_STANDARD 11)
link_directories(
/home/user/projects/test_lib/bin
)
add_executable(testproject main.cpp)
target_link_libraries (testproject test_pro)
It successfully builds the testproject (ldd command shows it has linked correctly), but I'm unable to use the library I've created in it.
In the main.cpp I've tried,
#include "library.h"
#include "test_pro"
#include <test_pro>
#include <test_pro/library.h>
But all the above gave build failures (fatal error: xxx: No such file or directory). How do I use this created library?
Just like you set link_directories() you have to specify include_directories(). And it is recommended not to use link_directories() at all, instead pass absolute path to the library into target_link_libraries().
Wt v. 3.2.2 and boost libraries v. 1.47 had succesfully installed in my computer and no errors occured in the installation process. Some simple Wt and Boost examples were compiled and ran correctly in the testing process. I use CMake, configured for MSVC 2008, to create the build files for my own Wt projects.
However, when I try to build my own project, I get this error (Cannot open include file: 'boost/any.hpp'). As I saw, boost/any.hpp is included in Wt/WApplication header file.
For further help, my CMakeLists.txt files contents are:
CMakeLists.txt placed on project directory:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(WT_EXAMPLE)
SET (WT_CONNECTOR "wthttp" CACHE STRING "Connector used (wthttp or wtfcgi)")
ADD_SUBDIRECTORY(source)
CMakeLists.txt placed on source directory:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(WT_INSTALL_DIR "C:/Program Files/WT/boost_1_47")
SET(BOOST_INSTALL_DIR "C:/Program Files/boost")
ADD_EXECUTABLE(
GOP.wt
Main.C
)
SET(WT_LIBS
optimized wthttp debug wthttpd
optimized wt debug wtd)
SET(BOOST_LIBS
boost_signals boost_regex boost_thread boost_filesystem boost_system
boost_random boost_date_time boost_program_options)
TARGET_LINK_LIBRARIES (
GOP.wt
${WT_LIBS} ${BOOST_LIBS} ${SYSTEM_LIBS}
)
LINK_DIRECTORIES (
${WT_INSTALL_DIR}/lib/
${BOOST_INSTALL_DIR}/lib/
)
INCLUDE_DIRECTORIES(${WT_INSTALL_DIR}/include)
INCLUDE_DIRECTORIES(${BOOST_INSTALL_DIR}/include)
As I saw in the CMakeCache.txt placed on Wt build directory, paths to boost libraries were found, but ...what about this line?
//The directory containing a CMake configuration file for Boost.
Boost_DIR:PATH=Boost_DIR-NOTFOUND
I asked this question on Wt support forum but I didn't get an answer for about 24 hours...
Update: I found that any.hpp is placed on C:\Program Files\boost\boost_1_47\boost\spirit\home\support\algorithm\any.hpp. So, i suspect that there's a concept with the path that searches any.hpp (it's not directly included in boost directory).
Problem solved. I did a new Wt build, I placed and rebuild boost in a new path and I wrote CMakeLists for this project with more caution.
To include <boost/any.hpp>
For example
#include <boost/any.hpp>
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<boost::any> some_values;
some_values.push_back(10);
const char* c_str = "Hello there!";
some_values.push_back(c_str);
some_values.push_back(std::string("Wow!"));
std::string& s = boost::any_cast<std::string&>(some_values.back());
s += " That is great!\n";
std::cout << s;
}
we only need a simple cmake file like
# Defines AppBase library target.
project(recipe_01)
cmake_minimum_required(VERSION 3.5)
include(GNUInstallDirs)
set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
if(CMAKE_CXX_STANDARD EQUAL 98 OR CMAKE_CXX_STANDARD LESS 14)
message(FATAL_ERROR "app requires c++14 or newer")
elseif(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
find_package(Boost 1.60 REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main)