Cmake:build YASM source files - c++

I am using CMake 3.4.1 to generate and build Visual Studio 2013 64bit C++ solution.One of the project also contains .asm files which we compile in VisualStudio with yasm assembler as lib.How do I configure CMake to use yasm for those files?I haven't found any documentation with example of how to set it up.

Have a look a the following example:
cmake_minimum_required(VERSION 3.0)
project(YasmCmake)
find_program(YASM_EXE NAMES yasm)
add_custom_command(OUTPUT hello.o COMMAND ${YASM_EXE}
ARGS -f elf64 -o hello.o ${CMAKE_CURRENT_SOURCE_DIR}/hello.asm)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(Hello hello.o)
set_target_properties(Hello PROPERTIES LINKER_LANGUAGE CXX)
Of course you need to specify the flags for yasm depending on your platform.

Related

Setting up stdlib path while compiling with mingw on linux

I am trying to build my c++ CMake project on linux with mingw. CMakeLists.txt consists of (for understanding):
Setting up project info:
project(<project name> LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Setting up TRY_COMPILE target type:
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
Setting up boost:
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost COMPONENTS system program_options REQUIRED)
Including subdirectories in which there is nothing about mingw:
add_subdirectory(<some_subdirectory>)
...
At the time of build process I see the following compilation command in the log:
/usr/bin/x86_64-w64-mingw32-g++ -I/usr/include -I<user include 1> -I<user include 2> -O3 -DNDEBUG -std=gnu++20 -MD -MT CMakeFiles/common.dir/<source>.cpp.o -MF <source>.cpp.o.d -o <source>.cpp.o -c <project path>/<source>.cpp
After that goes a compiler error message with the following beginning:
[build] In file included from /usr/x86_64-w64-mingw32/include/c++/12.2.0/cstdint:41,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/bits/char_traits.h:731,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ios:40,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ostream:38,
[build] from <project path>/<source>.hpp:5,
[build] from <project path>/<source>.cpp:1:
[build] /usr/include/stdint.h:90:33: error: conflicting declaration «typedef long unsigned int uintptr_t»
[build] 90 | typedef unsigned long int uintptr_t;
[build] | ^~~~~~~~~
...
According to the internet this error message is connected with the different mingw standard library implementation.
I guess in a compile command there should somehow be -I/usr/x86_64-w64-mingw32/include on a place of -I/usr/include in a compilation command. If I am right there, the question is "How to change standard include directory for mingw build spicifically?". If I am not right there, then how to solve the problem with project building?
PS: The project builds using both clang++ and g++.
You probably need a toolchain file for your cross-compiler.
But I'd suggest using quasi-msys2, which takes care of this, and also gives you access to prebuilt libraries for MinGW (Boost in your case).
Install dependencies (this assumes Ubuntu, for other distributions adjust as needed)
# Install Clang and LLD
bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
# Install other dependencies
sudo apt install make wget tar zstd gpg wine
Install and run quasi-msys2:
git clone https://github.com/holyblackcat/quasi-msys2
cd quasi-msys2/
make install _gcc _boost
env/shell.sh
cd ..
Now build your repo:
git clone https://github.com/gogagum/archiever
cd archiever/
git checkout dev
git submodule update --init --recursive
cmake -B build/
cmake --build build/ -j4
I tried running the test app too:
cd build/numerical/
./numerical_encoder.exe --input-file Makefile # This uses Wine automatically

How to set debug flags correctly in a Cmake project compiled with Visual Studio

I have a C++ CMake project that is compiled both on Linux and Windows. On Windows, this is done via Visual Studio/MSVCC.
In CMAKE and in VS, the build is set up as Debug, but it seems that no debug symbols are ever being made in the VS build - so debugging is impossible.
When looking over the Detailed output for VS, I saw this:
cl : command line warning D9002: ignoring unknown option '-g'
That suggests to me that it doesn't recognize the -g flag like GCC/Clang do.
Here is the CMake arguments:
SET(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(BUILD_MODE Debug)
SET(CMAKE_CXX_FLAGS "-Wall")
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3")
How do I make this compatible with Visual Studio? I've tried looking all over, but most related posts seem to be about C#/.net, or much older versions of VS.
The project does use the QT library if that matters.
UPDATE:
It turns out BUILD_MODE was something added by someone else so that each sub-project would not individually need to be set to release or debug, we could just set it once in the root level Cmakelists. They did all actually use CMAKE_BUILD_TYPE as intended.
Also, the answers here were correct. Setting the CMAKE_CXX_FLAGS directly was wiping away the defaults, causing the Debug build to not have options like /Zi in MSVCC, preventing debug symbols and all debugging. It also introduced an unrecognized flag "-g" which MSVCC couldn't understand.
I completely remove the SET_CXX_FLAGS from every Cmakelists.txt in the project, and everything is working perfectly.
Should I need to add to them, I will use the _INIT option as suggested.
You have to compile with a different mode set with CMAKE_BUILD_TYPE as in
cmake -DCMAKE_BUILD_TYPE=DEBUG <sourcedir>
You never set those flags directly. If you want to add a new flag to a debug mode like for example a stack protector, you should use the *_INIT variables.
You can further distinguish which OS you are running with the UNIX, WIN32 and MSVC cmake boolean predefined constants:
if ( UNIX )
set( CMAKE_CXX_FLAGS_DEBUG_INIT "-fstack-protector" )
elseif( WIN32 )
set( CMAKE_CXX_FLAGS_DEBUG_INIT "/GS" )
endif()
There should be no need to define -O3 and -g explicitly in cmake. Setting those may prevent the code from working with other compilers, as you've seen. Those 2 options are the default anyways.
To build one of the configurations using unix makefiles you simply set the CMAKE_BUILD_TYPE cache variable during configuration:
(I'm assuming the generators mentioned are the default generators below.)
cmake -D CMAKE_BUILD_TYPE=Debug -S ... -B buildDir
or
cmake -D CMAKE_BUILD_TYPE=Debug -S ... -B buildDir
and to build the project you use
cmake --build buildDir
The visual studio is differnet insofar that the generated project covers all configurations at once. You specify the configuration to work with when building (or installing) the project instead:
cmake -A x64 -S ... -B buildDir
cmake --build buildDir --config Release
cmake --build buildDir --config Debug
Alternatively you can simply open the generated solution in the IDE.
cmake --open buildDir
For compiler specific flags you may need to make a case distinction:
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
add_compile_options(/Wall)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wall)
endif()

Missing CMAKE_ASM_NASM_COMPILER when compiling gRPC with MS visual studio

I am trying to build gRPC C++ (1.48.0) with Visual Studio 2022 on Windows 10. It's a CMake build (cmake 3.22.22011901-MSVC_2)
I was able to build everything else but am stuck at BoringSSL. The relevant CMakeList is trying to enable_language(ASM_NASM). Context below:
if(NOT OPENSSL_NO_ASM)
if(UNIX)
enable_language(ASM)
# Clang's integerated assembler does not support debug symbols.
if(NOT CMAKE_ASM_COMPILER_ID MATCHES "Clang")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -Wa,-g")
endif()
# CMake does not add -isysroot and -arch flags to assembly.
if(APPLE)
if(CMAKE_OSX_SYSROOT)
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"")
endif()
foreach(arch ${CMAKE_OSX_ARCHITECTURES})
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}")
endforeach()
endif()
else()
set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -gcv8")
enable_language(ASM_NASM)
endif()
endif()
It gives me CMake Error: "No CMAKE_ASM_NASM_COMPILER could be found."
I don't know enough about compilers / assemblers, and why boringSSL would need a specific one (which none of the other modules needed including gRPC).
What is the recommended way to fix this?
To answer at least some of my questions for my future self, and others who are at a similar point in the journey.
NASM is an assembly compiler (assembler). BoringSSL has some assembly language code, which is why it needs an assembly compiler (and gRPC or other modules don't). I'll let someone else opine on why NASM and not some other assembler.
To fix the issue, you have to download/install the relevant NASM executable from here. I found it easier to download the exe, place it in a folder, add that folder to the PATH and set another env variable ASM_NASM with the name of nasm.exe.
Once I did that, boringSSL and the whole gRPC compiled quite smoothly.

How to make cmake support gcov [duplicate]

I'm on a linux machine, trying to build a project using cmake that does out of source builds. For code coverage, I looked into gcov and followed a simple tutorial that generate appropriate files for a sample helloWorld.cpp program. The only requirement were to compile with -fprofile-arcs -ftest-coverage flags & link with -lgcov flag, which can be done altogether with -coverage flag.
Now here comes the tricky part. I have a CMakeLists.txt wit contents as shown below:
cmake_minimum_required (VERSION 2.8)
project (SomeName)
SET(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS "-coverage -lgcov")
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories(include)
set(CATCH_HEADER_PATH ${PROJECT_SOURCE_DIR}/test/catch.hpp)
add_executable(runTest ${PROJECT_SOURCE_DIR}/test/test.cpp ${CATCH_HEADER_PATH})
So I've included appropriate compile time flags as well as linker flags too and appended them correctly. Another thing to note is set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) line which says that executables will be generated inside bin directory.
Now everything works as intended except that coverage files aren't generated properly. I follow these steps :
mkdir build && cd build
cmake ..
make -j4
./bin/runTest
and no other file is generated inside bin folder. However on more inspection I found out that there is another location build/CMakeFiles/runTest.dir/test where test.cpp.o resides initially and after the final step ./bin/runTest, two new files - test.cpp.gcda & test.cpp.gcno are generated.
I've already tried copying test/test.cpp to build/CMakeFiles/runTest.dir/test and running gcov test.cpp but it fails stating - test.gcno:cannot open notes file
A mismatch in gcov and gcc version was making this happen. gcc symlink /usr/bin/gcc was set to newest gcc, same for g++ but gcov in $PATH was still pointing to older version of gcov.

CMake - "Undefined symbols for architecture x86_64" using glad/GLFW/Catch2 [duplicate]

Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1