cmake linker configuration for a project that uses wxWidgets - cmake

I have the following problem. I want to create a cross-platform GUI application that uses wxWidgets
I am trying to compile and run a "Hello World" example from wxWidgets web site.
I want to use cmake to build the project. On Linux everything works without problems, but on Windows I see the following linking error
MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
It looks like the linker is looking for main function for some reason (shouldn't it look for WinMain?)
The example code has wxIMPLEMENT_APP(MyApp); macro, I have also set the linker option
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /subsystem:windows"), but nothing helps, so I don't understand what is the problem. I have a feeling that I missed something simple. May be you had a similar problem before with one of your projects? Thank you for your help.
My CMakeLists.txt file is given below
cmake_minimum_required (VERSION 3.8)
project ("project")
set(CMAKE_CXX_STANDARD 17)
set(WXWIN "C:/msys64/wxWidgets")
# =========================================================================
set(BUILD_DEPS ON)
list(APPEND CMAKE_MODULE_PATH "include/libs")
include_directories("include/libs")
add_subdirectory("include/libs/glog")
if (MSVC)
set(wxWidgets_ROOT_DIR ${WXWIN})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /subsystem:windows")
endif (MSVC)
find_package(wxWidgets COMPONENTS net gl core base)
include(${wxWidgets_USE_FILE})
set(wxWidgets_USE_UNICODE ON)
# Create shared library for the project
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(PROJECT_LINK_LIBS Tools)
set(LIBRARY_SRC include/Tools.cpp)
add_library(Tools SHARED ${LIBRARY_SRC})
link_directories("out/build")
set_target_properties(Tools PROPERTIES POSITION_INDEPENDENT_CODE 1)
# =========================================================================
# Add source to this project's executable.
add_executable (project "project.cpp" "project.h")
target_compile_features(project PUBLIC cxx_std_17)
target_link_libraries (project ${PROJECT_LINK_LIBS} ${wxWidgets_LIBRARIES})

It turns out that to make it work in need to put WIN32 into add_executable command of cmake
add_executable (project "project.cpp" "project.h") => add_executable (project WIN32 "project.cpp" "project.h")

Related

CMake not able to find Debug Library

I am a CMake noob trying to put together a package installer so i can move between my windows development machine and my cluster.
I have the following directory tree for my files (an example)
-Primary
--Library Source
--CMakeLists.txt
--src1.cpp
--src1.h
--Application Source
--CMakeLists.txt
--src1.cpp
--src1.h
--CMakeLists.txt
Each CMakeLists.txt is
Primary/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(BloodVesselRadiationDamageSimulations CXX)
SET(FIND_LIBRARY_USE_LIB64_PATHS true)
SET(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}) #only for testing
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_ROOT}/ ${CMAKE_SOURCE_DIR}/cmake/Modules/")
FIND_PACKAGE(OpenMP)
FIND_PACKAGE(MPI)
FIND_PACKAGE(HDF5)
FIND_PACKAGE(GTest)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
SET(CMAKE_DEBUG_POSTFIX _d)
ADD_SUBDIRECTORY(Source)
ADD_SUBDIRECTORY(SourceUnitTest)
Library Source/CMakeLists.txt
ADD_LIBRARY(VesselProjectBaseLibrary STATIC Src1.cpp
Src1.h)
INSTALL(TARGETS VesselProjectBaseLibrary DESTINATION x64/Debug CONFIGURATIONS Debug)
INSTALL(TARGETS VesselProjectBaseLibrary DESTINATION x64/Release CONFIGURATIONS Release|RelWithDebInfo)
Application Source/CMakeLists.txt
INCLUDE_DIRECTORIES("${GTEST_INCLUDE_DIRS}")
ADD_EXECUTABLE (SourceUnitTests Src1.cpp
Src1.h)
TARGET_LINK_LIBRARIES(SourceUnitTests ${GTEST_LIBRARY})
TARGET_LINK_LIBRARIES(SourceUnitTests debug VesselProjectBaseLibrary_d optimized VesselProjectBaseLibrary)
I am able to generate the projects correctly; I see all the correct files in the projects. However, when i go to compile the debug build I get the following error:
1>ipo: : error #11018: Cannot open VesselProjectBaseLibrary_d.lib
1>LINK : fatal error LNK1104: cannot open file 'VesselProjectBaseLibrary_d.lib'
If i compile my release build everything works perfectly and compilation is successful. The library compiles successfully under both builds.
When you link against a library created within the project, you need to specify library target name, not a library file. CMake will care about proper filename, path and other things:
TARGET_LINK_LIBRARIES(SourceUnitTests VesselProjectBaseLibrary)
Variable CMAKE_DEBUG_POSTFIX affects on library's filename. While file VesselProjectBaseLibrary_d.lib is actually created in debug build, it cannot be found automatically by the linker. Again, use target name and let CMake do all other work.

Ogre Error In Cmake

While implementing CMake in my code I am getting an ogre error:
/usr/bin/ld: cannot find -lOGRE
My CMakeLists.txt file looks like:
#Specify the version being used aswell as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(eCAD)
#sets cmake to run moc when needed
set(CMAKE_AUTOMOC ON)
#find requirements of this projects
find_package(Qt5Widgets)
find_package(Qt5Core)
find_package(OGRE)
find_package(OIS)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#Sends the -std=c++11 flag to the gcc compiler
add_definitions(-std=c++11)
qt5_wrap_ui(Cmake_form_hdr resources/ui/mainwindow.ui)
#This tells CMake to main.cpp and name it eCAD
add_executable(eCAD main.cpp ${Cmake_form_hdr})
#include the subdirectory containing our libs
add_subdirectory (gui)
include_directories(gui)
#link_libraries
target_link_libraries(eCAD Qt5::Widgets Qt5::Core OGRE OIS)
I am new to this. Please help me out to solve the problem
The command find_package(OGRE) runs file FindOGRE.cmake and sets variables OGRE_INCLUDE_DIRS and OGRE_LIBRARIES. To link with the OGRE library, you should use these variables, e.g.
target_include_directories(eCAD PRIVATE ${OGRE_INCLUDE_DIRS})
target_link_libraries(eCAD ${OGRE_LIBRARIES})
This is same for all of the external libraries you use.

Getting a CMake Error: Cannot specify link libraries for target which is not built by the project

I am implementing CMake in my code but I'm getting the error
"Cannot specify link libraries for target "Qt5::Widgets" which is not built by the project".
Below are the contents of the CMakeLists.txt:
#Specify the version being used aswell as the language
cmake_minimum_required(VERSION 2.6)
#Name your project here
project(eCAD)
#Sends the -std=c++11 flag to the gcc compiler
ADD_DEFINITIONS(-std=c++11)
#This tells CMake to main.cpp and name it eCAD
add_executable(eCAD main.cpp)
#include the subdirectory containing our libs
add_subdirectory (gui)
include_directories(gui)
#include Qt directories
find_package(Qt5Widgets)
find_package(Qt5Core)
find_package(Qt5Designer)
SET(QT_USE_QTDESIGNER ON)
#link_libraries
target_link_libraries(Qt5::Widgets Qt5::Core)
In addition to the accepted answer: An important detail is to place target_link_libraries after the add_executable and find_package lines, so all linked components are known.
The first argument of target_link_libraries is the target name:
target_link_libraries(eCAD Qt5::Widgets Qt5::Core)
Also, do not confuse target name with the project name:
a command project specifies a project name, but
a target is the one created with add_executable, add_library or add_custom_target.
The error message is about the target.
Set you_lib_name before setting target_link_libraries
set(you_lib_name libname)
target_link_libraries(you_lib_name Qt5::Widgets Qt5::Core)

cmake doesn't support imported libraries?

When I try to import a library using
add_library(libname SHARED IMPORTED)
set_property(TARGET libname PROPERTY IMPORTED_LOCATION /<foldername>/<sub-foldername>/lib")
The cmake shouts :
CMake Warning (dev) at /CMakeLists.txt:28
(target_link_libraries): Cannot specify link libraries for target
"libname" which is not built by this project.
CMake does not support this but it used to work accidentally and is
being allowed for compatibility.
Policy CMP0016 is not set: target_link_libraries() reports error if
only argument is not a target. Run "cmake --help-policy CMP0016"
for policy details. Use the cmake_policy command to set the policy
and suppress this warning. This warning is for project developers.
Use -Wno-dev to suppress it.
If this is true, what is the other best way to include a library somewhere in my build tree into another project.
I have a library setup and another place has executable which will be using the libraries.
Reading through the cmake documentation, it felt like this would be the best way forward but seems its a broken piece which is just being supported.
Cannot specify link libraries for target "libname" which is not built by this project
When you use target_link_libraries to some target you're specifying how to build it,
but imported library is already build. CMake told you that...
Example of linking imported target to executable:
add_library(boo SHARED IMPORTED)
set_target_properties(boo PROPERTIES IMPORTED_LOCATION "/path/to/boo/library")
add_executable(foo foo.cpp)
target_link_libraries(foo boo)
Note: using imported targets
I was getting the same error as navderm when trying to import the Poco C++ libPocoFoundation.so library into my project, and after trying different solutions unsuccessfully, I managed to find one that worked for me:
cmake_minimum_required(VERSION 3.5)
project(MyProject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_library(PocoLib SHARED IMPORTED GLOBAL)
# It's important to specify the full path to the library you want to import
set_target_properties(PocoLib PROPERTIES IMPORTED_LOCATION "/usr/local/lib/Poco_1.7.2/lib/libPocoFoundation.so")
# create my executable
set(EXEC_SOURCE_FILES main.cpp)
add_executable(MyProject ${EXEC_SOURCE_FILES})
target_link_libraries(MyProject PocoLib)

adding xapian library in cmake

I am trying to add xapian search engine library in cmake file
project(search)
cmake_minimum_required(VERSION 2.8)
find_package(Xapian REQUIRED)
aux_source_directory(. SRC_LIST)
target_link_libraries(${PROJECT_NAME}
${Xapian_LIBRARY}
)
add_executable(${PROJECT_NAME} ${SRC_LIST})
This is not working can any one tell me how to add this if i compile with -lxapian it works
Swap target_link_libraries() and add_executable() calls. You can link library only to already defined target.
And use ${XAPIAN_LIBRARIES} instead of ${Xapian_LIBRARY}.