Страницы

Поиск по вопросам

Показаны сообщения с ярлыком компиляция. Показать все сообщения
Показаны сообщения с ярлыком компиляция. Показать все сообщения

воскресенье, 15 марта 2020 г.

Как создать ассерт времени компиляции(аналог static_assert) в C?

#c #компиляция #отладка


В некоторых ситуациях для облегчения обнаружения и исправления ошибок в программе
может потребоваться сделать несколько утверждений об истинности/ложности какого-то
выражения, не только во время выполнения, но и во время компиляции. 

В С++ для этого применяется static_assert. 

Примеры:

Утверждение о версии подключенной библиотеки: 

#include "SomeLibrary.h"

static_assert(SomeLibrary::Version > 2, "Старые версии SomeLibrary не поддерживаются,
используйте новые.");


Утверждение о количестве бит в unsigned int:

static_assert(sizeof(unsigned int) * CHAR_BIT == 32, "Компиляция на неподдерживаемой
платформе");


Как создавать подобные утверждения в обычном C, где есть только ассерты времени выполнения
в виде макроса из assert.h?
    


Ответы

Ответ 1



Для этого можно использовать любую ошибку компиляции, например структуры с битовыми полями отрицательного размера: #define CT_ASSERT_NULL(x) ((void *)sizeof(struct { int:-!!(x); })) #define CT_ASSERT_ZERO(x) sizeof(struct { int: -!!(x); })) #define CT_ERROR sizeof(struct { int: -1;}); Кроме того такая функция добавлена, начиная со стандарта C11 и в gcc-4.6 теперь можно делать так: _Static_assert( sizeof(int) == sizeof(long int), "Error!");

пятница, 13 марта 2020 г.

Каким образом определяется необходимость вызова деструктора для объектов с автоматической продолжительностью хранения?

#cpp #компиляция #cpp11


Рассмотрим простой пример:

void f();
void f_exception();

class A {
  private:
    std::string m_name;

  public:
    A(std::string name) : m_name(name) {/*NOP*/}

    ~A() {
        std::cout << "Destroy object \"" << m_name << "\"." << std::endl;
    }
};

int main() {
    f();

    try {
        f_exception();
    } catch (const std::runtime_error& e) {
        std::cout << "Catch exception." << std::endl;
    }

    return 0;
}

void f() {
    A a("a");

    std::cout << "Before block" << std::endl;
    {
        A b("b");
    }
    std::cout << "After block." << std::endl;
}

void f_exception() {
    A c("c");

    std::cout << "Before block" << std::endl;
    {
        A d("d");
        throw std::runtime_error("exception");
    }
}


Стандарт гарантирует, что объекты с automatic storage duration будут удалены при
выходе из блока кода, в котором они объявлены. Я предположил, что при компиляции создаются
соответствующие инструкции, но ведь выход из блока может быть осуществлен и ранее (при
использовании исключений, оператора goto, оператора return и т.д.). Т.е. необходимость
вызова деструктора должна определяться динамически при выполнении программы. Это и
подтверждает приведенный выше пример (вывод в консоль):


  Before block
  Destroy object "b".
  After block.
  Destroy object "a".
  Before block
  Destroy object "d".
  Destroy object "c".
  Catch exception.


Собственно интересует, как это реализуется во время выполнения программы.
    


Ответы

Ответ 1



Почему динамически? Все инструкции известны компилятору, а это значит что он для всякой инструкции, которая ведёт к «покиданию» текущей области может добавить вызов деструктора(ов). Здесь нет никакой магии, и не требуется анализа рантайма — просто работа для компилятора. Кстати, вот это: Стандарт гарантирует, что объекты с automatic storage duration будут удалены при выходе из блока кода, в котором они объявлены. Не совсем правда. Попробуйте написать exit(0) в коде — Вы не увидите ни одного деструктора или попробуйте добавить noexcept к функции f_exception() — будет похожий результат.

воскресенье, 8 марта 2020 г.

Java. Создание пустого .txt на рабочем столе - ошибка компиляции [закрыт]

#java #компиляция


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Изучаю Java с нуля, есть вопрос.

Почему этот код, который должен создать пустой текстовый документ на рабочем столе,
при попытке скомпилировать выдает ошибку?

package filecreator;

import java.io.File;
import java.io.IOException;

public class FileCreator {

    public static void main(String[] args) {

        String fileName = "My File.txt";
        String filePath = "/Users/Donrumata/Desktop/";

        File myFile = new File(filePath + "/" + fileName);

        try {
            myFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    


Ответы

Ответ 1



Если вы привели весь код в классе, то в конце не хватает точки с запятой и закрывающей фигурной скобки после нее. Пока писал ответ, увидел ответ про лишний слэш. Опытным путем выяснил, что их количество в пути не играет роли. Следующий код создаст файл в той же дирректории, что и код из вопроса: String fileName = "My File.txt"; String filePath = "/Users/Documents/Desktop/"; File myFile = new File(filePath + "//////" + fileName);

суббота, 22 февраля 2020 г.

Дебаг исходного кода сборок в C# без компиляции сборок в dll

#c_sharp #компиляция


У меня есть несколько компонентов(исходный код библиотеки).

Если скомпилировать все сборки, то получится несколько библиотек dll
Добавив которые в references можно работать с библиотекой.

Как добавить эти сборки в проект, чтобы их не компилировать, а работать с ними как
с исходным кодом и можно было дебажить?

Например:


Library.Assembly1
Library.Assembly2
Library.Assembly3


Все они как разные проекты в студии идут.

После билда получится 3 dll с которыми потом можно работать.

А мне нужно, чтобы эти сборки были в моём проекте и можно было дебажить исходный код.
    


Ответы

Ответ 1



Добавляешь необходимые проекты в одно решение (Solution). Добавляешь ссылки на свои проекты, там где требуется. ПКМ по проекту - добавить ссылку. Теперь можно дебажить свои сборки. Порядок сборки можно изменить в зависимостях проектов.

Ответ 2



Если менять исходный код сборок и компилировать их не требуется, тогда нет необходимости добавлять их проекты в решение. Visual Studio позволяет отлаживать исходный код сборки, если она сможет определить путь к соответствующему PDB файлу этой сборки (он содержит отладочную информацию), а так же путь к исходному коду сборки. Файл PDB создается при компиляции сборки с ключем \debug в той же самой папке, где создается файл сборки (DLL). По умолчанию, компоновщик помещает полный путь и имя связанного PDB-файла в сборку (DLL). При отладке, Visual Studio проверяет, существует ли файл символов в расположении, которое задано в сборке. Но если сборка была скомпилирована не на этом компьютере, то указанного расположения либо не существует, либо PDB файлы находятся не там. В этом случае, путь к PDB файлам можно прописать в настройках (Сервис=>Параметры=>Отладка=>Символы или Tools=>Options=>Debugging=>Symbols). Кроме отладочной информации, PDB файл содержит также сведения о местонахождении исходного кода сборки. Если это местонахождение существует на компьютере, то Visual Studio автоматически открывает соответствующий файл при отладке. Когда отладчик приостанавливает выполнение в месте, для которого отсутствует исходный файл, он отображает страницу Нет исходного кода или Символы не загружены, которая может помочь найти исходный файл. Это сжатый пересказ инструкции описанной в MSDN: Указание файлов символов (.pdb) и файлов с исходным кодом в отладчике Visual Studio. При отладке с помощью PDB файлов, могут возникать трудности с чтением локальных переменных в отладчике. Для избежания этих трудностей, можно сделать две вещи. Отключить главный процесс Visual Studio (Visual Studio Hosting Process). Откройте проект исполняемого файла в Visual Studio. Проекты, которые не создают исполняемые файлы (например, проекты библиотеки классов или службы) не имеют этот параметр. В меню Проект (Project) выберите пункт Свойства (Properties). Перейдите на вкладку Отладка (Debugging). Снимите флажок Разрешить главный процесс Visual Studio (Enable Visual Studio Hosting Process) Подробнее о побочных эффектах связанных с отключением этой опции написано здесь: Практическое руководство. Отключение главного процесса Отключить JIT оптимизацию кода, таким образом избегая несоответствия его источникам, что сильно затрудняет отладку. Это можно сделать при помощи специального ключа в реестре (что влияет на все приложения), но лучше всего запустить Visual Studio из командной строки установив специальную переменную окружения. set COMPLUS_ZapDisable=1 cd /d "%ProgramFiles%\Microsoft Visual Studio 14.0\Common7\ide\" start devenv.exe exit Путь в скрипте выше указывает на Visual Studio 2015. Для другой версии необходимо указать соответствующий номер: VS 2013 - 12.0, VS 2012 - 11.0, VS 2010 - 10.0. Этот трюк позаимствован из блога, в котором он подробно описан: How to disable optimizations when debugging Reference Source.

воскресенье, 16 февраля 2020 г.

Дебаг исходного кода сборок в C# без компиляции сборок в dll

#c_sharp #компиляция


У меня есть несколько компонентов(исходный код библиотеки).

Если скомпилировать все сборки, то получится несколько библиотек dll
Добавив которые в references можно работать с библиотекой.

Как добавить эти сборки в проект, чтобы их не компилировать, а работать с ними как
с исходным кодом и можно было дебажить?

Например:


Library.Assembly1
Library.Assembly2
Library.Assembly3


Все они как разные проекты в студии идут.

После билда получится 3 dll с которыми потом можно работать.

А мне нужно, чтобы эти сборки были в моём проекте и можно было дебажить исходный код.
    


Ответы

Ответ 1



Добавляешь необходимые проекты в одно решение (Solution). Добавляешь ссылки на свои проекты, там где требуется. ПКМ по проекту - добавить ссылку. Теперь можно дебажить свои сборки. Порядок сборки можно изменить в зависимостях проектов.

Ответ 2



Если менять исходный код сборок и компилировать их не требуется, тогда нет необходимости добавлять их проекты в решение. Visual Studio позволяет отлаживать исходный код сборки, если она сможет определить путь к соответствующему PDB файлу этой сборки (он содержит отладочную информацию), а так же путь к исходному коду сборки. Файл PDB создается при компиляции сборки с ключем \debug в той же самой папке, где создается файл сборки (DLL). По умолчанию, компоновщик помещает полный путь и имя связанного PDB-файла в сборку (DLL). При отладке, Visual Studio проверяет, существует ли файл символов в расположении, которое задано в сборке. Но если сборка была скомпилирована не на этом компьютере, то указанного расположения либо не существует, либо PDB файлы находятся не там. В этом случае, путь к PDB файлам можно прописать в настройках (Сервис=>Параметры=>Отладка=>Символы или Tools=>Options=>Debugging=>Symbols). Кроме отладочной информации, PDB файл содержит также сведения о местонахождении исходного кода сборки. Если это местонахождение существует на компьютере, то Visual Studio автоматически открывает соответствующий файл при отладке. Когда отладчик приостанавливает выполнение в месте, для которого отсутствует исходный файл, он отображает страницу Нет исходного кода или Символы не загружены, которая может помочь найти исходный файл. Это сжатый пересказ инструкции описанной в MSDN: Указание файлов символов (.pdb) и файлов с исходным кодом в отладчике Visual Studio. При отладке с помощью PDB файлов, могут возникать трудности с чтением локальных переменных в отладчике. Для избежания этих трудностей, можно сделать две вещи. Отключить главный процесс Visual Studio (Visual Studio Hosting Process). Откройте проект исполняемого файла в Visual Studio. Проекты, которые не создают исполняемые файлы (например, проекты библиотеки классов или службы) не имеют этот параметр. В меню Проект (Project) выберите пункт Свойства (Properties). Перейдите на вкладку Отладка (Debugging). Снимите флажок Разрешить главный процесс Visual Studio (Enable Visual Studio Hosting Process) Подробнее о побочных эффектах связанных с отключением этой опции написано здесь: Практическое руководство. Отключение главного процесса Отключить JIT оптимизацию кода, таким образом избегая несоответствия его источникам, что сильно затрудняет отладку. Это можно сделать при помощи специального ключа в реестре (что влияет на все приложения), но лучше всего запустить Visual Studio из командной строки установив специальную переменную окружения. set COMPLUS_ZapDisable=1 cd /d "%ProgramFiles%\Microsoft Visual Studio 14.0\Common7\ide\" start devenv.exe exit Путь в скрипте выше указывает на Visual Studio 2015. Для другой версии необходимо указать соответствующий номер: VS 2013 - 12.0, VS 2012 - 11.0, VS 2010 - 10.0. Этот трюк позаимствован из блога, в котором он подробно описан: How to disable optimizations when debugging Reference Source.

пятница, 14 февраля 2020 г.

Где я могу задать ключи для компиляции в Visual Studio?

#c_sharp #visual_studio #компиляция #компилятор


Прочитал на хабре, что можно уменьшить время компиляции, за счет ключа параллельной
компиляции /MP. В настройках не вижу таких пунктов. Поиск в гугле не дал результатов.
Используется Visual Studio 2017.
UPD. В частности интересует C# под Windows Forms.
    


Ответы

Ответ 1



Параметр /MP служит для ускорения компиляции нативных проектов (C++ или C), в C# проектах этот параметр не поддерживается, да и в целом не нужен. Документация: ссылка.

четверг, 13 февраля 2020 г.

Работа компилятора: формулировка некоторых понятий

#компиляция #компилятор


У меня не совсем качественная подготовка по английскому языку, да и hashcode.ru не
являет сервисом, который помогает переводить что-то, но меня в первую очередь интересует
грамотная формулировка понятий.
Вот есть абзац:

The lexical parser analyses the source code and breaks it up into lexical tokens,
removing on the way all comments and white-spaces between the tokens. The syntax parser
groups the tokens into syntax constructs, and builds an equivalent    internal    abstract
   syntax    data    structure. The semantic analyser walks through the abstract syntax
and determines whether all semantic rules have been obeyed. The  code  generator, 
based  on the abstract  syntax  once again, produces the final equivalent code.

Я его перевёл вот так:

Лексический парсер анализирует исходный код, разбивает его на так называемые лексические
«токены», удаляет все комментарии и лишние пробелы. Синтаксический парсер группирует
эти полученные «токены» в синтаксические конструкции и создает эквивалентные внутренние
абстрактные синтаксические структуры данных. Семантический анализ снова «проходит»
по абстрактным синтаксическим структурам и проверяет соблюдение всех правил. Генератор
кода, снова основываясь на абстрактных синтаксических структурах, создаёт конечный
эквивалентный код.

У меня вопрос вот: что значит в данном контексте "abstract syntax", это одно и то
же, что и  "an equivalent   internal   abstract   syntax   data   structure", т.е.
это синонимы и что это означает в реальности?    


Ответы

Ответ 1



Я бы сказал, что здесь понятия abstract syntax и abstract syntax data structure коррелируют, однако, обозначают разные вещи. Abstract syntax - некое описание используемого парсером грамматики (которое, как пример, может быть задано в стандартных LL, LR формах, или, например, в форме БНФ). Abstract syntax data structure - структура данных, необходимая для поддержания набора правил грамматики. Примером такой структуры может являться тривиальное дерево разбора, разумеется, что в случае более сложных парсеров, сложность используемых структур возрастает. Если интересно, то могу порекомендовать неплохой референс по теории компиляторов вообще, там можно найти большое количество примеров и более формальные определения соответсвующих понятий.

Как задать в переменную текущую дату и время при компиляции?

#java #компиляция


В качестве билда программы использую текущую дату и время в специфичном формате на
момент компиляции.

private final String VERSION_REVISION= "20160216_1708";


Как задать переменную что бы при компиляции можно было вставить туда текущую дату
и время. 
    


Ответы

Ответ 1



Пример кода, если использовать File().lastModified(): private final String VERSION_REVISION = getClassBuildTime(); private static Date getClassBuildTime() { Date d = null; Class currentClass = new Object(){}.getClass().getEnclosingClass(); URL resource = currentClass.getResource(currentClass.getSimpleName() + ".class"); if (resource != null) { if (resource.getProtocol().equals("file")) { try { d = new Date(new File(resource.toURI()).lastModified()); } catch (URISyntaxException ignored) { } } else if (resource.getProtocol().equals("jar")) { String path = resource.getPath(); d = new Date( new File(path.substring(5, path.indexOf("!"))).lastModified()); } else if (resource.getProtocol().equals("zip")) { String path = resource.getPath(); File jarFileOnDisk = new File(path.substring(0, path.indexOf("!"))); try (JarFile jf = new JarFile (jarFileOnDisk)) { ZipEntry ze = jf.getEntry (path.substring(path.indexOf("!") + 2)); long zeTimeLong = ze.getTime (); Date zeTimeDate = new Date(zeTimeLong); d = zeTimeDate; } catch (IOException|RuntimeException ignored) { } } } return d; } Как я уже говорил, можете ещё попробовать записать в манифест атрибут Build-Date, а потом считать его: public void readManifest() throws IOException { URL res = getClass().getResource(getClass().getSimpleName() + ".class"); JarURLConnection conn = (JarURLConnection) res.openConnection(); Manifest mf = conn.getManifest(); Attributes atts = mf.getMainAttributes(); System.out.println(atts.getValue("Build-Date")); } Источник кода

Ответ 2



Простой пример с использованием Maven. На тот случай, если не строго обязательно зашивать версию в class файле. Версия задается на этапе сборки, и хранится в property внутри JAR. Проект ├───src │ ├───main │ │ ├───java │ │ │ └───prop │ │ │ Main.java │ │ └───resources │ │ application.properties application.properties version = ${version} pom.xml ${maven.build.timestamp} yyyy-MM-dd HH:mm src/main/resources true // .. Код public static void main(String[] args) { try ( final InputStream stream = Main.class.getClassLoader().getResourceAsStream("application.properties") ) { final Properties properties = new Properties(); properties.load(stream); System.out.println(properties.getProperty("version")); } catch (IOException e) { e.printStackTrace(); } }

среда, 12 февраля 2020 г.

Как в Intellj Idea подключить к проекту файлы class?

#java #intellij_idea #компиляция


Есть папка и в ней лежат уже скомпилированные классы. Как из них вызвать методы?
Закинул в каталог проекта, и написал 

import javax.help;


В результате Error:(15, 18) java: package javax.help does not exist.
    


Ответы

Ответ 1



Пример из консоли Структура каталогов: C:\dev\ TestImp.class c:\dev\mypack\ Test.class Код класса Test: package mypack; public class Test { public Test() { System.out.println("I live!"); } } Код класса TestImp: import mypack.Test; public class TestImp { public static void main(String[] args) { Test t = new Test(); } } В консоли переходим в каталог c:\dev\ и выполняем: java TestImp В консоль выводится: I live! UPD: Что касается Intellj Idea - вам требуется запаковать ваши файлы классов в jar командой jar cf test.jar Test1.class После этого импортируете jar в проект следующим образом: Структура проекта (CTRL + SHIFT + ALT + S on Windows/Linux, ⌘ + ; on Mac OS X) Modules на левой панели. Вкладка Dependencies '+' → JARs or directories UPD2: Intellij IDEA позволяет добавлять не только JAR'ы, но и каталоги с классами. Делается полностью аналогично написанному выше, только выбирается каталог с классами. После выбора откроется диалог, в котором можно исключить какие либо подкаталоги выбранного каталога.

суббота, 8 февраля 2020 г.

Компоновка, компиляция [закрыт]

#c #компиляция


        
             
                
                    
                        
                            Закрыт. Данный вопрос необходимо конкретизировать. Ответы
на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он был сосредоточен только на одной проблеме, отредактировав его.
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Можно объяснить, что такое препроцессор, компиляция, линковщик, как происходит сборка
файлов, пошаговые этапы?
    


Ответы

Ответ 1



Очень коротко. Препроцессор делает текстовые преобразования исходного .c файла (в т.ч. вставляет текст из #include) и результат передается на вход компилятору. Компилятор преобразует свой вход (программу на языке Си) в объектный файл (.o), который содержит константы, машинные команды и таблицу внешних символов (переменные и функции к которым обращается этот исходный код, но которые в нем не определены). Линковщик (редактор связей) на основе результатов компилятора (.o файлы) и известных ему библиотек (по сути это те же .о файлы, но специальным образом скомпонованные) создает исполняемый файл (в винде .exe) или разделяемую библиотеку (в винде .dll, в *nix .so). При этом происходит так называемое разрешение внешних имен, т.е. ранее известные только по именам функции и внешние переменные обретают адреса и в соответствии с этим меняется код объектного файла (сами .o, естественно, не изменяются). Системный загрузчик (часть ядра ОС) читает исполняемый файл в память и проводит окончательную настройку адресов (если требуется), а также связывает этот машинный код с кодом в системных разделяемых библиотеках (они общие для всех программ в системе и их часто используемые части обычно уже подкачаны в память к моменту загрузки Вашей программы). Вопросы виртуальной памяти (преобразование виртуальных адресов в физические) я тут не рассматривал.

среда, 5 февраля 2020 г.

Зачем нужна условная компиляция?

#cpp #компиляция


Она позволит включать различные части кода программы во время компиляции, отладки
или непосредственно выполнения?
    


Ответы

Ответ 1



Условная компиляция позволяет включать в программу различные части кода в зависимости от: Платформы (Windows, Android, Linux, x86,x64, etc.); Назначения сборки (debug, release); Версии самого ПО или его компонентов; Других факторов обусловленных спецификой разрабатываемого ПО или выполняемых задач. В основном использую в первых двух случаях.

суббота, 1 февраля 2020 г.

Компиляция php

#php #компиляция


Вопрос можно ли скомпилировать php для работы на сервере (т.е. не интерпретировать
через движок php, а скомпилировать и вызывать)?
Дело в том что нашел на хабре статью, сравнивающую twig со smarty и там была табличка
с графой компиляция. Вот я не понял как они компилировали и имелось ли ввиду компиляция
php скрипта или шаблона в быстрый php скрипт (как это делает смарти).
Также заинтересовал возможность компилирования, чтобы продавать под ключ сайты.    


Ответы

Ответ 1



Имеется еще такая штука, как говорит википедия Zend Guard (ранее назывался Zend Encoder) — позволяет закодировать скрипт в байт-код, который потом можно использовать точно также как и обычный, за исключением возможности его отредактировать. Предназначено для защиты интересов и интеллектуальной собственности разработчика. Для работы таких скриптов обязательно нужен Zend Optimizer. Zend SafeGuard Suite — то же самое, что и Zend Encoder, только дополнен Zend License Manager, который позволяет создавать лицензии к кодируемым скриптам. Можно задать время (expire) и условия (привязка к IP, MAC, etc) работы. Удобно для Shareware-версий или демоверсий. Zend Optimizer — единственное приложение, распространяемое бесплатно. Являет собой серверный модуль для запуска закодированных с помощью Zend Encoder и Zend SafeGuard Suite скриптов, а также немного их ускоряющий (заявлено, что до 40 %). Подробности о разработках Zend найдете здесь. Цены, правда, запредельные, но как вариант я бы рассмотрел.

Ответ 2



В Facebook компилируют PHP в C++, используя HipHop. Вроде как, это наиболее шустрое, из имеющихся на данное время решений. Правда, не поддерживаются некоторые конструкции, например, eval(). По сравнению с PHP+Apache (mod_php), по заявлениям Facebook, экономится около 50% процессорного времени при отдаче веб-интерфейса, и около 30% при отдаче API. Еще был (нынче, можно сказать, помер от нехватки интереса) проект Raven от Roadsend, который компилировал в байт-код LLVM, со всеми вытекающими плюсами оной (переносимость между платформами/архитектурами, JIT и т.д.)

Ответ 3



Например - http://www.phpcompiler.org/ со странички phc for PHP programmers (See Manual): Compile PHP source into an (optimized) executable (supports entire PHP standard library). Compile a web application into an (optimized) extension (supports entire PHP standard library). Pretty-print PHP code. Obfuscate PHP code (--obfuscate flag - experimental). Combine many php scripts into a single file (--include flag - experimental). Optimize PHP code using classical compiler optimizations (in the dataflow branch - very experimental). компиляция php в (оптимизированный) исполняемый файл (с полной поддержкой стандартных библитек php) компиляция web-приложения в (оптимизированное) расширение (с полной поддержкой стандартных библитек php) обфускация PHP кода (изменение кода таким образом, чтобы затруднить его анализ и понимание) (экспериментальная версия) комбинирование нескольких php скриптов в один файл оптимизация php скриптов с использованием классических методов оптимизации (экспериментальная версия)

Ответ 4



Компиляция это не про php - Это интерпретируемый язык. Его код на сервере как раз и интерпретируется. twig со smarty Сравнивали тк они действительно нужнаются в компиляции (и скорость их обработки разная). И php кстате тоже является шаблонизатором, причем нативным. smfrty и еже с ними призваны углубить (усугубить) принцип MVC, что бы при выводе html кода не возникало соблазна модифицировать данные

пятница, 24 января 2020 г.

Configure: передача параметра и значение параметра по умолчанию

#c #компиляция #autoconf #autotools


Необходимо, чтобы в файле configure.ac была переменная "XXX". При этом, необходимо,
чтобы у нее было значение по умолчанию и возможность установить значение, при вызове
./configure. Т.е., чтобы можно было сделать что-то такое:
если вызывается ./configure
используется значение XXX по умолчанию (пусть будет "ааа")
если вызывается ./configure XXX="bbb"
значение XXX становится "bbb"
Никак не пойму, как для этого необходимо описать файл configure.ac
    


Ответы

Ответ 1



FOO=${FOO:-foo} AC_DEFINE_UNQUOTED([FOO_MACRO],[$FOO],["Desriprion"]) Судя по всему всё что не раскрывается макросом из configure.ac просто поадает в скрипт ./configure. Поэтому для установки переменных можно использовать обычный синтаксис POSIX sh. Можно также задавать значение прямо в макросе, хотя в этом случае есть свои подводные камни с интерпретацией кавычек. AC_DEFINE_UNQUOTED([FOO_MACRO],[${FOO:-foo}],["Desriprion"]) Также ИМХО хорошим тоном будет объявить эту переменную AC_ARG_VAR.

воскресенье, 12 января 2020 г.

Раздельная компиляция и рефакторинг

#cpp #компиляция #cpp11 #рефакторинг


Например, у меня есть несколько файлов (все по правилу odr).

SuperClass.h SuperClass.сpp

SubClass.h SubClass.cpp (наследуется от SuperClass)

main.cpp

Скомпилировал, получил SuperClass.o, SubClass.o, main.o и все объединил компоновщиком
в programm - все хорошо работает.

Потом решил переделать приватную реализацию SuperClass, добавить некоторые публичные
методы, удалить приватные поля и добавить еще один класс SuperSuperClass, от которого
теперь наследуется SuperClass. 

Скомпилировал SuperSuperClass SuperClass и объединил компоновщиком со всеми остальными
- все хорошо работает, хоть я изменил иерархию наследования, внес изменения, но не
трогал имена функций которые вызываются в остальных файлах. Но правило ODR нарушено?
Я не перекомпилировал другие файлы, в которых осталось старое определение SuperClass
и нет никакой информации об обновлении иерархии наследования.

А вдруг я захочу добавить в SuperSuperClass виртуальну функцию? При каких случаях
нужна перекомпиляция остальных файлов? 
    


Ответы

Ответ 1



На самом деле всё просто. Если вы поменяли header — все зависимые от него файлы (то есть, все cpp-файлы, которые включают его прямо или косвенно) должны быть перекомпилированы. Если вы поменяли cpp-файл, то по идее только его и надо перекомпилировать. (Если вы, разумеется, не #include-ите его в другие файлы.) Если вы пользуетесь makefile'ом, зависимости нужно прописать там, тогда повторная компиляция произойдёт автоматически, соберутся лишь нужные таргеты. Если ваш проект слишком большой для ручной расстановки зависимостей, вам поможет утилита makedepend, которая автоматизирует этот процесс.

Ответ 2



Правило ODR тут не причём вообще . То, что у Вас всё работает правильно говорит о том, что Вам Повезло. Вы имеете неопределённое поведение, но так уж случилось, что всё работает правильно. Опять повезло, но уже с компоновщиком. Компоновщик очень умён, и в o файлах, до последней сборки содержатся лишь ссылки, которые потом очень умно заменяются. Общее правило таково: если хоть что-то в заголовке было изменено(в определении класса, даже если это просто порядок функций), все эти изменения, должны быть донесены до всех объектных файлов. В противном случае UB(неопределённое поведение) Не прав я касательно ODR оказался, правило как раз в этом разделе: 3.2/6 <...>There can be more than one definition of a class type <...> Given such an entity named D defined in more than one translation unit, then each definition of D shall consist of the same sequence of tokens; and <...>

суббота, 11 января 2020 г.

Почему объектные файлы не кроссплатформенны?

#c #gcc #компиляция #компилятор


По определению, объектный код - набор инструкций для определённой архитектуры процессора.
Возьмём компилятор GCC. Если компилировать один и тот же код из-под разных платформ(Linux/Windows
etc.), но на одном железе, на выходе получим с виду одинаковые *.o файлы, которые не
будут кросплатформенны. Почему?

Чтобы исключить разность реализаций библиотек, возьмём код без них, что-то вроде:

//main.c
int main()
{
    return 5+3;
}
//main.c EOF

    


Ответы

Ответ 1



По определению, объектный код - набор инструкций для определённой архитектуры процессора. Это правда. Но НЕ вся правда. Кроме собственно инструкций процессора он содержит таблицу внешних ссылок, таблицу перемещаемых адресов и т.д. Эти таблицы используются загрузчиком/линкером при подготовки объектного модуля к выполнению. Ни сами таблицы, ни метод настройки объектного модуля не стандартизованы. В силу этого, объектный модуль, подготовленный для исполнения на одной платформе, не может быть выполнен на другой. Можно было бы попытаться написать не очень сложный транслятор одного формата в другой, но проблема практически неразрешима, т.к. различается не только сам формат объектного модуля, но и формат вызовов внешних функций (структура стека) и даже формат вызова функций ОС. Дело дохлое...

Разрешение зависимостей для орграфа с циклами

#графы #зависимости #dependencies #компиляция


Балуюсь, хочу сделать транслятор из BNF в код-грамматику для LEPL. Парсер написал,
код для отдельных правил генерируется, но дальше подзастрял с порядком правил.

Есть набор правил, ссылающихся друг на друга. Зависимости можно просто представить
в виде орграфа, в котором есть циклы:



Нужно разрешить зависимости относительно заданной вершины, получив список, в котором
следует записывать правила так, чтобы последующие правила уже «видели» все требуемые
им предыдущие. Если возникает цикл — нужно перед первым употреблением поместить «предварительную
декларацию.» Т.е., для примера графа выше, если, упрощая, считать, что вершины содержат
просто строки, получить что-то в духе:

>>> deps_dict = {
...    "A": {"B", "C"},
...    "B": {"D", "E"},
...    "C": {"A", "E"},
...    "E": {"E", "D"}
... }
>>> resolve_deps(deps_dict, "A")
[
    "D"              # {}
    Predeclare("E"), # ref'd by {E, B}
    "E"              # {D, E}
    "B"              # {D, E}
    Predeclare("A"), # ref'd by {C}
    "C"              # {A, E}
    "A"              # {B, C}
]


(То, что это не единственный вариант удовлетворяющего условиям результата — понятно.)

Положение в списке предварительных деклараций не очень важно — в худшем случае, можно
их вытащить наверх, хотя лично мне хочется размещать их не раньше самого необходимого
(т.е. перед первой отсылкой).

Если бы циклов не было — все было бы, вроде как, понятно — про топологическую сортировку
я нашел и почитал. Но как справиться с циклами — честно говоря, пока не соображу.
    


Ответы

Ответ 1



Поскольку БНФ оперирует контекстно-свободными грамматиками, то самое простое - это использовать соответствующий раздел теории синтаксического анализа. Самое неприятное, что может быть в произвольно взятой КС-грамматике G - это левая рекурсия, которая, нестрого говоря, делает грамматику G недетерминированной. При этом шаги алгоритма избавления от левой рекурсии включают в себя избавление от циклов. Поскольку вы, судя по всему, пытаетесь достичь детерминированности соответствующей грамматики, то лично я рекомендовал бы сразу же заимплементировать алгоритм избавления от левой рекурсии. Простое описание подхода избавления от левой рекурсии можно найти здесь, более же обзорная публикация по разным алгоритмам избавления от левой рекурсии расположена тут. Если вы действительно знаете, что делаете и хотите только избавиться от циклов, то воспользуйтесь только шагами (1) и (2) из публикации Eliminating left-recursion: three steps. Из дополнительных референсов могу порекомендовать пост Эрика Липперта по поводу CFG и циклов в них вообще, а также набор хороших презентаций по теории формальных языков.

Компиляция скрипта на Java SE7 в Sublime Text 2

#java #компиляция #sublime_text


Как скомпилировать скрипт на Java SE7 в Sublime Text 2?

Как там настроить компилятор под Java?
    


Ответы

Ответ 1



Я все таки рекомендую использовать eclipse/idea/emacs/vim. Но если сильно-сильно хочется... В принципе ничего не нужно настраивать - все уже есть. После того, как откроете свой жава файл, просто зайдите в меню Tools-> Build System и убедитесь, что там выбрано JavaC. Если нет - выбирайте. Все, теперь можно жать Ctrl+B и саблим запустит javac для компиляции. Установить жаву конечно же нужно. И настроить, что бы она была в путях. На моем ноуте под Fedora все завелось сразу.

Ответ 2



В меню выберите Tools-> Build System -> New Build System, после чего откроется новая вкладка, куда нужно вставить следующий текст: { "cmd": ["javac", "$file_name","&&","java", "$file_base_name"], "shell": true, "path": "c:/Program Files/Java/jdk1.8.0_60/bin", "file_regex": "^(...*?):([0-9]*):?([0-9]*)", "selector": "source.java" } Параметр "path" указывает путь к JDK, если он у вас отличается, измените на свой. Либо можете удалить всю строку, если у вас путь прописан в системной переменной. Теперь нажмите комбинацию "ctrl + s" и сохраните файл настроек выполнения под любым именем, к примеру "JavaCompileRun". Последним шагом выбираем в меню пункт Tools-> Build System -> JavaCompileRun и дальше, при нажатии "ctrl + b" открытый файл c java-кодом будет выполнятся.

пятница, 10 января 2020 г.

Как сделать, чтобы программа компилировалась всеми популярными компиляторами?

#cpp #компиляция


Хочу устроить небольшой эксперимент, целью которого будет выяснение вопроса о необходимости
избавляться от ветвлений в таких функциях как min, max, sign и abs. Каждый должен иметь
возможность взять вот этот cpp файл (GitHub), скомпилировать, запустить и посмотреть
на вывод в stdout. Программа выдает две колонки чисел: время работы функции с ветвлением
и без него. Программа может работать долго, несколько минут (не пугайтесь, она не виснет).

Сейчас программа компилируется только в VС++ 2015 и в GCC 4.8.1 (из MinGW), а мне
бы хотелось, чтобы она работала и в других компиляторах. Кто что может посоветовать
сделать? От std::chrono мне не избавиться, время замерять нужно как-то более менее
универсально, от int32_t тоже, так как я не знаю, вдруг у кого-то будет int размером
64 бита (мало ли). Возможно, я не во всём следую Стандарту или есть ещё какие-то ошибки?

Важно вот что: я отдаю себе отчёт, что код зависит от наличия знакового сдвига и
дополнительного кода в представлении отрицательных чисел. Так и было задумано.
    


Ответы

Ответ 1



Приведённый код компилируется «только в VС++ 2015 и в GCC 4.8.1», так как использует возможности стандарта C++11 (а именно std::chrono и заголовочный файл cstdint). Для того, чтобы программа собиралась на компиляторах, поддерживающих исключительно более ранние стандарты, необходимо: Использовать функциюclock из заголовочного файла ctime. Эта функция возвращает время в процессорных тактах, а потому идеально подходит для решения поставленной задачи. Заменить включение на . Оба заголовка имеют практически идентичное содержимое, однако последний был введён ещё в C99.

понедельник, 6 января 2020 г.

Компиляция JavaScript в машинный код

#javascript #компиляция


Есть ли возможность компилировать программу на JavaScript в машинный код(байт-код
java не подходит)?
    


Ответы

Ответ 1



Статически - нет. JavaScript слишком гибкий язык. Динамически - любой современный интерпретатор так и делает. Первым по этому пути пошел V8 (движок, который используется в Хроме и в node.js).

Ответ 2



Нашел такую штуку http://enclosejs.com... Позволяет компилировать JS в исполняемый файл. Единственное на выходе сильно большой файл получается. Hello, World! весит 22Мб.

Ответ 3



В FrameWork.Net входит Microsoft JScript Compiler - jsc.exe (Лежит в c:\Windows\Microsoft.Net\FrameWork\ (ваша версия)\jsc.exe Подробное описание jsc.exe /? С его помощью компилируется в ".exe" Нужно заметить что DOM - отсутствует по понятным причинам, но у вас есть полный набор средств работы с диском, реестром и прочими вещами...

Как скомпилировать .cs (C# source code) файл в .exe программу НЕ с помощью Visual Studio?

#c_sharp #компиляция


Я получил исходный код файла игры в формате .cs используя ILSpy, отредактировал его
и теперь хочу протестировать, но не знаю как/используя что его скомпилировать обратно
в .exe. Приму любой вариант КРОМЕ Visual Studio.
    


Ответы

Ответ 1



Варианты: 1 Visual Studio Code 2 MonoDevelop 3 Построение из командной строки с помощью csc.exe Примеры командных строк для компилятора C# Компиляция File.cs и создание File.exe: csc File.cs Компиляция File.cs и создание File.dll: csc /target:library File.cs Компиляция File.cs и создание My.exe: csc /out:My.exe File.cs Компиляция всех файлов C# в текущем каталоге с включенными оптимизациями и определение символа DEBUG. Выводится файл File2.exe: csc /define:DEBUG /optimize /out:File2.exe *.cs Компиляция всех файлов C# в текущем каталоге с созданием отладочной версии File2.dll. Логотипы и предупреждения не отображаются: csc /target:library /out:File2.dll /warn:0 /nologo /debug *.cs Компиляция всех файлов C# в текущем каталоге в файл Something.xyz (библиотеку DLL): csc /target:library /out:Something.xyz *.cs

Ответ 2



ссылка на stack overflow If you have the .NET v4 installed (so if you have a newer windows or if you apply the windows updates) C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe nomefile.cs or C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe nomefile.sln or C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe nomefile.csproj It's highly probable that if you have .NET installed, the %FrameworkDir% variable is set, so: %FrameworkDir%\v4.0.30319\csc.exe ... %FrameworkDir%\v4.0.30319\msbuild.exe ...