Binaries missing after successful build? - c++

I have a CMake project that I use to generate a Visual Studio solution, which I then try to compile. For some reason, the library file after compilation is nonexistent. I've searched my entire project folder, and cannot find any library files. Here's my CMake setup:
Project root:
cmake_minimum_required(VERSION 3.22)
project(ShadowContainers)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
include_directories(include/)
add_subdirectory(library)
...
library subdirectory:
add_library(libShadows shadows.tpp ../include/shadows.hpp)
set_target_properties(libShadows PROPERTIES LINKER_LANGUAGE CXX) # a tpp and an hpp aren't enough to make the system certain it's c++
target_compile_features(libShadows PRIVATE cxx_std_23)
The MSbuild output contains these lines:
Done Building Project "C:\Users\[..]\projects\Shadow Array\library\libShadows.vcxproj" (default targets).
Done Building Project "C:\Users\[..]\projects\Shadow Array\library\libShadows.vcxproj.metaproj" (default targets).
Even if libShadows is the only target in my project, it's nowhere in my project directory.
Has anybody else had this experience? Any help is appreciated. Thanks!
Edit:
To compile the project, I have tried:
My typical process (working directory = the project root):
cmake .
msbuild ShadowContainers.sln
An alternate process (working directory also project root):
mkdir build
cd build
cmake ..
cmake --build .
Both have produced the same result, albeit with VS and CMake files in different places. No library is outputted either way.

I was able to find the issue. CMake (and conventions for that matter) do not see a .tpp as a code file (similarly to how they treat header files). Thus, I was trying to compile a target with no legitimate code files. Template-only libraries are not libraries at all, so I should not be attempting to compile this standalone, and should instead put the .hpp and .tpp as the include in my projects!

Related

Set cache, build files and binary files directories for Visual Studio in CMake

Current environment
I have the following file structure:
project_root/
__main.cpp # app starting point
__CMakeLists.txt # CMake build starting point
__include/ # header files
__src/ # source files
__lib/ # libraries/dependencies which are also CMake projects
__res/
__build/ # CMake cache, build files
__bin/ # compiled binaries
I've been working with VS Code for both Windows and Linux platforms, but I would like to try out Visual Studio environment.
So far, using CMake Tools extension worked pretty well placing build files in build/ and binaries in /bin with the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
project(OPENGL_TEMPLATE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build")
# targets, libs and properties setup
The problem
Unfortunately, Visual Studio overrides these variables and creates some project_root/out/Debug/ directory, which does not fit my current directory tree.
There are two ways (to my knowledge) to run CMake project in Visual Studio, which I would like both to be compatible with my current directory tree:
Generate VS solution with CMake from terminal or CMake GUI and open it;
Open directory from File Explorer with "Open with Visual Studio"
So far, I have come up with this CMakeLists.txt:
cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build")
set(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/build")
project(PROJECT_NAME)
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds are forbidden.")
endif()
add_executable(main)
set_target_properties(main PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin"
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build"
VS_STARTUP_PROJECT main
FOLDER "App"
)
# other targets, libs and properties setup
And it works when generating .sln solution with CMake (but does not set the VS_STARTUP_PROJECT for some reason, but this is for another SO question), here build files go to build/ and binaries to bin/.
When using the second approach, VS still generates everything into out/Debug/, seemingly completely ignoring CMAKE_BINARY_DIR (which they claim corresponds to buildRoot VS configuration variable) and ARCHIVE_OUTPUT_DIRECTORY, RUNTIME_OUTPUT_DIRECTORY target properties.
The question (finally)
How can I setup CMake variables so that Visual Studio respects them (and does not override) using both approaches? Ideal situation would be to just open a clean project and be ready to configure, build and run, which means no additional tinkering in Visual Studio configuration files/settings. I am using Visual Studio 2022 Community 17.3.3.

How do I link dynamically built cmake files on Windows?

I have been struggling for the last 8 hours to find information on how to reference a library in a C project on Windows built with CMake, specifically cURL.
I have downloaded version 7.67 cURL source from the website, and then went used the visual studio developer command prompt to compile the CMake project into a build folder using the standard method of:
cd winbuild
nmake /f Makefile.vc mode=dll
Which outputs three curl folders, one of them called "libcurl-vc-x86-release-dll-ipv6-sspi-winssl".
In that folder contains a lib, a bin, and an include folder.
I built my C project with CLion and this is the CMake file that is generated.
cmake_minimum_required(VERSION 3.15)
project(hello_world C)
set(CMAKE_C_STANDARD 99)
add_executable(hello_world main.c)
How do I use my compiled CURL in my C project with CMake properly?
I finally solved this issue by creating a cmake folder at the C: directory, and copying in the built curl CMake project folder.
The issue was that there weren't any specific tutorials that I found on how to reference projects on Windows for CMake, specifically the curl project.
Fortunately, I found this post which specified an issue I had in referencing the include folder and .lib directory separately.
How to link shared library *dll with CMake in Windows
cmake_minimum_required(VERSION 3.15)
project(hello_world C)
set(CMAKE_C_STANDARD 99)
include_directories("C:/cmake/libcurl-vc-x86-release-dll-ipv6-sspi-winssl/include")
link_directories("C:/cmake/libcurl-vc-x86-release-dll-ipv6-sspi-winssl/lib")
add_executable(hello_world main.c)
set( LIBS libcurl )
target_link_libraries(hello_world ${LIBS} )
Now the code compiles and runs succesfully.
I don't believe this is the proper method of doing this though, any help would be appreciated.

CMake cannot figure out header dependencies if build is out-of-source?

I've been using CMake to manage a separate small c++ project (Unix Makefile based) and decided to convert it to a more organized out-of-source build. However when it's out-of-source (by doing a cmake .. in build/), my headers are no longer dependencies for their source files. If I just cmake from the top-level, everything is fine again.
So I've made a small test version and found the same problem. I'm on an Arch Linux system by the way. Originally, my project was in the /tmp directory (intentionally) and by reading this question: Handling header files dependencies with cmake, I thought this could be the culprit because CMake might be seeing directories as system ones and hence thinking my headers are from system libraries, so I moved it to my home folder. Nothing changed. I then messed around with the paths in my CMakeLists.txt, but it didn't seem to change anything. I also tried replacing everything with absolute paths.
project/CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (MYTEST)
include_directories(${CMAKE_SOURCE_DIR}/include)
file(GLOB SOURCES "${CMAKE_SOURCE_DIR}/src/*.cpp")
add_executable(app ${SOURCES})
project/src/hey.cpp:
#include "hey.h"
int main()
{
std::cout << "Heyyy" << std::endl;
return 0;
}
project/include/hey.h:
#include <iostream>
Now if I make a new directory project/build and cmake .. from that directory then make, the project compiles. However if I change hey.h in any way and try to make again, nothing will recompile. The depend.make file is consistent with this:
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.15
CMakeFiles/app.dir/src/hey.cpp.o: ../src/hey.cpp
But if I cmake . from the top directory project, everything goes well and the dependencies are all there:
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.15
CMakeFiles/app.dir/src/hey.cpp.o: src/hey.cpp
CMakeFiles/app.dir/src/hey.cpp.o: include/hey.h
I have found people having similar problems, but most are edge cases and cause just one header not to be included. My actual project doesn't find any header dependencies. /: I could very easily just be using CMake horribly wrong (I'm sorta new to it), but I looked around and everyone seems to do it differently.
If your build directory is a subdirectory of the source directory, then it's not really out-of-source, but a sort of hybrid. The recommended CMake approach is to do proper out-of-source builds where the source and binary directory are totally unrelated. This means they can be siblings or further removed, but neither is a descendant of the other.

Generating dll from an existing code on Windows using CMake and VS

I have downloaded an SDK written in C++ (OPC UA) that creates a .exe file on compiling with Visual Studio 2015. It has a bunch of CMake files. How could one see if it is possible to generate a .dll from such an SDK? Do the CMake files have this information or should there be any macros inside the headers I would have to search for ? The SDK has Visual Studio sample projects (.sln) that I am using to create .exe.
The CMakeLists.txt looks like this
project(uasdk)
cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
include(CMakeDependentOption)
include(MessageUtils)
display_project_header("true")
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src")
add_subdirectory(src)
endif ()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples")
add_subdirectory(examples)
endif ()
# set CMAKE_INSTALL_MESSAGE to LAZY by default to hide 'Up to date' output when building INSTALL target
if (NOT ${CMAKE_VERSION} VERSION_LESS "3.1")
set(CMAKE_INSTALL_MESSAGE LAZY CACHE STRING "")
set(CMAKE_INSTALL_MESSAGE_VALUES "ALWAYS;LAZY;NEVER")
set_property(CACHE CMAKE_INSTALL_MESSAGE PROPERTY STRINGS ${CMAKE_INSTALL_MESSAGE_VALUES})
endif ()
The questions that already have been asked regarding this topic are from the people who are writing their own code. I intend to use the code from the SDK. Apart from changing the CMAKE file to include the dll do I need to make changes in the source code as well?
It has a bunch of CMake files. How could one see if it is possible to generate a .dll from such an SDK? Do, the CMake files have this information or should there be any MACROS inside the headers I would have to search for ?
If the CMake project generates a library, then the statement add_library must appear somewhere. Note, however, that hierarchies of CMakeLists.txt files are possible, for example, the CMakeLists.txt you included adds two subdirectories. Consider the CMakeLists.txt files in there as well. Since an executable is generated, a call to add_executable must appear somewhere as well.
I intend to use the code from the SDK. Apart from changing the CMAKE file to include the dll do I need to make changes in the source code as well?
I am not familiar with this SDK, but I would guess that examples contains the sources for the executable and src contains the sources for a library. If you just want to try something out, you can modify the example code or add a new example. In this case, you only have to modify the CMakeLists.txt in the examples directory (i.e., add your new source code file).
If you want to use the SDK as external dependency, check whether there is a FindNameofmySDK.cmake included in the CMake modules list or whether there is a NameofmySDK-config.cmake somewhere in the SDK sources or your installation. In this case, you can create a CMake project for your application and use find_package to look for the SDK.

Cmake generated Eclipse Project - No Source

I am attempting to use CMake to generate eclipse project files. Although I am able to build successfully, I am unable to browse or edit the source in eclipse. This is an out of tree build, where my build directory is at the same level as my source directory. I am using the following command to generate the eclipse files:
cmake -G"Eclipse CDT4 - Unix Makefiles" -DBoost_NO_BOOST_CMAKE=ON -DBOOST_ROOT=/usr/local/lib -DCMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT=TRUE ../proc
The source directory has many different modules, but the top level CMakeLists file is essentially a bunch of add_subdirectory commands adding each module. Is this incorrect?
I create the eclipse project with the following command
cmake -G"Eclipse CDT4 - Unix Makefiles" -DCMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT=TRUE -DCMAKE_BUILD_TYPE=Debug $PROJECT_SRC_DIR
// $PROJECT_SRC_DIR is where my highest level CMakeLists.txt is
My CMakeLists.txt does basically look like this
cmake_minimum_required (VERSION 3.5.0)
cmake_policy(VERSION 3.5.0)
project(myproject VERSION 0.0.0)
# definition, find packages, compiler settings
add_subdirectory(src) # where my code is
# src contains further subdirectories with CMakeLists.txt and subproject definition therein.
This creates an eclipse project with a virtual directory [Source Directory] which points to the directory where Eclipse shows the content of the highest level CMakeLists.txt file with a project(...) command. Furthermore it shows [Subprojects] and [Targets] where the sources are shown for cmake subprojects (the directory content from the level of CMakeLists.txt where the subproject is defined) or targets (the list of file which are combined to an executable with the add_executable() command.
Do you have a project defined?
I've made the same experience, both for Eclipse and KDevelop. CMake prepares the configuration such that you can compile and debug from within those IDEs, but it doesn't actually add any information that would help the IDE to list source files for browsing them.