We are trying to test for -pthread availability and set the flag in both CXXFLAGS and LDFLAGS. We don't want to use ax_pthread because it uses the wrong compiler and sets the wrong flags for a C++ project. And according to Significance of -pthread flag when compiling, -pthread is most portable, so we want to use it for both CXXFLAGS and LDFLAGS.
The scripting we added to configure.ac is:
AC_ARG_ENABLE(tls,
AS_HELP_STRING([--enable-tls], [enable thread storage (default is yes)]),
ac_enable_tls=$enableval,
ac_enable_tls=yes)
AM_CONDITIONAL(HAS_PTHREADS, test $ac_enable_tls = yes)
if test "$ac_enable_tls" = "yes"; then
SAVED_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="-pthread"
AC_MSG_CHECKING([for pthread support])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
[AC_MSG_RESULT([-pthread]) && AC_SUBST([AM_CXXFLAGS], ["-pthread"]) && AC_SUBST([AM_LDFLAGS], ["-pthread"])],
[AC_MSG_FAILURE(["--enable-tls=yes but pthreads are not available"])]
)
CXXFLAGS="$SAVED_CXXFLAGS"
fi
It results in:
./configure: line 16173: syntax error near unexpected token `&&'
./configure: line 16173: ` && AM_LDFLAGS="-pthread"'
autoreconf --warnings=all produces no warnings related to the test.
I'm guessing the trouble is trying to do three things in AC_COMPILE_IFELSE and [action-if-true]. The Autoconf AC_COMPILE_IFELSE docs don't tell us how to handle the situation and does not provide examples.
We want to perform three actions in [action-if-true]:
Print the message pthread
AM_CXXFLAGS += -pthread
AM_LDFLAGS += -pthread
How do I perform multiple actions in [action-if-true]?
It is not clear to me why you use the && shell operator; it will not work if the preceding m4 macro emits a newline. You should consider using ; or simply multiple lines.
It's also quite common in configure scripts just to set a shell variable in the AC_COMPILE_IFELSE actions, and check that afterwards. This avoids deeply nested shell code, and issues related to m4 quoting/macro expansion. Here is an example from glibc:
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <sys/sdt.h>
void foo (int i, void *p)
{
asm ("" STAP_PROBE_ASM (foo, bar, STAP_PROBE_ASM_TEMPLATE (2)) ""
:: STAP_PROBE_ASM_OPERANDS (2, i, p));
}]])], [libc_cv_sdt=yes], [libc_cv_sdt=no])
Related
I have a simple C++ program that calls some NASM code:
main.cpp:
#include <iostream>
extern "C" int foo();
int main() {
std::cout << "The result is: " << foo() << std::endl;
return 0;
}
foo.asm:
bits 64
global foo
section .text
foo:
mov rax, 123
inc rax
ret
I can compile everything with CMake
cmake_minimum_required (VERSION 3.15)
project (assembly-x64 LANGUAGES CXX ASM_NASM)
# old school CMAKE to handle NASM formats
if(WIN32)
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F cv8")
set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
elseif(APPLE)
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
else()
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
endif()
add_executable(assembly-x64)
target_compile_features(assembly-x64 PUBLIC cxx_std_17)
target_sources(assembly-x64 PRIVATE main.cpp foo.asm)
and I get the correct result. However, I'd like to be able to debug the assembly code just like I would the C++ code. I can create a breakpoint on the foo function (not using the GUI though), but it doesn't show me the corresponding source location when it pauses. Is there a way around that issue? I'd like to be able to watch registers, etc. Not sure if it's possible in VS code.
Short Answer: No. On linux, launching gdb from vs-code to debug asm code resulted in a quick crash. It doesn't even let you put breakpoints on asm code.
Read the longer answer in case you want to know about the alternatives.
I assume you are not using Linux, because I was unable to build the project on Linux with the cmake you provided. I had to add the following:
...
else()
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
# had to add this to build on linux
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> \
<FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
endif()
...
Ok, so now the project is built and running. However, the bad news is that I was unable to set up "debugging" environment with VS-Code. VS-Code doesn't really have good assembly support to begin with so I am not really surprised here. I tried to configure launch.json multiple times, but everytime I launch GDB, VS-Code crashes. This may or may not happen on Windows or Mac, so I can not answer for those platforms but I assume it will not work there.
I personally just use gdb from terminal directly because it is more powerful and easy to use once you figure it out. I will give you two work flows which you can use instead of Vs-code.
Use terminal
Build your executable
Next launch it using gdb like this:
gdb ./assembly-64 --tui
This will open gdb and bring you to the tui screen.
Lets assume we want to put a break point at foo, for this type:
b foo
Now our breakpoints are all set. We are ready to start our debugging session. Type:
run
It will go and break at foo.
But wait a minute, there are no registers, how should we see them? This is my favourite part about gdb. Type:
layout regs
And you will get a beautiful look window at top showing you all the registers. It will even highlight the registers as they change making it easy for you to monitor changes.
Other than this, Use n to step next, use si to step into. That's pretty much it for the basics. If you want to see the value at some memory location, or a register. Type:
print $rax
There's a lot more to this, but this will give you a quick start.
GUI
I was pleasantly surprised when I discovered that QtCreator can debug asm + cpp files very nicely. Just load up your cmake project and place your breakpoints. You can enable registers pane from Menu->Window->Views->Registers. Screenshot:
There are other guis(for gdb) out there, nemiver, ddd etc.
To debug C++ code and assembly code simultaneously,
you can do this with gobolt online: https://godbolt.org/
If you just want to write assembly and debug in vscode, let me tell you the method I just learned.
There is a great project for this.
https://github.com/newtonsart/vscode-assembly
You should also do these additionally.
32 Bit Support
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt install gcc-multilib
nostdlib gcc argument
(https://stackoverflow.com/a/32855954/6646336)
I used extra gcc argument for some errors.
# .vscode/tasks.json
# find gcc command and add <nostdlib> in two line
... gcc -nostdlib -m64...
... gcc -nostdlib -m32...
But still you can't set a breakpoint in (*.s, *.asm) file. vscode doesn't accept. You must enable in settings (keyword: debug.allowBreakpointsEverywhere = true)
And final step: Set a breakpoint and select your debugging type.
I am trying to figure out where a segmentation error is made. Thesame issue has been solved below for a different compiler. I am using CMake and am wondering if this compiler also has this function. CMake has no -g build option so I have no idea where to look.
Determine the line of code that causes a segmentation fault?
Here is also some info on what build options there are available for the debugger, maybe this points out what debugger I use since I have no idea.
/usr/bin/make: invalid option -- 'g'
Usage: make [options] [target] ...
Options:
-b, -m Ignored for compatibility.
-B, --always-make Unconditionally make all targets.
-C DIRECTORY, --directory=DIRECTORY
Change to DIRECTORY before doing anything.
-d Print lots of debugging information.
--debug[=FLAGS] Print various types of debugging information.
-e, --environment-overrides
Environment variables override makefiles.
--eval=STRING Evaluate STRING as a makefile statement.
-f FILE, --file=FILE, --makefile=FILE
Read FILE as a makefile.
-h, --help Print this message and exit.
-i, --ignore-errors Ignore errors from recipes.
-I DIRECTORY, --include-dir=DIRECTORY
Search DIRECTORY for included makefiles.
-j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.
-k, --keep-going Keep going when some targets can't be made.
-l [N], --load-average[=N], --max-load[=N]
Don't start multiple jobs unless load is below N.
-L, --check-symlink-times Use the latest mtime between symlinks and target.
-n, --just-print, --dry-run, --recon
Don't actually run any recipe; just print them.
-o FILE, --old-file=FILE, --assume-old=FILE
Consider FILE to be very old and don't remake it.
-O[TYPE], --output-sync[=TYPE]
Synchronize output of parallel jobs by TYPE.
-p, --print-data-base Print make's internal database.
-q, --question Run no recipe; exit status says if up to date.
-r, --no-builtin-rules Disable the built-in implicit rules.
-R, --no-builtin-variables Disable the built-in variable settings.
-s, --silent, --quiet Don't echo recipes.
-S, --no-keep-going, --stop
Turns off -k.
-t, --touch Touch targets instead of remaking them.
--trace Print tracing information.
-v, --version Print the version number of make and exit.
-w, --print-directory Print the current directory.
--no-print-directory Turn off -w, even if it was turned on implicitly.
-W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
Consider FILE to be infinitely new.
--warn-undefined-variables Warn when an undefined variable is referenced.
This program built for x86_64-pc-linux-gnu
Report bugs to <bug-make#gnu.org>
Is there a way to store the compile-time flags in the output binary when using clang?
For example after running:
clang -O3 -c main.c
The resulting main.o file should somewhere contain -O3.
gcc has -frecord-gcc-switches but I'm unable to find an equivalent for clang.
As ecatmur already has implied in the comments. This feature is currently not supported as documented in bug https://llvm.org/bugs/show_bug.cgi?id=16291 .
However as a work around while the feature is not available I would suggest having your build process define a macro inside the program using clang's -D argument. For example assuming you are invoking this from a bash script (adjust to whatever build tool you use):
CLANG_ARGS='-O3 -c main.c'
clang $CLANG_ARGS -D CLANG_ARGS="\"${CLANG_ARGS}\""
Then in your C or C++ programs you add something along the lines of:
const char clangArgs[] = CLANG_ARGS;
Which you can then retrieve using a debugger or some such or even could add some code to print it from your program when invoked with the -V or --version switch.
I have been trying to figure out a way to efficiently save a program, compile it and then run it in emacs. I have succeeded only partially in it.
I use smart-compile.el to make the job easier ( http://emacswiki.org/emacs/smart-compile.el ).
In that I have edited the C++ relevant portion to the below so that a program compiles and runs when I type M-x smart-compile RET followed by a RET.
(defcustom smart-compile-alist '(
;; g++-3 is used instead of g++ as the latter does not
;; work in Windows. Also '&& %n' is added to run the
;; compiled object if the compilation is successful
("\\.[Cc]+[Pp]*\\'" . "g++-3 -O2 -Wall -pedantic -Werror
-Wreturn-type %f -lm -o %n && %n")
..
To give an example, for a program sqrt.cpp, smart-compile auto generates following compile command:
g++-3 -O2 -Wall -pedantic -Werror -Wreturn-type sqrt.cpp -lm -o sqrt && sqrt
This works as long as my .cpp does not have any cin statement. For codes with cin statements, the console window shows the point where the user is supposed to input data. But I am unable to input anything and the Compilations status stays stuck at running.
In order to make the codes with user input work, I have to remove the && FILENAME part and then manually run ./FILENAME in emacs' eshell.
I am running emacs 24.3 in Windows. I have Cygwin installed and its bin added to the Windows environment variable Path (that's why g++-3 compilation works).
I would appreciate if someone could guide me how to save-compile-run user input required .cpp programs in emacs using a single command. Or at least how do I need to modify the above g++-3 command to make compile+run work for user input programs.
Thanks!
Emacs is programmable, so if something requires two steps, you can write a command that combines them. The simples code would look like this:
(defun save-compile-execute ()
(interactive)
(smart-compile 1) ; step 1: compile
(let ((exe (smart-compile-string "%n"))) ; step 2: run in *eshell*
(with-current-buffer "*eshell*"
(goto-char (point-max))
(insert exe)
(eshell-send-input))
(switch-to-buffer-other-window "*eshell*")))
The above code is simple, but it has one flaw: it doesn't wait for the compilation to finish. Since smart-compile doesn't support a flag for synchronous compilation, this must be achieved by temporarily hooking into the compilation-finish-functions, which makes the code more complex:
(require 'cl) ; for lexical-let
(defun do-execute (exe)
(with-current-buffer "*eshell*"
(goto-char (point-max))
(insert exe)
(eshell-send-input))
(switch-to-buffer-other-window "*eshell*"))
(defun save-compile-execute ()
(interactive)
(lexical-let ((exe (smart-compile-string "./%n"))
finish-callback)
;; when compilation is done, execute the program
;; and remove the callback from
;; compilation-finish-functions
(setq finish-callback
(lambda (buf msg)
(do-execute exe)
(setq compilation-finish-functions
(delq finish-callback compilation-finish-functions))))
(push finish-callback compilation-finish-functions))
(smart-compile 1))
The command can be run with M-x save-compile-execute RET or by binding it to a key.
suppose I have a long algorithm which I would like to be optionally verbose to debug it. So far I just added many if verbose then printf "whatever" all around the code but this forces the code to execute many useless tests if I don't want to have it in the verbose mode.
Is there a way to obtain a simple conditional compilation which can just ignore the printf lines if a flag is set?
Something that, for example, I can do in C by using #IFDEF DEBUG printf .. #ENDIF
What you are looking for can be found in camlp4. If you include the predefined macros then you can define flags on the command line using -D (and -U to undef them):
camlp4o pa_macro.cmo -DFOO file.ml
In code it looks like this:
let f x = IFDEF FOO THEN x + 1 ELSE x - 1 END;;