cmake generator expression for target architecture? - c++

Is there a modern approach to use target architecture within a condition for a generator expression in CMake? There are some answers that are somewhat outdated. I am looking for a modern or at least very robust and reliable custom script for using target architecture within a generator expression.
The docs do not seem to contain that kind of info.
One of the ideas for a workaround I see is to use $<<STRING:MY_DETECTED_ARCH:ARCH_ARM>:src_for_arm.cpp>

I checked a solution from this answer and it worked.
cmake_minimum_required(VERSION 3.14.2 FATAL_ERROR)
project(cmake_target_arch)
set(CMAKE_CXX_STANDARD 17)
include(TargetArch.cmake)
target_architecture(TARGET_ARCH)
message(STATUS "target_architecture: ${TARGET_ARCH}")
add_executable(cmake_target_arch
main.cpp
$<$<STREQUAL:"${TARGET_ARCH}","x86_64">:x86_64.cpp>
$<$<STREQUAL:"${TARGET_ARCH}","i386">:i386.cpp>
$<$<STREQUAL:"${TARGET_ARCH}","armv7">:armv7.cpp>
)
main.cpp
#include <iostream>
#include <string>
extern std::string hello_message();
int main()
{
std::cout << hello_message() << std::endl;
return 0;
}
i386.cpp
#include <string>
std::string hello_message()
{
return "Hello i386!";
}
Example output for i386 binary:
C:\Users\serge\dev\repos\cmake_target_arch\cmake-build-release-visual-studio-win32\cmake_target_arch.exe
Hello i386!
I guess one can come up with a CMake Macro to wrap strings comparison

Related

Catch2 test don't work when building application with CMake

I'm trying to test my program by using Catch2 tests and build the application using CMake. The program works and the application gets build when the Catch2 tests are not implemented.
Once I implemented the Catch2 tests, the application won't build anymore. I included #define CONFIG_CATCH_MAIN and #include "catch.hpp" into main.cpp.
But I always get something like this when I try to build the application with the tests included:
CMakeFiles\intent_recognition.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x43d): undefined reference to Catch::StringRef::StringRef(char const*)' CMakeFiles\intent_recognition.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x4b9): undefined reference to Catch::AssertionHandler::AssertionHandler(Catch::StringRef const&, Catch::SourceLineInfo const&, Catch::StringRef, Catch::ResultDisposition::Flags)'
I don't know what's going...
My main.cpp file looks like this:
#define CONFIG_CATCH_MAIN
#include "catch.hpp"
#include <iostream>
#include <string>
#include "Intent.h"
std::string func (std::string input)
{
std::cout << input << std::endl;
Intent IntentObj = Intent(input); // create Intent Object with input
IntentObj.analyze();
return IntentObj.result();
}
TEST_CASE("Get Weather", "[func]")
{
REQUIRE( func("What is the weather like today?") == "Intent: Get Weather" );
REQUIRE( func("Tell me what the weather is like.") == "Intent: Get Weather") ;
REQUIRE( func("I want to know the weather for tomorrow") == "Intent: Get Weather" );
REQUIRE( func("Can you tell me the weather for Wednesday?") == "Intent: Get Weather") ;
}
My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.20.2)
project(intent_recognition)
add_executable(intent_recognition main.cpp)
Having a quick look at the Catch2 tutorial you are at least missing the specification of the Catch2 library to link.
The tutorial states that you are at least need to have this code which your file above seems to miss:
find_package(Catch2 REQUIRED)
add_executable(tests test.cpp)
target_link_libraries(tests PRIVATE Catch2::Catch2)
The target_link_libraries... is missing in your example. That's probably why you are getting those linker errors.
The find_package will introduce the library under the name Catch2::Catch2 which you can then link to your test executable.
If the find_package command is not working in your setup, you may need to check how you did install Catch2.
I'm assuming that you want to use Catch2 as a header only library. The problem may be because you are including include/catch.hpp instead of single_include/catch2/catch.hpp.

How to use spdlog

I am new to c++, please don't grill too much. I am trying to use spdlog in C++ program and using CLion from Jetbrains.
Here is my screenshot but don't know what I am doing wrong. Please advise what I am doing wrong .
This is my main.cpp
#include <iostream>
#include "include/spdlog/spdlog.h"
int main() {
std::cout << "Hello, World!" << std::endl;
spdlog::info("hello world");
return 0;
}
This my CMakeList.txt
cmake_minimum_required(VERSION 3.17) project(Lesson01)
set(CMAKE_CXX_STANDARD 14)
add_executable(Lesson01 main.cpp) include_directories(spdlog)
Thanks
In the prototype you have created you have mentioned twice the keyword include
First after the # and a second one in between the quotation mark.
I have been looking in internet and basic writting of spdlog prototype is just. Here the link: https://github.com/gabime/spdlog
#include "spdlog/spdlog.h"
Test is without the second include in your code.
All the best
Mathieu
In your code you have #include "include/spdlog/spdlog.h", and going by the screenshot you linked, this include is found. However it is then complaining that spdlog.h tries to #include <spdlog/common.h>, and this file is not found.
Together this sounds like you are not setting the right include directory for the library, and just getting the first file right by over-specifying the path.
I would try to change include_directories(spdlog) to include_directories(include) (or possibly include_directories(include/spdlog), not entirely sure which folder is the base one with the library in). If you want, then you can also add all of those; I don't think anything will break from adding too many here, but it may impact compile speed so try to only keep the correct one.
Also, after making this change you may need to change your original include from #include "include/spdlog/spdlog.h" to #include "spdlog/spdlog.h".

CLion does not pick up (complex) pre-processor definitions

EDIT: Turns out the problem was the complexity of my project. Using the simple example below works as expected, but CLion cannot make sense of the complex dependencies of the project I'm working on. Using the linked question as a workaround for now.
I'm using CLion as my C++ IDE and I've added a simple pre-processor directive as a CMake option:
cmake_minimum_required(VERSION 3.10)
project(cmake_macro_test)
set(CMAKE_CXX_STANDARD 14)
option(SIMPLE_FLAG "My simple flag." ON)
if(SIMPLE_FLAG)
add_definitions(-DSIMPLE_FLAG) # Using CMake 3.10
endif()
add_executable(cmake_macro_test main.cpp)
Then my code has conditional compilation sections of the form:
#include <iostream>
int main() {
#ifdef SIMPLE_FLAG
// Do things
std::cout << "Hello, World!" << std::endl;
#else
// Do other things
std::cout << "Goodbye, World!" << std::endl;
#endif
return 0;
}
The flag is set to on by default, so I expected Clion would pick it up from the CMakeLists.txt and highlight the relevant parts of the code.
However, Clion views the //Do things part of the code as dead, and does provide syntax highlighting or auto-complete for that section, unless I actually re-define the flag in the same file which would defeat the purpose of the CMake option.
Is this a known issue with CLion? Is there some way to guarantee that pre-processor flags get picked up by the IDE?

C++ executable keep looking for ordinal entry point

I have a C++ application with the below source code:
#include <cstdint>
#include <iostream>
#include <vector>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;
int main(int argc, char** argv)
{
std::cout << "\nJust to be sure!" << std::endl;
// Making a connection to Mongo
mongocxx::instance instance{};
mongocxx::client client{mongocxx::uri{}};
// Access a database
mongocxx::database db = client["results"];
std::cout << "\ndone." << std::endl;
return 0;
}
I compile it using the below CMakeLists.txt file:
cmake_minimum_required(VERSION 3.7)
project(testing)
set(APP_SOURCES
test.cpp
)
link_directories(../../installed_mongocxx/lib)
add_executable(testapp ${APP_SOURCES})
target_link_libraries(testapp mongocxx bsoncxx)
target_include_directories(testapp PUBLIC
../../installed_mongocxx/include/mongocxx/v_noabi
../../installed_mongocxx/include/bsoncxx/v_noabi
E:/Softwares/Libraries/Boost/boost_1_64_0
)
install(TARGETS testapp
DESTINATION bin)
I compile the program using MSBuild on Windows 10 64bit without errors, and upon running it gives this error;
The ordinal 4694 could not be located in the dynamic library libmongoc-1.0.dll
Is there anything wrong with the C++ code or CMakeLists.txt that could be explanation of the error?
That's unlikely. The question is what .LIB file you're using to link the DLL. When you build a DLL, that also creates a small .LIB file. This is basically just a table of contents. If you mix the .LIB file from one build with the .DLL from another build, you may run into incompatibilities.
In this case, the .LIB file will be taken from ../../installed_mongocxx/lib, but the .DLL might not be. The DLL will be found at runtime, by Windows rules.
I notice that you've been asking a number of questions related to developing with mongocxx lately that all seem related. I encourage you to either ask a question on our mongodb-user Google Group or on our Jira project, which will make it easier for us to assist you in any follow-up questions you might have without needing to have a conversation in multiple places.
(Apologies for posting this as an answer rather than a comment; StackOverflow seems to have a length limit on comments, and I couldn't fit this in one)

Making allegro5 project with CLion

Few days ago I downloaded clion to make a school project in C++ and Allegro5. First I used allegro installed with homebrew but it wasn't working so I compiled it by myself. Since I've never worked with CMake before it took me some time to include the libs and compile the project but I managed to do it. The problem is that when I try to run it it throws an error:
dyld: Symbol not found: __al_mangled_main
Referenced from: /usr/local/lib/liballegro_main.5.0.dylib
Expected in: flat namespace
in /usr/local/lib/liballegro_main.5.0.dylib
My CMakeLists.txt:
cmake_minimum_required(VERSION 3.3)
project(arkanoid)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES classes/main.cpp classes/ball.cpp classes/ball.h classes/block.cpp classes/block.h)
add_executable(arkanoid ${SOURCE_FILES})
INCLUDE_DIRECTORIES( allegro/5.0.11/include )
LINK_DIRECTORIES( allegro/5.0.11/lib )
TARGET_LINK_LIBRARIES(arkanoid allegro_acodec
allegro_audio
allegro_color
allegro_dialog
allegro_image
allegro_main
allegro_memfile
allegro_physfs
allegro_primitives
allegro_ttf
allegro_font
allegro)
And for now my main.cpp looks like this:
#include <iostream>
#include <allegro5/allegro.h>
using namespace std;
int main() {
al_init();
return 0;
}
I'm trying to build this project on OSX. I've searched for 2 days for the solution to my problem but with no results. Not many people are using CLion and even less use it with allegro5. Could anyone have a clue what this error even mean?
Ok this one blew my mind. I don't know why I found solution only after asking on stackoverflow but I'm posting it for someone who might encounter simillar problem to mine. Change your main declaration from
int main()
to
int main(int argc, char **argv)
and that's it. Really.